Skip to content

Commit dde52b1

Browse files
committed
KeyedEncodingContainer implemented
1 parent 1f1fc42 commit dde52b1

15 files changed

+359
-284
lines changed

sources/Codable/CodecKey.swift

Lines changed: 0 additions & 27 deletions
This file was deleted.

sources/Codable/CodingKey.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/// The coding key used to identify encoding/decoding containers.
2+
internal struct IndexKey: CodingKey {
3+
/// The integer value of the coding key.
4+
let index: Int
5+
/// Designated initializer.
6+
init(_ index: Int) { self.index = index }
7+
8+
init?(intValue: Int) {
9+
guard intValue >= 0 else { return nil }
10+
self.init(intValue)
11+
}
12+
13+
init?(stringValue: String) {
14+
guard let intValue = Int(stringValue) else { return nil }
15+
self.init(intValue)
16+
}
17+
18+
var stringValue: String { String(self.index) }
19+
var intValue: Int? { self.index }
20+
}
21+
22+
/// Coding key used to represent a key with both an integer value and a string value.
23+
internal struct NameKey: CodingKey {
24+
/// The integer value of the given key.
25+
let index: Int
26+
/// The name for the given key.
27+
let name: String
28+
/// Designated initializer.
29+
init(index: Int, name: String) {
30+
self.index = index
31+
self.name = name
32+
}
33+
34+
init?(intValue: Int) { nil }
35+
init?(stringValue: String) { nil }
36+
37+
var stringValue: String { self.name }
38+
var intValue: Int? { self.index }
39+
}
40+
41+
/// Coding key used to represent an invalid branch on a coding path.
42+
internal struct InvalidKey: CodingKey {
43+
init() {}
44+
init?(intValue: Int) { nil }
45+
init?(stringValue: String) { nil }
46+
47+
var stringValue: String { "" }
48+
var intValue: Int? { nil }
49+
}

sources/Codable/Decodable/Containers/DecodingKeyed.swift renamed to sources/Codable/Decodable/Containers/KeyedDecodingContainer.swift

Lines changed: 71 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ extension ShadowDecoder.KeyedContainer {
7979
switch self.focus {
8080
case .file:
8181
guard let rowIndex = key.intValue else { throw DecodingError.invalidKey(forRow: key, codingPath: self.codingPath + [key]) }
82-
var codingPath = self.decoder.codingPath; codingPath.append(CodecKey(rowIndex))
82+
var codingPath = self.decoder.codingPath; codingPath.append(IndexKey(rowIndex))
8383
let decoder = ShadowDecoder(source: self.decoder.source, codingPath: codingPath)
8484
return KeyedDecodingContainer(ShadowDecoder.KeyedContainer<NestedKey>(unsafeDecoder: decoder, rowIndex: rowIndex))
8585
case .row: throw DecodingError.invalidContainerRequest(codingPath: self.codingPath)
@@ -90,7 +90,7 @@ extension ShadowDecoder.KeyedContainer {
9090
switch self.focus {
9191
case .file:
9292
guard let rowIndex = key.intValue else { throw DecodingError.invalidKey(forRow: key, codingPath: self.codingPath + [key]) }
93-
var codingPath = self.decoder.codingPath; codingPath.append(CodecKey(rowIndex))
93+
var codingPath = self.decoder.codingPath; codingPath.append(IndexKey(rowIndex))
9494
let decoder = ShadowDecoder(source: self.decoder.source, codingPath: codingPath)
9595
return ShadowDecoder.UnkeyedContainer(unsafeDecoder: decoder, rowIndex: rowIndex)
9696
case .row: throw DecodingError.invalidContainerRequest(codingPath: self.codingPath)
@@ -101,7 +101,7 @@ extension ShadowDecoder.KeyedContainer {
101101
switch self.focus {
102102
case .file:
103103
guard let rowIndex = key.intValue else { throw DecodingError.invalidKey(forRow: key, codingPath: self.codingPath + [key]) }
104-
var codingPath = self.decoder.codingPath; codingPath.append(CodecKey(rowIndex))
104+
var codingPath = self.decoder.codingPath; codingPath.append(IndexKey(rowIndex))
105105
return ShadowDecoder(source: self.decoder.source, codingPath: codingPath)
106106
case .row: throw DecodingError.invalidContainerRequest(codingPath: self.codingPath)
107107
}
@@ -110,7 +110,7 @@ extension ShadowDecoder.KeyedContainer {
110110
func superDecoder() throws -> Decoder {
111111
switch self.focus {
112112
case .file:
113-
var codingPath = self.decoder.codingPath; codingPath.append(CodecKey(0))
113+
var codingPath = self.decoder.codingPath; codingPath.append(IndexKey(0))
114114
return ShadowDecoder(source: self.decoder.source, codingPath: codingPath)
115115
case .row: throw DecodingError.invalidContainerRequest(codingPath: self.codingPath)
116116
}
@@ -196,67 +196,67 @@ extension ShadowDecoder.KeyedContainer {
196196
}
197197
}
198198

199-
extension ShadowDecoder.KeyedContainer {
200-
func decodeIfPresent(_ type: String.Type, forKey key: Key) throws -> String? {
201-
try? self.decode(String.self, forKey: key)
202-
}
203-
204-
func decodeIfPresent(_ type: Bool.Type, forKey key: Key) throws -> Bool? {
205-
try? self.decode(Bool.self, forKey: key)
206-
}
207-
208-
func decodeIfPresent(_ type: Int.Type, forKey key: Key) throws -> Int? {
209-
try? self.decode(Int.self, forKey: key)
210-
}
211-
212-
func decodeIfPresent(_ type: Int8.Type, forKey key: Key) throws -> Int8? {
213-
try? self.decode(Int8.self, forKey: key)
214-
}
215-
216-
func decodeIfPresent(_ type: Int16.Type, forKey key: Key) throws -> Int16? {
217-
try? self.decode(Int16.self, forKey: key)
218-
}
219-
220-
func decodeIfPresent(_ type: Int32.Type, forKey key: Key) throws -> Int32? {
221-
try? self.decode(Int32.self, forKey: key)
222-
}
223-
224-
func decodeIfPresent(_ type: Int64.Type, forKey key: Key) throws -> Int64? {
225-
try? self.decode(Int64.self, forKey: key)
226-
}
227-
228-
func decodeIfPresent(_ type: UInt.Type, forKey key: Key) throws -> UInt? {
229-
try? self.decode(UInt.self, forKey: key)
230-
}
231-
232-
func decodeIfPresent(_ type: UInt8.Type, forKey key: Key) throws -> UInt8? {
233-
try? self.decode(UInt8.self, forKey: key)
234-
}
235-
236-
func decodeIfPresent(_ type: UInt16.Type, forKey key: Key) throws -> UInt16? {
237-
try? self.decode(UInt16.self, forKey: key)
238-
}
239-
240-
func decodeIfPresent(_ type: UInt32.Type, forKey key: Key) throws -> UInt32? {
241-
try? self.decode(UInt32.self, forKey: key)
242-
}
243-
244-
func decodeIfPresent(_ type: UInt64.Type, forKey key: Key) throws -> UInt64? {
245-
try? self.decode(UInt64.self, forKey: key)
246-
}
247-
248-
func decodeIfPresent(_ type: Float.Type, forKey key: Key) throws -> Float? {
249-
try? self.decode(Float.self, forKey: key)
250-
}
251-
252-
func decodeIfPresent(_ type: Double.Type, forKey key: Key) throws -> Double? {
253-
try? self.decode(Double.self, forKey: key)
254-
}
255-
256-
func decodeIfPresent<T>(_ type: T.Type, forKey key: Key) throws -> T? where T:Decodable {
257-
try? self.decode(T.self, forKey: key)
258-
}
259-
}
199+
//extension ShadowDecoder.KeyedContainer {
200+
// func decodeIfPresent(_ type: String.Type, forKey key: Key) throws -> String? {
201+
// try? self.decode(String.self, forKey: key)
202+
// }
203+
//
204+
// func decodeIfPresent(_ type: Bool.Type, forKey key: Key) throws -> Bool? {
205+
// try? self.decode(Bool.self, forKey: key)
206+
// }
207+
//
208+
// func decodeIfPresent(_ type: Int.Type, forKey key: Key) throws -> Int? {
209+
// try? self.decode(Int.self, forKey: key)
210+
// }
211+
//
212+
// func decodeIfPresent(_ type: Int8.Type, forKey key: Key) throws -> Int8? {
213+
// try? self.decode(Int8.self, forKey: key)
214+
// }
215+
//
216+
// func decodeIfPresent(_ type: Int16.Type, forKey key: Key) throws -> Int16? {
217+
// try? self.decode(Int16.self, forKey: key)
218+
// }
219+
//
220+
// func decodeIfPresent(_ type: Int32.Type, forKey key: Key) throws -> Int32? {
221+
// try? self.decode(Int32.self, forKey: key)
222+
// }
223+
//
224+
// func decodeIfPresent(_ type: Int64.Type, forKey key: Key) throws -> Int64? {
225+
// try? self.decode(Int64.self, forKey: key)
226+
// }
227+
//
228+
// func decodeIfPresent(_ type: UInt.Type, forKey key: Key) throws -> UInt? {
229+
// try? self.decode(UInt.self, forKey: key)
230+
// }
231+
//
232+
// func decodeIfPresent(_ type: UInt8.Type, forKey key: Key) throws -> UInt8? {
233+
// try? self.decode(UInt8.self, forKey: key)
234+
// }
235+
//
236+
// func decodeIfPresent(_ type: UInt16.Type, forKey key: Key) throws -> UInt16? {
237+
// try? self.decode(UInt16.self, forKey: key)
238+
// }
239+
//
240+
// func decodeIfPresent(_ type: UInt32.Type, forKey key: Key) throws -> UInt32? {
241+
// try? self.decode(UInt32.self, forKey: key)
242+
// }
243+
//
244+
// func decodeIfPresent(_ type: UInt64.Type, forKey key: Key) throws -> UInt64? {
245+
// try? self.decode(UInt64.self, forKey: key)
246+
// }
247+
//
248+
// func decodeIfPresent(_ type: Float.Type, forKey key: Key) throws -> Float? {
249+
// try? self.decode(Float.self, forKey: key)
250+
// }
251+
//
252+
// func decodeIfPresent(_ type: Double.Type, forKey key: Key) throws -> Double? {
253+
// try? self.decode(Double.self, forKey: key)
254+
// }
255+
//
256+
// func decodeIfPresent<T>(_ type: T.Type, forKey key: Key) throws -> T? where T:Decodable {
257+
// try? self.decode(T.self, forKey: key)
258+
// }
259+
//}
260260

261261
// MARK: -
262262

@@ -274,29 +274,21 @@ extension ShadowDecoder.KeyedContainer {
274274
/// - returns: The single value container holding the field decoding functionality.
275275
private func fieldContainer(forKey key: Key) throws -> ShadowDecoder.SingleValueContainer {
276276
let index: (row: Int, field: Int)
277-
let decoder: ShadowDecoder
277+
var codingPath = self.decoder.codingPath
278+
codingPath.append(key)
278279

279280
switch self.focus {
280281
case .row(let rowIndex):
281282
index = (rowIndex, try self.decoder.source.fieldIndex(forKey: key, codingPath: self.codingPath))
282-
var codingPath = self.decoder.codingPath; codingPath.append(CodecKey(index.field))
283-
decoder = ShadowDecoder(source: self.decoder.source, codingPath: codingPath)
284283
case .file:
285-
guard let rowIndex = key.intValue else {
286-
throw DecodingError.invalidKey(forRow: key, codingPath: self.codingPath + [key])
287-
}
284+
guard let rowIndex = key.intValue else { throw DecodingError.invalidKey(forRow: key, codingPath: codingPath) }
288285
// Values are only allowed to be decoded directly from a nested container in "file level" if the CSV rows have a single column.
289-
guard self.decoder.source.numFields == 1 else {
290-
throw DecodingError.invalidNestedRequired(codingPath: self.codingPath)
291-
}
292-
286+
guard self.decoder.source.numFields == 1 else { throw DecodingError.invalidNestedRequired(codingPath: self.codingPath) }
293287
index = (rowIndex, 0)
294-
var codingPath = self.decoder.codingPath
295-
codingPath.append(CodecKey(index.row))
296-
codingPath.append(CodecKey(index.field))
297-
decoder = ShadowDecoder(source: self.decoder.source, codingPath: codingPath)
288+
codingPath.append(IndexKey(index.field))
298289
}
299290

291+
let decoder = ShadowDecoder(source: self.decoder.source, codingPath: codingPath)
300292
return .init(unsafeDecoder: decoder, rowIndex: index.row, fieldIndex: index.field)
301293
}
302294
}

sources/Codable/Decodable/Containers/DecodingValue.swift renamed to sources/Codable/Decodable/Containers/SingleValueDecodingContainer.swift

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,12 @@ extension ShadowDecoder.SingleValueContainer {
146146
}
147147

148148
func decode<T>(_ type: T.Type) throws -> T where T:Decodable {
149-
if T.self == Date.self {
150-
return try self.decode(Date.self) as! T
151-
} else if T.self == Data.self {
152-
return try self.decode(Data.self) as! T
153-
} else if T.self == Decimal.self {
154-
return try self.decode(Decimal.self) as! T
155-
} else if T.self == URL.self {
156-
return try self.decode(URL.self) as! T
157-
} else {
158-
return try T(from: self.decoder)
149+
switch type {
150+
case is Date.Type: return try self.decode(Date.self) as! T
151+
case is Data.Type: return try self.decode(Data.self) as! T
152+
case is Decimal.Type: return try self.decode(Decimal.self) as! T
153+
case is URL.Type: return try self.decode(URL.self) as! T
154+
default: return try T(from: self.decoder)
159155
}
160156
}
161157
}
@@ -247,12 +243,12 @@ private extension ShadowDecoder.SingleValueContainer {
247243
// Values are only allowed to be decoded directly from a single value container in "row level" if the CSV has single column rows.
248244
guard source.numFields == 1 else { throw DecodingError.invalidNestedRequired(codingPath: self.codingPath) }
249245
let string = try source.field(at: rowIndex, 0)
250-
return try transform(string) ?! DecodingError.invalid(type: T.self, string: string, codingPath: self.codingPath + [CodecKey(0)])
246+
return try transform(string) ?! DecodingError.invalid(type: T.self, string: string, codingPath: self.codingPath + [IndexKey(0)])
251247
case .file:
252248
// Values are only allowed to be decoded directly from a single value container in "file level" if the CSV file has a single row with a single column.
253249
if source.isRowAtEnd(index: 1), source.numFields == 1 {
254250
let string = try self.decoder.source.field(at: 0, 0)
255-
return try transform(string) ?! DecodingError.invalid(type: T.self, string: string, codingPath: self.codingPath + [CodecKey(0), CodecKey(0)])
251+
return try transform(string) ?! DecodingError.invalid(type: T.self, string: string, codingPath: self.codingPath + [IndexKey(0), IndexKey(0)])
256252
} else {
257253
throw DecodingError.invalidNestedRequired(codingPath: self.codingPath)
258254
}

0 commit comments

Comments
 (0)