[Pre-Pitch] Codable Customization using PropertyWrappers

Yeah, the difficulty is that needs to be added to the CodingKeys. Maybe if/when we have the ability to customize that generation something like that could be added.

In the meantime, if you don't already have it working, you can customize it to use either key:

// Decodes from { "name" : "1", "parent_id" : 2} or { "name" : "1", "state_id" : 2}
struct MyType: Codable {
    var name: String
    var stateID: Int

    enum CodingKeys: String, CodingKey {
        case name
        case stateID = "state_id"
        case parentID = "parent_id"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decode(String.self, forKey: .name)

        if let realStateID = try values.decodeIfPresent(Int.self, forKey: .stateID) {
            self.stateID = realStateID
        }
        else if let realStateID = try values.decodeIfPresent(Int.self, forKey: .parentID) {
            self.stateID = realStateID
        }
        else {
            throw DecodingError.valueNotFound(MyType.self,  DecodingError.Context(codingPath: decoder.codingPath,
            debugDescription: "Expected \(MyType.self) but could not find state_id or parent_id"))
        }
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        try container.encode(stateID, forKey: .stateID)
    }
}
2 Likes