Skip to content

Commit 3c8bdca

Browse files
committed
Rename Identifiable to JSONAPIIdentifiable and add Swift Identifiable conformance to the same types
1 parent 1e2a87a commit 3c8bdca

6 files changed

Lines changed: 93 additions & 53 deletions

File tree

Sources/JSONAPI/Resource/Relationship.swift

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,46 +35,46 @@ public struct MetaRelationship<MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links>
3535
/// a JSON API "Resource Linkage."
3636
/// See https://jsonapi.org/format/#document-resource-object-linkage
3737
/// A convenient typealias might make your code much more legible: `One<ResourceObjectDescription>`
38-
public struct ToOneRelationship<Identifiable: JSONAPI.Identifiable, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links>: RelationshipType, Equatable {
38+
public struct ToOneRelationship<Identifiable: JSONAPI.JSONAPIIdentifiable, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links>: RelationshipType, Equatable {
3939

40-
public let id: Identifiable.Identifier
40+
public let id: Identifiable.ID
4141

4242
public let meta: MetaType
4343
public let links: LinksType
4444

45-
public init(id: Identifiable.Identifier, meta: MetaType, links: LinksType) {
45+
public init(id: Identifiable.ID, meta: MetaType, links: LinksType) {
4646
self.id = id
4747
self.meta = meta
4848
self.links = links
4949
}
5050
}
5151

5252
extension ToOneRelationship where MetaType == NoMetadata, LinksType == NoLinks {
53-
public init(id: Identifiable.Identifier) {
53+
public init(id: Identifiable.ID) {
5454
self.init(id: id, meta: .none, links: .none)
5555
}
5656
}
5757

5858
extension ToOneRelationship {
59-
public init<T: ResourceObjectType>(resourceObject: T, meta: MetaType, links: LinksType) where T.Id == Identifiable.Identifier {
59+
public init<T: ResourceObjectType>(resourceObject: T, meta: MetaType, links: LinksType) where T.Id == Identifiable.ID {
6060
self.init(id: resourceObject.id, meta: meta, links: links)
6161
}
6262
}
6363

6464
extension ToOneRelationship where MetaType == NoMetadata, LinksType == NoLinks {
65-
public init<T: ResourceObjectType>(resourceObject: T) where T.Id == Identifiable.Identifier {
65+
public init<T: ResourceObjectType>(resourceObject: T) where T.Id == Identifiable.ID {
6666
self.init(id: resourceObject.id, meta: .none, links: .none)
6767
}
6868
}
6969

7070
extension ToOneRelationship where Identifiable: OptionalRelatable {
71-
public init<T: ResourceObjectType>(resourceObject: T?, meta: MetaType, links: LinksType) where T.Id == Identifiable.Wrapped.Identifier {
71+
public init<T: ResourceObjectType>(resourceObject: T?, meta: MetaType, links: LinksType) where T.Id == Identifiable.Wrapped.ID {
7272
self.init(id: resourceObject?.id, meta: meta, links: links)
7373
}
7474
}
7575

7676
extension ToOneRelationship where Identifiable: OptionalRelatable, MetaType == NoMetadata, LinksType == NoLinks {
77-
public init<T: ResourceObjectType>(resourceObject: T?) where T.Id == Identifiable.Wrapped.Identifier {
77+
public init<T: ResourceObjectType>(resourceObject: T?) where T.Id == Identifiable.Wrapped.ID {
7878
self.init(id: resourceObject?.id, meta: .none, links: .none)
7979
}
8080
}
@@ -85,24 +85,24 @@ extension ToOneRelationship where Identifiable: OptionalRelatable, MetaType == N
8585
/// A convenient typealias might make your code much more legible: `Many<ResourceObjectDescription>`
8686
public struct ToManyRelationship<Relatable: JSONAPI.Relatable, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links>: RelationshipType, Equatable {
8787

88-
public let ids: [Relatable.Identifier]
88+
public let ids: [Relatable.ID]
8989

9090
public let meta: MetaType
9191
public let links: LinksType
9292

93-
public init(ids: [Relatable.Identifier], meta: MetaType, links: LinksType) {
93+
public init(ids: [Relatable.ID], meta: MetaType, links: LinksType) {
9494
self.ids = ids
9595
self.meta = meta
9696
self.links = links
9797
}
9898

99-
public init<T: JSONAPI.Identifiable>(pointers: [ToOneRelationship<T, NoMetadata, NoLinks>], meta: MetaType, links: LinksType) where T.Identifier == Relatable.Identifier {
99+
public init<T: JSONAPI.JSONAPIIdentifiable>(pointers: [ToOneRelationship<T, NoMetadata, NoLinks>], meta: MetaType, links: LinksType) where T.ID == Relatable.ID {
100100
ids = pointers.map(\.id)
101101
self.meta = meta
102102
self.links = links
103103
}
104104

105-
public init<T: ResourceObjectType>(resourceObjects: [T], meta: MetaType, links: LinksType) where T.Id == Relatable.Identifier {
105+
public init<T: ResourceObjectType>(resourceObjects: [T], meta: MetaType, links: LinksType) where T.Id == Relatable.ID {
106106
self.init(ids: resourceObjects.map(\.id), meta: meta, links: links)
107107
}
108108

@@ -117,40 +117,40 @@ public struct ToManyRelationship<Relatable: JSONAPI.Relatable, MetaType: JSONAPI
117117

118118
extension ToManyRelationship where MetaType == NoMetadata, LinksType == NoLinks {
119119

120-
public init(ids: [Relatable.Identifier]) {
120+
public init(ids: [Relatable.ID]) {
121121
self.init(ids: ids, meta: .none, links: .none)
122122
}
123123

124-
public init<T: JSONAPI.Identifiable>(pointers: [ToOneRelationship<T, NoMetadata, NoLinks>]) where T.Identifier == Relatable.Identifier {
124+
public init<T: JSONAPI.JSONAPIIdentifiable>(pointers: [ToOneRelationship<T, NoMetadata, NoLinks>]) where T.ID == Relatable.ID {
125125
self.init(pointers: pointers, meta: .none, links: .none)
126126
}
127127

128128
public static var none: ToManyRelationship {
129129
return .none(withMeta: .none, links: .none)
130130
}
131131

132-
public init<T: ResourceObjectType>(resourceObjects: [T]) where T.Id == Relatable.Identifier {
132+
public init<T: ResourceObjectType>(resourceObjects: [T]) where T.Id == Relatable.ID {
133133
self.init(resourceObjects: resourceObjects, meta: .none, links: .none)
134134
}
135135
}
136136

137-
public protocol Identifiable: JSONTyped {
138-
associatedtype Identifier: Equatable
137+
public protocol JSONAPIIdentifiable: JSONTyped {
138+
associatedtype ID: Equatable
139139
}
140140

141141
/// The Relatable protocol describes anything that
142142
/// has an IdType Identifier
143-
public protocol Relatable: Identifiable where Identifier: JSONAPI.IdType {
143+
public protocol Relatable: JSONAPIIdentifiable where ID: JSONAPI.IdType {
144144
}
145145

146146
/// OptionalRelatable just describes an Optional
147147
/// with a Reltable Wrapped type.
148-
public protocol OptionalRelatable: Identifiable where Identifier == Wrapped.Identifier? {
148+
public protocol OptionalRelatable: JSONAPIIdentifiable where ID == Wrapped.ID? {
149149
associatedtype Wrapped: JSONAPI.Relatable
150150
}
151151

152-
extension Optional: Identifiable, OptionalRelatable, JSONTyped where Wrapped: JSONAPI.Relatable {
153-
public typealias Identifier = Wrapped.Identifier?
152+
extension Optional: JSONAPIIdentifiable, OptionalRelatable, JSONTyped where Wrapped: JSONAPI.Relatable {
153+
public typealias ID = Wrapped.ID?
154154

155155
public static var jsonType: String { return Wrapped.jsonType }
156156
}
@@ -196,7 +196,7 @@ extension MetaRelationship: Codable {
196196
}
197197
}
198198

199-
extension ToOneRelationship: Codable where Identifiable.Identifier: OptionalId {
199+
extension ToOneRelationship: Codable where Identifiable.ID: OptionalId {
200200
public init(from decoder: Decoder) throws {
201201
let container = try decoder.container(keyedBy: ResourceLinkageCodingKeys.self)
202202

@@ -219,7 +219,7 @@ extension ToOneRelationship: Codable where Identifiable.Identifier: OptionalId {
219219
// type at which point we can store nil in `id`.
220220
let anyNil: Any? = nil
221221
if try container.decodeNil(forKey: .data) {
222-
guard let val = anyNil as? Identifiable.Identifier else {
222+
guard let val = anyNil as? Identifiable.ID else {
223223
throw DecodingError.valueNotFound(
224224
Self.self,
225225
DecodingError.Context(
@@ -256,7 +256,7 @@ extension ToOneRelationship: Codable where Identifiable.Identifier: OptionalId {
256256
)
257257
}
258258

259-
id = Identifiable.Identifier(rawValue: try identifier.decode(Identifiable.Identifier.RawType.self, forKey: .id))
259+
id = Identifiable.ID(rawValue: try identifier.decode(Identifiable.ID.RawType.self, forKey: .id))
260260
}
261261

262262
public func encode(to encoder: Encoder) throws {
@@ -273,7 +273,7 @@ extension ToOneRelationship: Codable where Identifiable.Identifier: OptionalId {
273273
// If id is nil, instead of {id: , type: } we will just
274274
// encode `null`
275275
let anyNil: Any? = nil
276-
let nilId = anyNil as? Identifiable.Identifier
276+
let nilId = anyNil as? Identifiable.ID
277277
guard id != nilId else {
278278
try container.encodeNil(forKey: .data)
279279
return
@@ -314,7 +314,7 @@ extension ToManyRelationship: Codable {
314314
path: context.codingPath)
315315
}
316316

317-
var newIds = [Relatable.Identifier]()
317+
var newIds = [Relatable.ID]()
318318
while !identifiers.isAtEnd {
319319
let identifier = try identifiers.nestedContainer(keyedBy: ResourceIdentifierCodingKeys.self)
320320

@@ -324,7 +324,7 @@ extension ToManyRelationship: Codable {
324324
throw JSONAPICodingError.typeMismatch(expected: Relatable.jsonType, found: type, path: decoder.codingPath)
325325
}
326326

327-
newIds.append(Relatable.Identifier(rawValue: try identifier.decode(Relatable.Identifier.RawType.self, forKey: .id)))
327+
newIds.append(Relatable.ID(rawValue: try identifier.decode(Relatable.ID.RawType.self, forKey: .id)))
328328
}
329329
ids = newIds
330330
}

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,13 @@ extension ResourceObject: Hashable where EntityRawIdType: RawIdType {
163163
}
164164
}
165165

166-
extension ResourceObject: Identifiable, IdentifiableResourceObjectType, Relatable where EntityRawIdType: JSONAPI.RawIdType {
167-
public typealias Identifier = ResourceObject.Id
166+
extension ResourceObject: JSONAPIIdentifiable, IdentifiableResourceObjectType, Relatable where EntityRawIdType: JSONAPI.RawIdType {
167+
public typealias ID = ResourceObject.Id
168168
}
169169

170+
@available(OSX 10.15, iOS 13, tvOS 13, watchOS 6, *)
171+
extension ResourceObject: Swift.Identifiable where EntityRawIdType: JSONAPI.RawIdType {}
172+
170173
extension ResourceObject: CustomStringConvertible {
171174
public var description: String {
172175
return "ResourceObject<\(ResourceObject.jsonType)>(id: \(String(describing: id)), attributes: \(String(describing: attributes)), relationships: \(String(describing: relationships)))"
@@ -230,7 +233,7 @@ public extension ResourceObject where EntityRawIdType == Unidentified {
230233

231234
/// Create a new `ResourceObject` from this one with the given Id.
232235
func identified<RawIdType: JSONAPI.RawIdType>(by id: RawIdType) -> ResourceObject<Description, MetaType, LinksType, RawIdType> {
233-
return .init(id: ResourceObject<Description, MetaType, LinksType, RawIdType>.Identifier(rawValue: id), attributes: attributes, relationships: relationships, meta: meta, links: links)
236+
return .init(id: ResourceObject<Description, MetaType, LinksType, RawIdType>.ID(rawValue: id), attributes: attributes, relationships: relationships, meta: meta, links: links)
234237
}
235238
}
236239

@@ -294,14 +297,14 @@ public extension ResourceObjectProxy {
294297
/// Access to an Id of a `ToOneRelationship`.
295298
/// This allows you to write `resourceObject ~> \.other` instead
296299
/// of `resourceObject.relationships.other.id`.
297-
static func ~><OtherEntity: Identifiable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity, MType, LType>>) -> OtherEntity.Identifier {
300+
static func ~><OtherEntity: JSONAPIIdentifiable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity, MType, LType>>) -> OtherEntity.ID {
298301
return entity.relationships[keyPath: path].id
299302
}
300303

301304
/// Access to an Id of an optional `ToOneRelationship`.
302305
/// This allows you to write `resourceObject ~> \.other` instead
303306
/// of `resourceObject.relationships.other?.id`.
304-
static func ~><OtherEntity: OptionalRelatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity, MType, LType>?>) -> OtherEntity.Identifier {
307+
static func ~><OtherEntity: OptionalRelatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity, MType, LType>?>) -> OtherEntity.ID {
305308
// Implementation Note: This signature applies to `ToOneRelationship<E?, _, _>?`
306309
// whereas the one below applies to `ToOneRelationship<E, _, _>?`
307310
return entity.relationships[keyPath: path]?.id
@@ -310,7 +313,7 @@ public extension ResourceObjectProxy {
310313
/// Access to an Id of an optional `ToOneRelationship`.
311314
/// This allows you to write `resourceObject ~> \.other` instead
312315
/// of `resourceObject.relationships.other?.id`.
313-
static func ~><OtherEntity: Relatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity, MType, LType>?>) -> OtherEntity.Identifier? {
316+
static func ~><OtherEntity: Relatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity, MType, LType>?>) -> OtherEntity.ID? {
314317
// Implementation Note: This signature applies to `ToOneRelationship<E, _, _>?`
315318
// whereas the one above applies to `ToOneRelationship<E?, _, _>?`
316319
return entity.relationships[keyPath: path]?.id
@@ -319,14 +322,14 @@ public extension ResourceObjectProxy {
319322
/// Access to all Ids of a `ToManyRelationship`.
320323
/// This allows you to write `resourceObject ~> \.others` instead
321324
/// of `resourceObject.relationships.others.ids`.
322-
static func ~><OtherEntity: Relatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToManyRelationship<OtherEntity, MType, LType>>) -> [OtherEntity.Identifier] {
325+
static func ~><OtherEntity: Relatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToManyRelationship<OtherEntity, MType, LType>>) -> [OtherEntity.ID] {
323326
return entity.relationships[keyPath: path].ids
324327
}
325328

326329
/// Access to all Ids of an optional `ToManyRelationship`.
327330
/// This allows you to write `resourceObject ~> \.others` instead
328331
/// of `resourceObject.relationships.others?.ids`.
329-
static func ~><OtherEntity: Relatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToManyRelationship<OtherEntity, MType, LType>?>) -> [OtherEntity.Identifier]? {
332+
static func ~><OtherEntity: Relatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToManyRelationship<OtherEntity, MType, LType>?>) -> [OtherEntity.ID]? {
330333
return entity.relationships[keyPath: path]?.ids
331334
}
332335
}

Sources/JSONAPITesting/Relationship+Literal.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,39 @@
77

88
import JSONAPI
99

10-
extension ToOneRelationship: ExpressibleByNilLiteral where Identifiable.Identifier: ExpressibleByNilLiteral, MetaType == NoMetadata, LinksType == NoLinks {
10+
extension ToOneRelationship: ExpressibleByNilLiteral where Identifiable.ID: ExpressibleByNilLiteral, MetaType == NoMetadata, LinksType == NoLinks {
1111
public init(nilLiteral: ()) {
1212

13-
self.init(id: Identifiable.Identifier(nilLiteral: ()))
13+
self.init(id: Identifiable.ID(nilLiteral: ()))
1414
}
1515
}
1616

17-
extension ToOneRelationship: ExpressibleByUnicodeScalarLiteral where Identifiable.Identifier: ExpressibleByUnicodeScalarLiteral, MetaType == NoMetadata, LinksType == NoLinks {
18-
public typealias UnicodeScalarLiteralType = Identifiable.Identifier.UnicodeScalarLiteralType
17+
extension ToOneRelationship: ExpressibleByUnicodeScalarLiteral where Identifiable.ID: ExpressibleByUnicodeScalarLiteral, MetaType == NoMetadata, LinksType == NoLinks {
18+
public typealias UnicodeScalarLiteralType = Identifiable.ID.UnicodeScalarLiteralType
1919

2020
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
21-
self.init(id: Identifiable.Identifier(unicodeScalarLiteral: value))
21+
self.init(id: Identifiable.ID(unicodeScalarLiteral: value))
2222
}
2323
}
2424

25-
extension ToOneRelationship: ExpressibleByExtendedGraphemeClusterLiteral where Identifiable.Identifier: ExpressibleByExtendedGraphemeClusterLiteral, MetaType == NoMetadata, LinksType == NoLinks {
26-
public typealias ExtendedGraphemeClusterLiteralType = Identifiable.Identifier.ExtendedGraphemeClusterLiteralType
25+
extension ToOneRelationship: ExpressibleByExtendedGraphemeClusterLiteral where Identifiable.ID: ExpressibleByExtendedGraphemeClusterLiteral, MetaType == NoMetadata, LinksType == NoLinks {
26+
public typealias ExtendedGraphemeClusterLiteralType = Identifiable.ID.ExtendedGraphemeClusterLiteralType
2727

2828
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
29-
self.init(id: Identifiable.Identifier(extendedGraphemeClusterLiteral: value))
29+
self.init(id: Identifiable.ID(extendedGraphemeClusterLiteral: value))
3030
}
3131
}
3232

33-
extension ToOneRelationship: ExpressibleByStringLiteral where Identifiable.Identifier: ExpressibleByStringLiteral, MetaType == NoMetadata, LinksType == NoLinks {
34-
public typealias StringLiteralType = Identifiable.Identifier.StringLiteralType
33+
extension ToOneRelationship: ExpressibleByStringLiteral where Identifiable.ID: ExpressibleByStringLiteral, MetaType == NoMetadata, LinksType == NoLinks {
34+
public typealias StringLiteralType = Identifiable.ID.StringLiteralType
3535

3636
public init(stringLiteral value: StringLiteralType) {
37-
self.init(id: Identifiable.Identifier(stringLiteral: value))
37+
self.init(id: Identifiable.ID(stringLiteral: value))
3838
}
3939
}
4040

4141
extension ToManyRelationship: ExpressibleByArrayLiteral where MetaType == NoMetadata, LinksType == NoLinks {
42-
public typealias ArrayLiteralElement = Relatable.Identifier
42+
public typealias ArrayLiteralElement = Relatable.ID
4343

4444
public init(arrayLiteral elements: ArrayLiteralElement...) {
4545
self.init(ids: elements)

Tests/JSONAPITests/NonJSONAPIRelatable/NonJSONAPIRelatableTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extension NonJSONAPIRelatableTests {
8383
struct NonJSONAPIEntity: Relatable, JSONTyped {
8484
static var jsonType: String { return "other" }
8585

86-
typealias Identifier = NonJSONAPIEntity.Id
86+
typealias ID = NonJSONAPIEntity.Id
8787

8888
let id: Id
8989

Tests/JSONAPITests/ResourceObject/ResourceObjectTests.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class ResourceObjectTests: XCTestCase {
9191
let _ = TestEntity9(id: .init(rawValue: "9"), attributes: .none, relationships: .init(meta: .init(meta: .init(x: "hello", y: 5), links: .none), optionalMeta: nil, one: entity1.pointer, nullableOne: nil, optionalOne: entity1.pointer, optionalNullableOne: nil, optionalMany: nil), meta: .none, links: .none)
9292
let _ = TestEntity9(id: .init(rawValue: "9"), attributes: .none, relationships: .init(meta: .init(meta: .init(x: "hello", y: 5), links: .none), optionalMeta: nil, one: entity1.pointer, nullableOne: nil, optionalOne: nil, optionalNullableOne: .init(resourceObject: entity1, meta: .none, links: .none), optionalMany: nil), meta: .none, links: .none)
9393
let _ = TestEntity9(id: .init(rawValue: "9"), attributes: .none, relationships: .init(meta: .init(meta: .init(x: "hello", y: 5), links: .none), optionalMeta: nil, one: entity1.pointer, nullableOne: nil, optionalOne: nil, optionalNullableOne: .init(resourceObject: entity1, meta: .none, links: .none), optionalMany: .init(resourceObjects: [], meta: .none, links: .none)), meta: .none, links: .none)
94-
let e10id1 = TestEntity10.Identifier(rawValue: "hello")
94+
let e10id1 = TestEntity10.ID(rawValue: "hello")
9595
let e10id2 = TestEntity10.Id(rawValue: "world")
9696
let e10id3: TestEntity10.Id = "!"
9797
let _ = TestEntity10(id: .init(rawValue: "10"), attributes: .none, relationships: .init(selfRef: .init(id: e10id1), selfRefs: .init(ids: [e10id2, e10id3])), meta: .none, links: .none)
@@ -901,15 +901,15 @@ extension ResourceObjectTests {
901901
typealias Attributes = NoAttributes
902902

903903
struct Relationships: JSONAPI.Relationships {
904-
var metaRelationship: (TestEntityWithMetaRelationship) -> TestEntity1.Identifier {
904+
var metaRelationship: (TestEntityWithMetaRelationship) -> TestEntity1.ID {
905905
return { entity in
906-
return TestEntity1.Identifier(rawValue: "hello")
906+
return TestEntity1.ID(rawValue: "hello")
907907
}
908908
}
909909

910-
var toManyMetaRelationship: (TestEntityWithMetaRelationship) -> [TestEntity1.Identifier] {
910+
var toManyMetaRelationship: (TestEntityWithMetaRelationship) -> [TestEntity1.ID] {
911911
return { entity in
912-
return [TestEntity1.Identifier.id(from: "hello")]
912+
return [TestEntity1.ID.id(from: "hello")]
913913
}
914914
}
915915
}

0 commit comments

Comments
 (0)