swiftswift-protocolsrawrepresentable

Swift protocol for things that convert to and from String


I'd like to have a GenericThing with a template parameter that is any type that can sensibly be converted to and from a string.

// ConvertsToAndFromString is a made up protocol here – what should I use instead?
struct GenericThing<Id: ConvertsToAndFromString> {
}

I should then be able to use GenericThing with any type that has a reasonable encoding as a string. For example, it should work for Int, String (well, dah), and ideally, any RawRepresentable where the RawValue itself will convert to and from a string.

Example:

enum Tubbies: String {
  case dipsy
  case laalaa
  case po
}

// I'd like to be able to do this.
let genericThing = GenericThing<Tubbies>

I can't see how to easily do this.

I was hoping I could use LosslessStringConvertible instead of my made up ConvertsToAndFromString.

I tried this, and it works for Int and such. But it doesn't work for Tubbies. I couldn't see a way to make all RawRepresentable where RawValue: LosslessStringConvertible also conform to LosslessStringConvertible.


Solution

  • This is how you extend RawRespresentable to be conditionally LosslessStringConvertible depending on its RawValue:

    extension RawRepresentable where RawValue: LosslessStringConvertible {
        init?(_ rv: RawValue) {
            self.init(rawValue: rv)
        }
    
        var description: String { return self.rawValue.description }
    }
    

    Here it is in action:

    struct GenericThing<Id: LosslessStringConvertible> {
    
    }
    
    enum Tubbies: String, LosslessStringConvertible {
        case dipsy
        case laalaa
        case po
    }
    
    let genericThing = GenericThing<Tubbies>()
    print(Tubbies.po is LosslessStringConvertible) // => true