How exactly does that work from the perspective of the initializer if you have 2 sets of keys to choose from? Would I extend the initializer to include my feature flag `public init(from decoder: Decoder, flag: Bool) throws` and switch on that? Or could I pass in the Container I want to use somehow, which seems cleaner to me as an abstraction? (This is similar to what we're already doing with the setup we have.) How does a key jump multiple levels "permissions.can_send_message" and is there a way to know ahead of time which key maps to what property? Needing to express every possible mapping from the initializer seems clumsy to me and I think would fit better as a part of the Container itself.
On Mon, Apr 10, 2017 at 3:13 PM, Tony Parker <anthony.par...@apple.com> wrote: > Hi Rex, > > On Apr 10, 2017, at 12:48 PM, Rex Fenley via swift-evolution < > swift-evolution@swift.org> wrote: > > Forgive me if I'm missing something, this is a very large proposal and a > lot to parse through. I like how everything is designed as far as I can > tell except I'm not sure from this proposal how one would compose multiple > different types of Decoders against the same output type. For example, with > Location we have. > > // Continuing examples from before; below is automatically generated by > the compiler if no customization is needed. > public struct Location : Codable { > private enum CodingKeys : CodingKey { > case latitude > case longitude > } > > public init(from decoder: Decoder) throws { > let container = try decoder.container(keyedBy: CodingKeys.self) > latitude = try container.decode(Double.self, forKey: .latitude) > longitude = try container.decode(Double.self, forKey: .longitude) > } > } > > However, this initializer seems strictly tied to the `CodingKeys` set of > coding keys. From what it appears, if this was used to decode from JSON the > format would have to always be: > > { > "latitude" : 20.0 > "longitude" : 20.0 > } > > I have a use case we're on my client we began the process of switching > from one version of an API to another. In one version we had a payload > similar to > > { > "user" : { > "uuid" : "uuid string..." > "can_send_message" : true > "can_delete_message" : false > } > } > > this would result in the following Codable (from "user") from what I'm > following > > public struct User : Codable { > private enum CodingKeys : CodingKey { > case uuid > case can_send_message > case can_delete_message > } > > public init(from decoder: Decoder) throws { > let container = try decoder.container(keyedBy: CodingKeys.self) > uuid = try container.decode(Double.self, forKey: .uuid) > canSendMessage = try container.decode(Bool.self, forKey: > .can_send_message) > canDeleteMessage = try container.decode(Bool.self, forKey: > .can_delete_message) > } > } > > when we began switching over to the new api the payload was returned as > > { > user { > "uuid" : "uuid string..." > "permissions" : { > "can_send_message" : true > "can_delete_message" : false > } > } > } > > Here with "permissions" we have a new internal container with a separate > set of coding keys. Issue is in my use case I still need to maintain a way > to decode the old version simultaneously; we guard all new changes behind > feature flags in case something goes awry and we need to roll back our > changes. > > How would one go about expressing this new Decoding and the previous > Decoding simultaneously on the same User type? > > > You would fall out of the automatically-generated scenario here, but this > use case is exactly what the ‘container’ API is for. You can create a > container with a new set of keys, then decode from it. > > Another approach would be to create a nested type that conforms with > Codable which represents the “permissions” as a type of its own. > > - Tony > > > > -- > Rex Fenley | IOS DEVELOPER > > Remind.com <https://www.remind.com/> | BLOG <http://blog.remind.com/> | > FOLLOW US <https://twitter.com/remindhq> | LIKE US > <https://www.facebook.com/remindhq> > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > > > -- Rex Fenley | IOS DEVELOPER Remind.com <https://www.remind.com/> | BLOG <http://blog.remind.com/> | FOLLOW US <https://twitter.com/remindhq> | LIKE US <https://www.facebook.com/remindhq>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution