Skip to content

Commit 707ad42

Browse files
authored
Add KeyedDecodingContainer convenience methods for optional Date (#16)
1 parent e4e6fa8 commit 707ad42

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

Sources/SQLite/PreciseDateFormatter.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,27 @@ extension KeyedDecodingContainer {
3030
}
3131
return date
3232
}
33+
34+
public func decodePreciseDateIfPresent(forKey key: K) throws -> Date? {
35+
guard let asString = try self.decodeIfPresent(String.self, forKey: key) else { return nil }
36+
guard let date = PreciseDateFormatter.date(from: asString) else {
37+
let context = DecodingError.Context(
38+
codingPath: self.codingPath,
39+
debugDescription: "Could not parse '\(asString)' into Date."
40+
)
41+
throw Swift.DecodingError.typeMismatch(Date.self, context)
42+
}
43+
return date
44+
}
3345
}
3446

3547
extension KeyedEncodingContainer {
3648
public mutating func encode(preciseDate: Date, forKey key: K) throws {
3749
try self.encode(PreciseDateFormatter.string(from: preciseDate), forKey: key)
3850
}
51+
52+
public mutating func encodeIfPresent(preciseDate: Date?, forKey key: K) throws {
53+
guard let preciseDate = preciseDate else { return }
54+
try self.encodeIfPresent(PreciseDateFormatter.string(from: preciseDate), forKey: key)
55+
}
3956
}

Tests/SQLiteTests/PreciseDateFormatterTests.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,17 @@ class PreciseDateFormatterTests: XCTestCase {
2828

2929
func testEncodingAndDecodingPreciseDate() throws {
3030
let date = Date(timeIntervalSince1970: 1534500993.44331)
31-
let model = Model(date)
31+
let optionalSome = Date(timeIntervalSince1970: 1)
32+
let optionalNone: Date? = nil
3233

33-
let encoded = try JSONEncoder().encode(model)
34-
let decoded = try JSONDecoder().decode(Model.self, from: encoded)
35-
XCTAssertEqual(model, decoded)
34+
let one = Model(date, optionalSome)
35+
let two = Model(date, optionalNone)
36+
37+
for model in [one, two] {
38+
let encoded = try JSONEncoder().encode(model)
39+
let decoded = try JSONDecoder().decode(Model.self, from: encoded)
40+
XCTAssertEqual(model, decoded)
41+
}
3642
}
3743

3844
static var allTests = [
@@ -45,23 +51,28 @@ class PreciseDateFormatterTests: XCTestCase {
4551

4652
private struct Model: Codable, Equatable {
4753
let date: Date
54+
let optionalDate: Date?
4855

49-
init(_ date: Date) {
56+
init(_ date: Date, _ optionalDate: Date?) {
5057
self.date = date
58+
self.optionalDate = optionalDate
5159
}
5260

5361
enum CodingKeys: String, CodingKey {
5462
case date
63+
case optionalDate
5564
}
5665

5766
init(from decoder: Decoder) throws {
5867
let container = try decoder.container(keyedBy: CodingKeys.self)
5968
self.date = try container.decodePreciseDate(forKey: .date)
69+
self.optionalDate = try container.decodePreciseDateIfPresent(forKey: .optionalDate)
6070
}
6171

6272
func encode(to encoder: Encoder) throws {
6373
var container = encoder.container(keyedBy: CodingKeys.self)
6474
try container.encode(preciseDate: self.date, forKey: .date)
75+
try container.encodeIfPresent(preciseDate: self.optionalDate, forKey: .optionalDate)
6576
}
6677
}
6778

0 commit comments

Comments
 (0)