Skip to content

Array of enums with associated values #25

@jsbean

Description

@jsbean

Thanks for taking up the maintenance on this project!

I am working with an XML schema which requires support for heterogeneous arrays of values within a set of specified types.

Consider the following enum which defines each of the types allowable:

enum AB {
    struct A: Decodable { let value: Int }
    struct B: Decodable { let value: String }
    case a(A)
    case b(B)   
}

Currently, the Decodable implementation is as follows (based on objc.io/codable-enums):

extension AB: Decodable {
    enum CodingKeys: String, CodingKey { case a, b }
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            self = .a(try container.decode(A.self, forKey: .a))
        } catch {
            self = .b(try container.decode(B.self, forKey: .b))
        }
    }
}

A minimal example of the source XML could look something like this (though there could be arbitrary amounts of either type, in any order):

let xml = """
<?xml version="1.0" encoding="UTF-8"?>
<container>
    <a value="42"></a>
    <b value="forty-two"></b>
</container>
"""

Upon decoding it with the XMLDecoder:

let decoder = XMLDecoder()
let abs: [AB] = try! decoder.decode([AB].self, from: xml.data(using: .utf8)!)

We get the following:

// => [.a(AB.A(value: 42))]

The desired result should be:

// => [.a(AB.A(value: 42)), .b(AB.B(value: "forty-two"))]

I have tried many combinations of keyed, unkeyed, singleValue, and nested containers, yet haven't found a solution that treats the data as an Array rather than a Dictionary.

Let me know if I am holding this wrong (at either the Decodable or the XMLDecoder stages), or if this could be a current limitation of the XMLCoder implementation. I'd be happy to contribute, but if anyone notices something glaring here, this would be very helpful.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions