diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f332bfb..736e54c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ [Norio Nomura](https://github.com/norio-nomura) [#146](https://github.com/jpsim/Yams/pull/146) +* Fix null/~/NULL/Null were parsed as strings, not nil by `YAMLDecoder`. + [Norio Nomura](https://github.com/norio-nomura) + [#157](https://github.com/jpsim/Yams/issues/157) + ## 1.0.1 ##### Breaking diff --git a/Sources/Yams/Decoder.swift b/Sources/Yams/Decoder.swift index 19fba00a..6a085cbe 100644 --- a/Sources/Yams/Decoder.swift +++ b/Sources/Yams/Decoder.swift @@ -109,7 +109,7 @@ private struct _KeyedDecodingContainer : KeyedDecodingContainerP func contains(_ key: Key) -> Bool { return mapping[key.stringValue] != nil } func decodeNil(forKey key: Key) throws -> Bool { - return try node(for: key) == Node("null", Tag(.null)) + return try decoder(for: key).decodeNil() } func decode(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable & ScalarConstructible { @@ -166,12 +166,7 @@ private struct _UnkeyedDecodingContainer: UnkeyedDecodingContainer { mutating func decodeNil() throws -> Bool { try throwErrorIfAtEnd(Any?.self) - if currentNode == Node("null", Tag(.null)) { - currentIndex += 1 - return true - } else { - return false - } + return try currentDecoder { $0.decodeNil() } } mutating func decode(_ type: T.Type) throws -> T where T: Decodable & ScalarConstructible { diff --git a/Tests/YamsTests/EncoderTests.swift b/Tests/YamsTests/EncoderTests.swift index 46ea23a3..79e157d4 100644 --- a/Tests/YamsTests/EncoderTests.swift +++ b/Tests/YamsTests/EncoderTests.swift @@ -316,6 +316,29 @@ class EncoderTests: XCTestCase { // swiftlint:disable:this type_body_length expectEqual(type(of: decoded), Employee.self, "Expected decoded value to be of type Employee; got \(type(of: decoded)) instead.") } + func test_null_yml() throws { + let s = """ + n1: ~ + n2: null + n3: NULL + n4: Null + n5: + """ + struct Test: Decodable { + let n1: String? + let n2: String? + let n3: String? + let n4: String? + let n5: String? + } + let t = try YAMLDecoder().decode(Test.self, from: s) + XCTAssertNil(t.n1) + XCTAssertNil(t.n2) + XCTAssertNil(t.n3) + XCTAssertNil(t.n4) + XCTAssertNil(t.n5) + } + // MARK: - Helper Functions private func _testRoundTrip(of value: T, @@ -1089,7 +1112,8 @@ extension EncoderTests { ("testValuesInUnkeyedContainer", testValuesInUnkeyedContainer), ("testDictionary", testDictionary), ("testNodeTypeMismatch", testNodeTypeMismatch), - ("testDecodingConcreteTypeParameter", testDecodingConcreteTypeParameter) + ("testDecodingConcreteTypeParameter", testDecodingConcreteTypeParameter), + ("test_null_yml", test_null_yml) ] } }