Skip to content

Commit e1b9bd2

Browse files
committed
encoder/decoder passing tests
1 parent 575e5be commit e1b9bd2

File tree

4 files changed

+134
-13
lines changed

4 files changed

+134
-13
lines changed

Sources/PostgreSQL/Coders/PartialPostgreSQLData.swift

+18-10
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,22 @@ final class PartialPostgreSQLData {
1717
/// Returns the value, if one at from the given path.
1818
func get(at path: [CodingKey]) -> PostgreSQLData? {
1919
var child = data
20-
2120
for seg in path {
22-
guard let c = child.dictionary?[seg.stringValue] else {
21+
switch child {
22+
case .array(let arr):
23+
guard let index = seg.intValue, arr.count > index else {
24+
return nil
25+
}
26+
child = arr[index]
27+
case .dictionary(let dict):
28+
guard let value = dict[seg.stringValue] else {
29+
return nil
30+
}
31+
child = value
32+
default:
2333
return nil
2434
}
25-
child = c
2635
}
27-
2836
return child
2937
}
3038

@@ -103,18 +111,18 @@ extension PartialPostgreSQLData {
103111

104112
extension PartialPostgreSQLData {
105113
/// Gets a value at the supplied path or throws a decoding error.
106-
func requireGet(at path: [CodingKey]) throws -> PostgreSQLData {
114+
func requireGet<T>(_ type: T.Type, at path: [CodingKey]) throws -> PostgreSQLData {
107115
switch get(at: path) {
108116
case .some(let w): return w
109-
case .none: throw DecodingError.valueNotFound(Bool.self, .init(codingPath: path, debugDescription: ""))
117+
case .none: throw DecodingError.valueNotFound(T.self, .init(codingPath: path, debugDescription: ""))
110118
}
111119
}
112120

113121
/// Gets a `Float` from the supplied path or throws a decoding error.
114122
func requireFixedWidthItenger<I>(_ type: I.Type = I.self, at path: [CodingKey]) throws -> I
115123
where I: FixedWidthInteger
116124
{
117-
switch try requireGet(at: path) {
125+
switch try requireGet(I.self, at: path) {
118126
case .int8(let value): return try safeCast(value, at: path)
119127
case .int16(let value): return try safeCast(value, at: path)
120128
case .int32(let value): return try safeCast(value, at: path)
@@ -145,7 +153,7 @@ extension PartialPostgreSQLData {
145153
func requireFloatingPoint<F>(_ type: F.Type = F.self, at path: [CodingKey]) throws -> F
146154
where F: BinaryFloatingPoint
147155
{
148-
switch try requireGet(at: path) {
156+
switch try requireGet(F.self, at: path) {
149157
case .int8(let value): return F(value)
150158
case .int16(let value): return F(value)
151159
case .int32(let value): return F(value)
@@ -158,15 +166,15 @@ extension PartialPostgreSQLData {
158166

159167
/// Gets a `String` from the supplied path or throws a decoding error.
160168
func requireString(at path: [CodingKey]) throws -> String {
161-
switch try requireGet(at: path) {
169+
switch try requireGet(String.self, at: path) {
162170
case .string(let value): return value
163171
default: throw DecodingError.typeMismatch(String.self, .init(codingPath: path, debugDescription: ""))
164172
}
165173
}
166174

167175
/// Gets a `Bool` from the supplied path or throws a decoding error.
168176
func requireBool(at path: [CodingKey]) throws -> Bool {
169-
switch try requireGet(at: path) {
177+
switch try requireGet(Bool.self, at: path) {
170178
case .bool(let value): return value
171179
default: throw DecodingError.typeMismatch(Bool.self, .init(codingPath: path, debugDescription: ""))
172180
}

Sources/PostgreSQL/Coders/PostgreSQLDataDecoder.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ internal final class _PostgreSQLDataDecoder: Decoder {
4545

4646
/// See `Decoder.singleValueContainer`
4747
func singleValueContainer() -> SingleValueDecodingContainer {
48-
fatalError()
48+
return PostgreSQLDataSingleValueDecodingContainer(partialData: partialData, at: codingPath)
4949
}
5050
}
51-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/// Internal `SingleValueDecodingContainer` for `PostgreSQLDataDecoder`
2+
final class PostgreSQLDataSingleValueDecodingContainer: SingleValueDecodingContainer {
3+
/// See `SingleValueDecodingContainer.codingPath`
4+
var codingPath: [CodingKey]
5+
6+
/// Data being encoded.
7+
let partialData: PartialPostgreSQLData
8+
9+
/// Creates a new internal `PostgreSQLDataSingleValueDecodingContainer`.
10+
init(partialData: PartialPostgreSQLData, at path: [CodingKey]) {
11+
self.codingPath = path
12+
self.partialData = partialData
13+
}
14+
15+
/// See `SingleValueDecodingContainer.decodeNil`
16+
func decodeNil() -> Bool {
17+
return partialData.get(at: codingPath) == nil
18+
}
19+
20+
/// See `SingleValueDecodingContainer.decode`
21+
func decode(_ type: Bool.Type) throws -> Bool {
22+
return try partialData.requireBool(at: codingPath)
23+
}
24+
25+
/// See `SingleValueDecodingContainer.decode`
26+
func decode(_ type: Int.Type) throws -> Int {
27+
return try partialData.requireFixedWidthItenger(at: codingPath)
28+
}
29+
30+
/// See `SingleValueDecodingContainer.decode`
31+
func decode(_ type: Int8.Type) throws -> Int8 {
32+
return try partialData.requireFixedWidthItenger(at: codingPath)
33+
}
34+
35+
/// See `SingleValueDecodingContainer.decode`
36+
func decode(_ type: Int16.Type) throws -> Int16 {
37+
return try partialData.requireFixedWidthItenger(at: codingPath)
38+
}
39+
40+
/// See `SingleValueDecodingContainer.decode`
41+
func decode(_ type: Int32.Type) throws -> Int32 {
42+
return try partialData.requireFixedWidthItenger(at: codingPath)
43+
}
44+
45+
/// See `SingleValueDecodingContainer.decode`
46+
func decode(_ type: Int64.Type) throws -> Int64 {
47+
return try partialData.requireFixedWidthItenger(at: codingPath)
48+
}
49+
50+
/// See `SingleValueDecodingContainer.decode`
51+
func decode(_ type: UInt.Type) throws -> UInt {
52+
return try partialData.requireFixedWidthItenger(at: codingPath)
53+
}
54+
55+
/// See `SingleValueDecodingContainer.decode`
56+
func decode(_ type: UInt8.Type) throws -> UInt8 {
57+
return try partialData.requireFixedWidthItenger(at: codingPath)
58+
}
59+
60+
/// See `SingleValueDecodingContainer.decode`
61+
func decode(_ type: UInt16.Type) throws -> UInt16 {
62+
return try partialData.requireFixedWidthItenger(at: codingPath)
63+
}
64+
65+
/// See `SingleValueDecodingContainer.decode`
66+
func decode(_ type: UInt32.Type) throws -> UInt32 {
67+
return try partialData.requireFixedWidthItenger(at: codingPath)
68+
}
69+
70+
/// See `SingleValueDecodingContainer.decode`
71+
func decode(_ type: UInt64.Type) throws -> UInt64 {
72+
return try partialData.requireFixedWidthItenger(at: codingPath)
73+
}
74+
75+
/// See `SingleValueDecodingContainer.decode`
76+
func decode(_ type: Float.Type) throws -> Float {
77+
return try partialData.requireFloatingPoint(at: codingPath)
78+
}
79+
80+
/// See `SingleValueDecodingContainer.decode`
81+
func decode(_ type: Double.Type) throws -> Double {
82+
return try partialData.requireFloatingPoint(at: codingPath)
83+
}
84+
85+
/// See `SingleValueDecodingContainer.decode`
86+
func decode(_ type: String.Type) throws -> String {
87+
return try partialData.requireString(at: codingPath)
88+
}
89+
90+
/// See `SingleValueDecodingContainer.decode`
91+
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
92+
let decoder = _PostgreSQLDataDecoder(partialData: partialData, at: codingPath)
93+
return try T(from: decoder)
94+
}
95+
96+
/// See `SingleValueDecodingContainer.nestedContainer`
97+
func nestedContainer<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key>
98+
where Key: CodingKey
99+
{
100+
let container = PostgreSQLDataKeyedDecodingContainer<Key>(partialData: partialData, at: codingPath)
101+
return .init(container)
102+
}
103+
104+
/// See `SingleValueDecodingContainer.nestedSingleValueContainer`
105+
func nestedSingleValueContainer() throws -> SingleValueDecodingContainer {
106+
return PostgreSQLDataSingleValueDecodingContainer(partialData: partialData, at: codingPath)
107+
}
108+
109+
/// See `SingleValueDecodingContainer.superDecoder`
110+
func superDecoder() throws -> Decoder {
111+
return _PostgreSQLDataDecoder(partialData: partialData, at: codingPath)
112+
}
113+
}
114+

Tests/PostgreSQLTests/PostgreSQLDataTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class PostgreSQLDataTests: XCTestCase {
99
}
1010

1111
func testDecode() throws {
12-
let kitchenSink = try PostgreSQLDataDecoder().decode(KitchenSink.self, from: .kitchenSink)
12+
let kitchenSink = try! PostgreSQLDataDecoder().decode(KitchenSink.self, from: .kitchenSink)
1313
XCTAssertEqual(kitchenSink, .test)
1414
}
1515

0 commit comments

Comments
 (0)