diff --git a/Sources/BetterCodable/DefaultCodable.swift b/Sources/BetterCodable/DefaultCodable.swift index ed328c7..4ac41b4 100644 --- a/Sources/BetterCodable/DefaultCodable.swift +++ b/Sources/BetterCodable/DefaultCodable.swift @@ -30,3 +30,18 @@ public struct DefaultCodable: Codable { extension DefaultCodable: Equatable where Default.RawValue: Equatable { } extension DefaultCodable: Hashable where Default.RawValue: Hashable { } + +// MARK: - KeyedDecodingContainer +public extension KeyedDecodingContainer { + + /// Default implementation of decoding a DefaultCodable + /// + /// Decodes successfully if key is available if not fallsback to the default value provided. + func decode

(_: DefaultCodable

.Type, forKey key: Key) throws -> DefaultCodable

{ + if let value = try decodeIfPresent(DefaultCodable

.self, forKey: key) { + return value + } else { + return DefaultCodable(wrappedValue: P.defaultValue) + } + } +} diff --git a/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift b/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift index 5edad25..dbfab0e 100644 --- a/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift +++ b/Tests/BetterCodableTests/DefaulEmptyDictionaryTests.swift @@ -11,6 +11,12 @@ class DefaultEmptyDictionaryTests: XCTestCase { let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) XCTAssertEqual(fixture.stringToInt, [:]) } + + func testDecodingKeyNotPresentDefaultsToEmptyDictionary() throws { + let jsonData = #"{}"#.data(using: .utf8)! + let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) + XCTAssertEqual(fixture.stringToInt, [:]) + } func testEncodingDecodedFailableDictionaryDefaultsToEmptyDictionary() throws { let jsonData = #"{ "stringToInt": null }"#.data(using: .utf8)! diff --git a/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift b/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift index a66f46b..b00d191 100644 --- a/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift +++ b/Tests/BetterCodableTests/DefaultEmptyArrayTests.swift @@ -18,6 +18,13 @@ class DefaultEmptyArrayTests: XCTestCase { XCTAssertEqual(fixture.values, []) XCTAssertEqual(fixture.nonPrimitiveValues, []) } + + func testDecodingKeyNotPresentDefaultsToEmptyArray() throws { + let jsonData = #"{}"#.data(using: .utf8)! + let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) + XCTAssertEqual(fixture.values, []) + XCTAssertEqual(fixture.nonPrimitiveValues, []) + } func testEncodingDecodedFailableArrayDefaultsToEmptyArray() throws { let jsonData = #"{ "values": null, "nonPrimitiveValues": null }"#.data(using: .utf8)! diff --git a/Tests/BetterCodableTests/DefaultFalseTests.swift b/Tests/BetterCodableTests/DefaultFalseTests.swift index 65039b4..1ce1ede 100644 --- a/Tests/BetterCodableTests/DefaultFalseTests.swift +++ b/Tests/BetterCodableTests/DefaultFalseTests.swift @@ -6,13 +6,19 @@ class DefaultFalseTests: XCTestCase { @DefaultFalse var truthy: Bool } - func testDecodingFailableArrayDefaultsToEmptyArray() throws { + func testDecodingFailableArrayDefaultsToFalse() throws { let jsonData = #"{ "truthy": null }"#.data(using: .utf8)! let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) XCTAssertEqual(fixture.truthy, false) } + + func testDecodingKeyNotPresentDefaultsToFalse() throws { + let jsonData = #"{}"#.data(using: .utf8)! + let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) + XCTAssertEqual(fixture.truthy, false) + } - func testEncodingDecodedFailableArrayDefaultsToEmptyArray() throws { + func testEncodingDecodedFailableArrayDefaultsToFalse() throws { let jsonData = #"{ "truthy": null }"#.data(using: .utf8)! var _fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) @@ -23,7 +29,7 @@ class DefaultFalseTests: XCTestCase { XCTAssertEqual(fixture.truthy, true) } - func testEncodingDecodedFulfillableArrayRetainsContents() throws { + func testEncodingDecodedFulfillableBoolRetainsValue() throws { let jsonData = #"{ "truthy": true }"#.data(using: .utf8)! let _fixture = try JSONDecoder().decode(Fixture.self, from: jsonData) let fixtureData = try JSONEncoder().encode(_fixture)