Decode a JSON object of unknown format into a Dictionary with Decodable in Swift 4

Thanks for bringing this back up, Dale. I’ve given this a bit of further thought in my spare time (though due to resource constraints I don’t think we’ll be able to do this for Swift 5 right now). It’s possible to extend the containers (and add default implementations) to do this, but I think a slightly more elegant solution would be to just expose the Unevaluated type more generally:

public struct Unevaluated : Codable {
    public let value: Any
    public init(_ value: Any) { self.value = value }

    public init(from decoder: Decoder) throws {
        // throw a type mismatch
    }

    public func encode(to encoder: Encoder) throws {
        // throws an invalid value error
    }
}

The naming and scoping is something we’d need to figure out, but the idea is that this type can be shared among all encoders and decoders (and their containers). Just like some encoders and decoders intercept certain types to customize them (e.g. with encoding strategies), they would intercept Unevaluated as well. You would encode(Unevaluated(...)) and decode(Unevaluated.self) just as you would any other type. If the type is intercepted, the encoder/decoder does what it needs to to handle the inner value; if not, you’ll get the error thrown by default (“this encoder/decoder can’t handle Unevaluated”), which you can catch and decide how to deal with.

Aside from naming and deciding where to hang the type, I think this would be the easiest and least intrusive approach.

1 Like