Access node tag during decoding
We have a data model schema that is using verbatim tags in YAML to indicate polymorphism. Note the protocol property in the below YAML snippet.
globalParameters:
- !<!Parameter> &ref_8
schema: *ref_0
...
protocol: !<!Protocols>
http: !<!HttpParameter>
in: uri
Here is Protocols.swift:
public protocol ProtocolInterface: Codable {}
/// Custom extensible metadata for individual protocols (ie, HTTP, etc)
public struct Protocols: Codable {
public let http: ProtocolInterface?
...
}
So under protocol, the http property could be one of a few different types. Here is the model for HttpParameter (as indicated in the snippet):
/// extended metadata for HTTP operation parameters
public class HttpParameter: ProtocolInterface {
public let `in`: ParameterLocation
...
}
This requires us to supply the following methods to Protocols:
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
http = try? container.decode(HttpParameter.self, forKey: .http)
...
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(http as? HttpParameter, forKey: .http)
}
The tag appears in the decoder object, and we would like to be able to access that info, as this would tell us which polymorphic type to encode and decode. As it stands, we have to just keep trying each possibility until one or none worked. The problem we have is that the _Decoder class and its node property are both private. We can print them in the debugger and see that they are viewable, but we can't programmatically access them in our methods. Is there a way to access the tag during the call to init(from decoder:)?
cc/ @sacheu
How do we upvote these issues? This is something I really need as well.
An option that would work for me, is to be able to up front register specific types for specific tags. Then the decoder could be allowed to do the work itself.
I'm not sure that this would be practical for @tjprescott 's case, though.