I'm working with Github's graphQL API in order to get Issues and Pull Requests for a macOS app. Since both of those types are wrapped in the objects of similar structure, I would like to user polimorphic serialization.
Here are my Codable DTOs:
struct Edge: Codable {
var node: Node
enum CodingKeys: String, CodingKey {
case node
}
}
enum Node: Codable {
case pull(Pull)
case issue(Issue)
init (from decoder: Decoder) throws {
if let pull = try? Pull(from: decoder) {
self = .pull(pull)
} else if let issue = try? Issue(from: decoder) {
self = .issue(issue)
} else {
try self.init(from: decoder) // this will fail!
}
}
func encode(to encoder: Encoder) throws {
switch self {
case .issue(let issue):
try issue.encode(to: encoder)
case .pull(let pull):
try pull.encode(to: encoder)
}
}
}
struct Pull: Codable {
var title: String
var isDraft: Bool
enum CodingKeys: String, CodingKey {
case isDraft
}
}
struct Issue: Codable {
var title: String
var author: User
enum CodingKeys: String, CodingKey {
case title
case author
}
}
The JSON response is serialized without errors, however I cannot access the object. How can I get Pull or Issue object from the Node?
In debug mode I can see the Node somehow got casted to a Pull or to an Issue:
But everything I tried so far gives error:
edge.node.title //Value of type 'Node' has no member 'title'
Pull(edge.node) //Argument type 'Node' does not conform to expected type 'Decoder'
edge.node as Pull // Cannot convert value of type 'Node' to type 'Pull' in coercion