From fc962f9a0d76b0d08400d49535365d4a6ccbcfa1 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Mon, 24 Dec 2018 07:05:35 -0800 Subject: [PATCH] Lift the constraint that Attributes and Relationships are Codable for EntityProxies. --- Sources/JSONAPI/Resource/Entity.swift | 16 ++++++++++------ Tests/JSONAPITests/Poly/PolyProxyTests.swift | 15 +++++++++++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Sources/JSONAPI/Resource/Entity.swift b/Sources/JSONAPI/Resource/Entity.swift index f52a7f8..2d5d2a3 100644 --- a/Sources/JSONAPI/Resource/Entity.swift +++ b/Sources/JSONAPI/Resource/Entity.swift @@ -32,21 +32,25 @@ public protocol JSONTyped { static var type: String { get } } +/// An `EntityProxyDescription` is an `EntityDescription` +/// without Codable conformance. +public protocol EntityProxyDescription: JSONTyped { + associatedtype Attributes: Equatable + associatedtype Relationships: Equatable +} + /// An `EntityDescription` describes a JSON API /// Resource Object. The Resource Object /// itself is encoded and decoded as an /// `Entity`, which gets specialized on an /// `EntityDescription`. -public protocol EntityDescription: JSONTyped { - associatedtype Attributes: JSONAPI.Attributes - associatedtype Relationships: JSONAPI.Relationships -} +public protocol EntityDescription: EntityProxyDescription where Attributes: JSONAPI.Attributes, Relationships: JSONAPI.Relationships {} /// EntityProxy is a protocol that can be used to create /// types that _act_ like Entities but cannot be encoded /// or decoded as Entities. public protocol EntityProxy: Equatable, JSONTyped { - associatedtype Description: EntityDescription + associatedtype Description: EntityProxyDescription associatedtype EntityRawIdType: JSONAPI.MaybeRawId typealias Id = JSONAPI.Id @@ -75,7 +79,7 @@ extension EntityProxy { /// EntityType is the protocol that Entity conforms to. This /// protocol lets other types accept any Entity as a generic /// specialization. -public protocol EntityType: EntityProxy, PrimaryResource { +public protocol EntityType: EntityProxy, PrimaryResource where Description: EntityDescription { associatedtype Meta: JSONAPI.Meta associatedtype Links: JSONAPI.Links } diff --git a/Tests/JSONAPITests/Poly/PolyProxyTests.swift b/Tests/JSONAPITests/Poly/PolyProxyTests.swift index 514bfe8..dc0416e 100644 --- a/Tests/JSONAPITests/Poly/PolyProxyTests.swift +++ b/Tests/JSONAPITests/Poly/PolyProxyTests.swift @@ -23,6 +23,7 @@ public class PolyProxyTests: XCTestCase { XCTAssertEqual(polyUserA[\.name], "Ken Moore") XCTAssertEqual(polyUserA.id, "1") XCTAssertEqual(polyUserA.relationships, .none) + XCTAssertEqual(polyUserA[\.x], .init(x: "y")) } func test_UserAAndBEncodeEquality() { @@ -57,6 +58,7 @@ public class PolyProxyTests: XCTestCase { XCTAssertEqual(polyUserB[\.name], "Ken Less") XCTAssertEqual(polyUserB.id, "2") XCTAssertEqual(polyUserB.relationships, .none) + XCTAssertEqual(polyUserB[\.x], .init(x: "y")) } } @@ -111,9 +113,9 @@ extension Poly2: EntityProxy, JSONTyped where A == PolyProxyTests.UserA, B == Po public var attributes: SharedUserDescription.Attributes { switch self { case .a(let a): - return .init(name: .init(value: "\(a[\.firstName]) \(a[\.lastName])")) + return .init(name: .init(value: "\(a[\.firstName]) \(a[\.lastName])"), x: .init(x: "y")) case .b(let b): - return .init(name: .init(value: b[\.name].joined(separator: " "))) + return .init(name: .init(value: b[\.name].joined(separator: " ")), x: .init(x: "y")) } } @@ -121,14 +123,19 @@ extension Poly2: EntityProxy, JSONTyped where A == PolyProxyTests.UserA, B == Po return .none } - public enum SharedUserDescription: EntityDescription { + public enum SharedUserDescription: EntityProxyDescription { public static var type: String { return A.type } - public struct Attributes: JSONAPI.Attributes { + public struct Attributes: Equatable { let name: Attribute + let x: SomeRandomThingThatIsNotCodable } public typealias Relationships = NoRelationships + + public struct SomeRandomThingThatIsNotCodable: Equatable { + let x: String + } } public typealias Description = SharedUserDescription