Skip to content

Commit 58ebdc9

Browse files
authored
Merge pull request #116 from mattpolzin/fix-optional-meta-omit-decode
Allow optional metadata to be omitted as well as nulled out.
2 parents 3856a88 + 6f8e133 commit 58ebdc9

File tree

5 files changed

+37
-12
lines changed

5 files changed

+37
-12
lines changed

Sources/JSONAPI/Document/DocumentDecodingError.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ public enum DocumentDecodingError: Swift.Error, Equatable {
3333
self = .primaryResourceMissing
3434
case .valueNotFound(let type, let context) where Location(context) == .data && type == UnkeyedDecodingContainer.self:
3535
self = .primaryResourcesMissing
36+
case .valueNotFound(let type, let context) where Location(context) == .data && type is _ArrayType.Type && context.debugDescription.hasSuffix("found null value instead"):
37+
self = .primaryResourcesMissing
38+
case .valueNotFound(_, let context) where Location(context) == .data && context.debugDescription.hasSuffix("found null value instead"):
39+
self = .primaryResourceMissing
3640
case .typeMismatch(let type, let context) where Location(context) == .data && type is _ArrayType.Type && context.debugDescription.hasSuffix("but found null instead."):
3741
self = .primaryResourcesMissing
3842
case .typeMismatch(_, let context) where Location(context) == .data && context.debugDescription.hasSuffix("but found null instead."):

Sources/JSONAPI/Resource/Relationship.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,6 @@ extension MetaRelationship: Codable {
263263
}
264264
}
265265

266-
fileprivate protocol _Optional {}
267-
extension Optional: _Optional {}
268-
269266
extension ToOneRelationship: Codable where Identifiable.ID: OptionalId {
270267
public init(from decoder: Decoder) throws {
271268
let container = try decoder.container(keyedBy: ResourceLinkageCodingKeys.self)

Sources/JSONAPI/Resource/Resource Object/ResourceObject.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,17 @@ public extension ResourceObject {
447447
)
448448
}
449449

450-
meta = try (NoMetadata() as? MetaType) ?? container.decode(MetaType.self, forKey: .meta)
450+
do {
451+
meta = try (NoMetadata() as? MetaType) ?? container.decode(MetaType.self, forKey: .meta)
452+
} catch let decodingError as DecodingError {
453+
let anyNil: Any? = nil
454+
455+
guard case .keyNotFound = decodingError,
456+
let omittedMeta = anyNil as? MetaType else {
457+
throw decodingError
458+
}
459+
meta = omittedMeta
460+
}
451461

452462
links = try (NoLinks() as? LinksType) ?? container.decode(LinksType.self, forKey: .links)
453463
}

Tests/JSONAPITests/ResourceObject/ResourceObjectTests.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ extension ResourceObjectTests {
151151
data: entity_no_relationships_no_attributes)
152152
}
153153

154+
func test_EntityNoMetaDecodesAsOptionalMeta() {
155+
let _ = decoded(type: TestEntityOptionalMeta.self,
156+
data: entity_no_relationships_no_attributes)
157+
}
158+
154159
func test_EntityNoRelationshipsSomeAttributes() {
155160
let entity = decoded(type: TestEntity5.self,
156161
data: entity_no_relationships_some_attributes)
@@ -861,13 +866,13 @@ extension ResourceObjectTests {
861866

862867
public struct Relationships: JSONAPI.Relationships {
863868
public init() {
864-
optionalMeta = nil
869+
optionalMeta = nil
865870
optionalOne = nil
866871
optionalNullableOne = nil
867872
optionalMany = nil
868873
}
869874

870-
let optionalMeta: MetaRelationship<TestEntityMeta, NoLinks>?
875+
let optionalMeta: MetaRelationship<TestEntityMeta, NoLinks>?
871876

872877
let optionalOne: ToOneRelationship<TestEntity1, NoIdMetadata, NoMetadata, NoLinks>?
873878

@@ -879,6 +884,19 @@ extension ResourceObjectTests {
879884

880885
typealias TestEntity12 = BasicEntity<TestEntityType12>
881886

887+
enum TestEntityOptionalMetaType: JSONAPI.ResourceObjectDescription {
888+
public static var jsonType: String { return "test_entities" }
889+
890+
typealias Attributes = NoAttributes
891+
typealias Relationships = NoRelationships
892+
}
893+
894+
struct UnimportantMeta: JSONAPI.Meta {
895+
let property1: String
896+
}
897+
898+
typealias TestEntityOptionalMeta = JSONAPI.ResourceObject<TestEntityOptionalMetaType, UnimportantMeta?, NoLinks, String>
899+
882900
enum UnidentifiedTestEntityType: ResourceObjectDescription {
883901
public static var jsonType: String { return "unidentified_test_entities" }
884902

Tests/JSONAPITests/SparseFields/SparseFieldEncoderTests.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,9 @@ class SparseFieldEncoderTests: XCTestCase {
4343
XCTAssertEqual(allThingsOnDeserialized["bool"] as? Bool, true)
4444
XCTAssertEqual(allThingsOnDeserialized["double"] as? Double, 10.5)
4545
XCTAssertEqual(allThingsOnDeserialized["string"] as? String, "hello")
46-
#if os(Linux)
47-
// There's some bug with Linux where it won't case the value to a float.
48-
// It does exist and it is == 1.2
46+
// For latest versions of MacOS and all versions of Linux, floats
47+
// decode as doubles.
4948
XCTAssertEqual(allThingsOnDeserialized["float"] as? Double, 1.2)
50-
#else
51-
XCTAssertEqual(allThingsOnDeserialized["float"] as? Float, 1.2)
52-
#endif
5349
XCTAssertEqual(allThingsOnDeserialized["int"] as? Int, 3)
5450
XCTAssertEqual(allThingsOnDeserialized["int8"] as? Int8, 4)
5551
XCTAssertEqual(allThingsOnDeserialized["int16"] as? Int16, 5)

0 commit comments

Comments
 (0)