I have lost track of the number of times I've had to write the following code:
enum Foo {
case weGot(Int)
case someCases(String)
case here(Bool)
var discriminator: Discriminator {
switch self {
case .weGot: return .weGot
case .someCases: return .someCases
case .here: return .here
}
}
enum Discriminator: String, CaseIterable {
case weGot, someCases, here
}
}
There are a wide range of use cases where this is needed (wiring up in-app settings preferences, log message shorthand, etc). This is boilerplate that, as far as my understanding goes, could be automatically synthesized by the compiler:
enum Foo: Discriminated {
case weGot(Int)
case someCases(String)
case here(Bool)
}
Any frozen enum with one or more associated values could be marked Discriminated. If it is, the compiler would synthesize:
An enum Discriminator nested type within that enum
A var discriminator: Discriminator property on that enum
The Discriminator enum would have a raw value of String (raw values would be exactly match the case names) and would be CaseIterable.
The compiler would emit a build error on an enum marked Discriminated if any of the following are true:
This is something I’ve also wanted several times. However, AFAIK @frozen is only allowed when compiling in library evolution mode, so it doesn’t seem this would be very useful to most apps or packages. Why does it have to be limited to @frozen enums?
This change would be enormously useful for me. I make heavy use of enums, and it's often useful to access a string/int representation of a given case (e.g. for custom enum Codable implementations)
In those instances do you need var discriminator: Discriminator (enum value) or just var string: String (the raw value like "weGot")? If it is the former, can you provide a mini sample code to show it?
The string itself is easy to get, smth like: "\(Foo.weGot(123))" to get "weGot(123)" and then remove the brackets and what's in them.
I think this is great. I don't see why you would need the enum to be @frozen though. Seems like you could have the Discriminator just be @frozen or not depending on if the enum is frozen or not. If it's not frozen, then the Discriminator isn't frozen and you would have to deal with that when using it.