Skip to content

Commit 10debb7

Browse files
authored
Allow encode<T: Encodable>(_ value: T) in JSONSingleValueEncodingContainer (#24)
fixes #19
1 parent f5a249d commit 10debb7

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

Sources/PureSwiftJSONCoding/Encoding/JSONSingleValueEncodingContainer.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct JSONSingleValueEncodingContainer: SingleValueEncodingContainer {
1616
}
1717

1818
mutating func encode(_ value: Bool) throws {
19+
preconditionCanEncodeNewValue()
1920
self.impl.singleValue = .bool(value)
2021
}
2122

@@ -68,23 +69,31 @@ struct JSONSingleValueEncodingContainer: SingleValueEncodingContainer {
6869
}
6970

7071
mutating func encode(_ value: String) throws {
72+
preconditionCanEncodeNewValue()
7173
self.impl.singleValue = .string(value)
7274
}
7375

7476
mutating func encode<T: Encodable>(_ value: T) throws {
75-
77+
preconditionCanEncodeNewValue()
78+
try value.encode(to: self.impl)
79+
}
80+
81+
func preconditionCanEncodeNewValue() {
82+
precondition(self.impl.singleValue == nil, "Attempt to encode value through single value container when previously value already encoded.")
7683
}
7784
}
7885

7986
extension JSONSingleValueEncodingContainer {
8087

8188
@inline(__always) private mutating func encodeFixedWidthInteger<N: FixedWidthInteger>(_ value: N) throws {
89+
preconditionCanEncodeNewValue()
8290
self.impl.singleValue = .number(value.description)
8391
}
8492

8593
@inline(__always) private mutating func encodeFloatingPoint<N: FloatingPoint>(_ value: N)
8694
throws where N: CustomStringConvertible
8795
{
96+
preconditionCanEncodeNewValue()
8897
self.impl.singleValue = .number(value.description)
8998
}
9099

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import XCTest
2+
@testable import PureSwiftJSONCoding
3+
@testable import PureSwiftJSONParsing
4+
5+
class JSONSingleValueEncodingContainerTests: XCTestCase {
6+
7+
func testEncodeEncodable() {
8+
struct Name: Encodable {
9+
var firstName: String
10+
var surname: String
11+
}
12+
13+
struct Object: Encodable {
14+
var name: Name
15+
16+
func encode(to encoder: Encoder) throws {
17+
var container = encoder.singleValueContainer()
18+
try container.encode(name)
19+
}
20+
}
21+
22+
do {
23+
let object = Object(name: Name(firstName: "Adam", surname: "Fowler"))
24+
let json = try PureSwiftJSONCoding.JSONEncoder().encode(object)
25+
26+
let parsed = try JSONParser().parse(bytes: json)
27+
XCTAssertEqual(parsed, .object(["firstName": .string("Adam"), "surname": .string("Fowler")]))
28+
}
29+
catch {
30+
XCTFail("Unexpected error: \(error)")
31+
}
32+
}
33+
34+
}
35+

0 commit comments

Comments
 (0)