Automatic Codable conformance for enums with associated values that themselves conform to Codable

Apologies — I wrote the above while in a bit of a hurry, so let me clarify: I don't think one use case is more important than another; I think we should find a solution which is able to synthesize code for both use cases which want a discriminator, and those which do not.

For instance, one straw-man approach to this is to generate both implementations and allow someone to use either approach via a property, e.g.

enum SynthesizedEnumDiscriminatorType {
    // No discriminator -- attempt cases in order single-value
    case none

    // Use the case name as the value-containing key, e.g.
    // {"album": {"id": "abc"}} or {"podcast": {"id": "xyz"}}
    case discriminateByCaseName

    // Use the case name as a discriminator keyed by the given key, e.g.
    // with disciminateByCaseNameForKey(CodingKeys.object), {"object": "album", "id": "abc"}
    case discriminateByCaseNameForKey(CodingKey)
}

enum MyEnum {
    case string(String)
    case double(Double)

    // Synthesized
    static var codableDiscriminatorType: SynthesizedEnumDiscriminatorType {
        return .none
    }

    init(from decoder: Decoder) throws {
        switch MyEnum.codableDiscriminatorType {
            // ... use the strategies
        }
    }
}

Essentially, add another customization point by using a property similar to how CodingKeys influences the representation of a structured type. If you want to override the discriminator strategy used, provide a discriminator type via the enum (you can even make it mutable if we decide to generate all implementations and choose dynamically).


Of course, there are design issues with the above, but what I'm trying to get at is that it's possible to come up with solutions that work across multiple use cases.

6 Likes