Skip to content

Commit 434a239

Browse files
Merge pull request #33 from DanieleCeglia-EPR/main
Added support for optional values in arrays.
2 parents 6fbd643 + 69b8635 commit 434a239

File tree

5 files changed

+45
-6
lines changed

5 files changed

+45
-6
lines changed

.github/CONTRIBUTORS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ I would like to give a special thanks to all of the people below who have contri
66

77
- [Jos Kuijpers](https://github.com/joskuijpers)
88
- [Dave Abrahams](https://github.com/dabrahams)
9+
- [Amerigo Mancino](https://github.com/AmerigoM)
10+
- [Daniele Ceglia - Electrolux Professional](https://github.com/DanieleCeglia-EPR)
911

1012
## I would like to join this list! How can I help the project?
1113

CBORCoding.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22

33
s.name = "CBORCoding"
4-
s.version = "1.4.0"
4+
s.version = "1.4.1"
55
s.summary = "A CBOR Encoder and Decoder"
66
s.description = <<-DESC
77
A lightweight framework containing a coder pair for encoding and decoding `Codable` conforming types to and from CBOR document format for iOS, macOS, tvOS, and watchOS.

Sources/CBORCoding/CBORDecoder.swift

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer {
10201020
defer { decoder.codingPath.removeLast() }
10211021

10221022
let value = container[currentIndex]
1023-
guard !(value is CBOR.Null) else {
1023+
guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else {
10241024
throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead."))
10251025
}
10261026

@@ -1039,7 +1039,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer {
10391039
defer { decoder.codingPath.removeLast() }
10401040

10411041
let value = container[currentIndex]
1042-
guard !(value is CBOR.Null) else {
1042+
guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else {
10431043
throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead."))
10441044
}
10451045

@@ -1058,7 +1058,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer {
10581058
defer { decoder.codingPath.removeLast() }
10591059

10601060
let value = container[currentIndex]
1061-
guard !(value is CBOR.Null) else {
1061+
guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else {
10621062
throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead."))
10631063
}
10641064

@@ -1077,7 +1077,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer {
10771077
defer { decoder.codingPath.removeLast() }
10781078

10791079
let value = container[currentIndex]
1080-
guard !(value is CBOR.Null) else {
1080+
guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else {
10811081
throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead."))
10821082
}
10831083

@@ -1088,6 +1088,20 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer {
10881088
}
10891089
}
10901090

1091+
// MARK: - Optional Extension
1092+
1093+
// Protocol to determine if type is optional
1094+
// https://stackoverflow.com/questions/32536420/determine-if-any-type-is-optional
1095+
1096+
protocol OptionalProtocol {}
1097+
extension Optional: OptionalProtocol {}
1098+
1099+
extension __CBORUnkeyedDecodingContainer {
1100+
private func isOptionalType(_ type: Any.Type) -> Bool {
1101+
return type is OptionalProtocol.Type
1102+
}
1103+
}
1104+
10911105
// MARK: - DecodingError Extension
10921106

10931107
extension DecodingError {

Tests/CBORCodingTests/CBORDecoderTests.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,29 @@ class CBORDecoderTests: XCTestCase {
11921192

11931193
XCTAssertNoThrow(try CBORDecoder().decode(Test2.self, from: convertFromHexString("0xA2616101616202")))
11941194
}
1195+
1196+
func testDecodingNilValuesInArray() throws {
1197+
let arrayWithNilValues: [UInt?] = [nil, nil]
1198+
let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues)
1199+
1200+
XCTAssertNoThrow(try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData))
1201+
}
1202+
1203+
func testDecodingNilValuesInArray2() throws {
1204+
let arrayWithNilValues: [UInt?] = [nil, 2]
1205+
let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues)
1206+
1207+
XCTAssertNoThrow(try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData))
1208+
}
1209+
1210+
func testDecodingNilValuesInArray3() throws {
1211+
let arrayWithNilValues: [UInt?] = [nil, 2]
1212+
let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues)
1213+
1214+
let decodedValue = try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData)
1215+
1216+
XCTAssertEqual(decodedValue, [nil, 2])
1217+
}
11951218

11961219
// MARK: Private Methods
11971220

0 commit comments

Comments
 (0)