Skip to content

Access node tag during decoding #265

@tjprescott

Description

@tjprescott

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions