Skip to content

Commit b15a479

Browse files
authored
Fix decoding of enum with associated values when enum case does not contain value (#265)
1 parent 80b4a16 commit b15a479

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

Sources/XMLCoder/Decoder/XMLKeyedDecodingContainer.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ struct XMLKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtocol {
144144
referencing: decoder,
145145
wrapping: SharedBox(keyedContainer)
146146
)
147+
} else if let singleBox = value as? SingleKeyedBox {
148+
let element = (singleBox.key, singleBox.element)
149+
let keyedContainer = KeyedBox(elements: [element], attributes: [])
150+
container = XMLKeyedDecodingContainer<NestedKey>(
151+
referencing: decoder,
152+
wrapping: SharedBox(keyedContainer)
153+
)
147154
} else {
148155
throw DecodingError.typeMismatch(
149156
at: codingPath,

Tests/XMLCoderTests/AdvancedFeatures/SimpleChoiceTests.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,58 @@ final class SimpleChoiceTests: XCTestCase {
8585
let decoded = try XMLDecoder().decode([[IntOrString]].self, from: encoded)
8686
XCTAssertEqual(original, decoded)
8787
}
88+
89+
#if swift(>=5.5)
90+
func testMixedChoice() throws {
91+
enum Choice: Equatable, Codable {
92+
case one
93+
case two(value: Int)
94+
case three(key: String, value: Int)
95+
case four(Int)
96+
}
97+
98+
struct Foo: Equatable, Codable {
99+
var field1 = Choice.one
100+
var field2 = Choice.two(value: 10)
101+
var field3 = Choice.three(key: "qq", value: 20)
102+
var field4 = Choice.four(30)
103+
}
104+
105+
let encoder = XMLEncoder()
106+
encoder.outputFormatting = .prettyPrinted
107+
encoder.prettyPrintIndentation = .spaces(4)
108+
109+
let original = Foo()
110+
let encoded = try encoder.encode(original, withRootKey: "container")
111+
let decoded = try XMLDecoder().decode(Foo.self, from: encoded)
112+
XCTAssertEqual(original, decoded)
113+
114+
XCTAssertEqual(
115+
String(data: encoded, encoding: .utf8),
116+
"""
117+
<container>
118+
<field1>
119+
<one />
120+
</field1>
121+
<field2>
122+
<two>
123+
<value>10</value>
124+
</two>
125+
</field2>
126+
<field3>
127+
<three>
128+
<key>qq</key>
129+
<value>20</value>
130+
</three>
131+
</field3>
132+
<field4>
133+
<four>
134+
<_0>30</_0>
135+
</four>
136+
</field4>
137+
</container>
138+
"""
139+
)
140+
}
141+
#endif
88142
}

0 commit comments

Comments
 (0)