Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for optional values in arrays. #33

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ I would like to give a special thanks to all of the people below who have contri

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

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

Expand Down
2 changes: 1 addition & 1 deletion CBORCoding.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "CBORCoding"
s.version = "1.4.0"
s.version = "1.4.1"
s.summary = "A CBOR Encoder and Decoder"
s.description = <<-DESC
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.
Expand Down
2 changes: 1 addition & 1 deletion Half
22 changes: 18 additions & 4 deletions Sources/CBORCoding/CBORDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer {
defer { decoder.codingPath.removeLast() }

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

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

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

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

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

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

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

Expand All @@ -1088,6 +1088,20 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer {
}
}

// MARK: - Optional Extension

// Protocol to determine if type is optional
// https://stackoverflow.com/questions/32536420/determine-if-any-type-is-optional

protocol OptionalProtocol {}
extension Optional: OptionalProtocol {}

extension __CBORUnkeyedDecodingContainer {
private func isOptionalType(_ type: Any.Type) -> Bool {
return type is OptionalProtocol.Type
}
}

// MARK: - DecodingError Extension

extension DecodingError {
Expand Down
23 changes: 23 additions & 0 deletions Tests/CBORCodingTests/CBORDecoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,29 @@ class CBORDecoderTests: XCTestCase {

XCTAssertNoThrow(try CBORDecoder().decode(Test2.self, from: convertFromHexString("0xA2616101616202")))
}

func testDecodingNilValuesInArray() throws {
let arrayWithNilValues: [UInt?] = [nil, nil]
let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues)

XCTAssertNoThrow(try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData))
}

func testDecodingNilValuesInArray2() throws {
let arrayWithNilValues: [UInt?] = [nil, 2]
let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues)

XCTAssertNoThrow(try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData))
}

func testDecodingNilValuesInArray3() throws {
let arrayWithNilValues: [UInt?] = [nil, 2]
let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues)

let decodedValue = try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData)

XCTAssertEqual(decodedValue, [nil, 2])
}

// MARK: Private Methods

Expand Down