CoreOffice / XMLCoder

Easy XML parsing using Codable protocols in Swift
https://coreoffice.github.io/XMLCoder/
MIT License
793 stars 104 forks source link

Decoding Elements with Property wrappers doesn't work #279

Open janvhs opened 7 months ago

janvhs commented 7 months ago

There seems to be a problem decoding annotated struct members into arrays.

When decoding a struct with the DynamicNodeDecoding protocol, it decodes correctly, but when using @ Element, it doesn't.

To highlight the problem, I typed up the following example.

import Foundation
import XMLCoder // .package(url: "https://github.com/CoreOffice/XMLCoder.git", from: "0.17.1")

struct WorkingRoot: Codable, DynamicNodeDecoding, DynamicNodeEncoding {
    var nodes: [String]

    enum CodingKeys: String, CodingKey {
        case nodes
    }

    static func nodeDecoding(for key: CodingKey) -> XMLCoder.XMLDecoder.NodeDecoding {
        switch key {
        case WorkingRoot.CodingKeys.nodes: .element
        default: .elementOrAttribute
        }
    }

    static func nodeEncoding(for key: CodingKey) -> XMLCoder.XMLEncoder.NodeEncoding {
        switch key {
        case WorkingRoot.CodingKeys.nodes: .element
        default: .element
        }
    }
}

struct FailedRoot: Codable {
    @Element var nodes: [String]
}

// struct Node: Codable {
//     @Attribute var attr: String?
//     @Element var value: String
//
//     enum CodingKeys: String, CodingKey {
//         case attr
//         case value = ""
//     }
// }

let xml = """
<root>
    <nodes attr="test">
        First
    </nodes>
    <nodes>
        Second
    </nodes>
    <nodes>
        Third
    </nodes>
</root>
"""

let testContents = xml.data(using: .utf8)!

// This uses the DynamicNodeDecoding and DynamicNodeEncoding protocols and is working as expected.
let correctDecoded: WorkingRoot = try XMLDecoder().decode(WorkingRoot.self, from: testContents)

// This uses the @Element decorator and doesn't decode correctly.
let wrongDecoded: FailedRoot = try XMLDecoder().decode(FailedRoot.self, from: testContents)

print("This is fine")
print(correctDecoded) // WorkingRoot(nodes: ["First", "Second", "Third"])
print()
print("This isn't")
print(wrongDecoded) // FailedRoot(_nodes: XMLCoder.Element<Swift.Array<Swift.String>>(wrappedValue: ["First"]))