Was having trouble decoding into IdentifiedArray, a data structure from @pointfreeco. It conforms to Codable. Came up with the following minimal reproduction:
import IdentifiedCollections
import XCTest
import XMLCoder
let sourceXML: String = """
<?xml version="1.0" encoding="utf-8"?>
<team>
<user>
<id>1</id>
<name>Bob</name>
</user>
<user>
<id>2</id>
<name>Alice</name>
</user>
</team>
"""
struct User: Decodable, Identifiable {
let id: Int
let name: String
}
struct Team: Decodable {
let users: [User]
enum CodingKeys: String, CodingKey {
case users = "user"
}
}
struct IdentifiableTeam: Decodable {
let users: IdentifiedArrayOf<User>
enum CodingKeys: String, CodingKey {
case users = "user"
}
}
final class XMLCoderTests: XCTestCase {
func testDecodeArray() throws {
let decoder = XMLDecoder()
guard let data = sourceXML.data(using: .utf8) else { XCTFail(); return }
let team = try decoder.decode(Team.self, from: data)
XCTAssertEqual(2, team.users.count)
}
func testDecodeIdentifiedArray() throws {
let decoder = XMLDecoder()
guard let data = sourceXML.data(using: .utf8) else { XCTFail(); return }
let team = try decoder.decode(IdentifiableTeam.self, from: data) // ❌ throws
XCTAssertEqual(2, team.users.count)
}
}
I would expect both tests to pass. The vanilla array decoding does pass, but the IdentifiedArray decoding throws the following:
testDecodeIdentifiedArray(): failed: caught error: "typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "user", intValue: nil), XMLKey(stringValue: "0", intValue: 0), XMLKey(stringValue: "0", intValue: 0)], debugDescription: "Expected to decode Dictionary<String, Any> but found ChoiceBox instead.", underlyingError: nil))"
Had a little trouble understanding XMLCoder's internals, but did notice that it extends a few standard library data structures to conform to an internal protocol AnySequence. If I change my minimal reproduction like so:
-import XMLCoder
+@testable import XMLCoder
// ...
+extension IdentifiedArray: AnySequence where Element: Identifiable, ID == Element.ID { }
then both tests pass.
Are my findings correct that conformance to this internal protocol are necessary to decode arbitrary data structures from outside the standard library?
I think ideally this would not be the case, and the encoder/decoder implementations would support arbitrary Codable types generally. But I understand the maintainers of the library are not the original authors.
In the mean time, if conformance to AnySequence is required, what do the maintainers think about making it public?
Was having trouble decoding into
IdentifiedArray, a data structure from @pointfreeco. It conforms toCodable. Came up with the following minimal reproduction:I would expect both tests to pass. The vanilla array decoding does pass, but the
IdentifiedArraydecoding throws the following:Had a little trouble understanding
XMLCoder's internals, but did notice that it extends a few standard library data structures to conform to an internal protocolAnySequence. If I change my minimal reproduction like so:then both tests pass.
Are my findings correct that conformance to this internal protocol are necessary to decode arbitrary data structures from outside the standard library?
I think ideally this would not be the case, and the encoder/decoder implementations would support arbitrary
Codabletypes generally. But I understand the maintainers of the library are not the original authors.In the mean time, if conformance to
AnySequenceis required, what do the maintainers think about making it public?