Skip to content

Commit 8aa887b

Browse files
committed
Add metadata and links to resource objects (i.e. Entity). untested.
1 parent 7d0a686 commit 8aa887b

16 files changed

Lines changed: 257 additions & 70 deletions

File tree

Sources/JSONAPI/Resource/Entity.swift

Lines changed: 187 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public protocol IdentifiableEntityType: EntityType, Relatable where EntityRawIdT
8080
/// encoded to or decoded from a JSON API
8181
/// "Resource Object."
8282
/// See https://jsonapi.org/format/#document-resource-objects
83-
public struct Entity<Description: JSONAPI.EntityDescription, EntityRawIdType: JSONAPI.MaybeRawId>: EntityType {
83+
public struct Entity<Description: JSONAPI.EntityDescription, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links, EntityRawIdType: JSONAPI.MaybeRawId>: EntityType {
8484
/// The `Entity`'s Id. This can be of type `Unidentified` if
8585
/// the entity is being created clientside and the
8686
/// server is being asked to create a unique Id. Otherwise,
@@ -92,11 +92,19 @@ public struct Entity<Description: JSONAPI.EntityDescription, EntityRawIdType: JS
9292

9393
/// The JSON API compliant relationships of this `Entity`.
9494
public let relationships: Description.Relationships
95+
96+
/// Any additional metadata packaged with the entity.
97+
public let meta: MetaType
98+
99+
/// Links related to the entity.
100+
public let links: LinksType
95101

96-
public init(id: Entity.Id, attributes: Description.Attributes, relationships: Description.Relationships) {
102+
public init(id: Entity.Id, attributes: Description.Attributes, relationships: Description.Relationships, meta: MetaType, links: LinksType) {
97103
self.id = id
98104
self.attributes = attributes
99105
self.relationships = relationships
106+
self.meta = meta
107+
self.links = links
100108
}
101109
}
102110

@@ -113,60 +121,214 @@ extension Entity: CustomStringConvertible {
113121

114122
// MARK: Convenience initializers
115123
extension Entity where EntityRawIdType: CreatableRawIdType {
116-
public init(attributes: Description.Attributes, relationships: Description.Relationships) {
124+
public init(attributes: Description.Attributes, relationships: Description.Relationships, meta: MetaType, links: LinksType) {
117125
self.id = Entity.Id()
118126
self.attributes = attributes
119127
self.relationships = relationships
128+
self.meta = meta
129+
self.links = links
120130
}
121131
}
122132

123133
extension Entity where EntityRawIdType == Unidentified {
124-
public init(attributes: Description.Attributes, relationships: Description.Relationships) {
134+
public init(attributes: Description.Attributes, relationships: Description.Relationships, meta: MetaType, links: LinksType) {
125135
self.id = .unidentified
126136
self.attributes = attributes
127137
self.relationships = relationships
138+
self.meta = meta
139+
self.links = links
128140
}
129141
}
130142

131143
extension Entity where Description.Attributes == NoAttributes {
144+
public init(id: Entity.Id, relationships: Description.Relationships, meta: MetaType, links: LinksType) {
145+
self.init(id: id, attributes: NoAttributes(), relationships: relationships, meta: meta, links: links)
146+
}
147+
}
148+
149+
extension Entity where Description.Attributes == NoAttributes, MetaType == NoMetadata {
150+
public init(id: Entity.Id, relationships: Description.Relationships, links: LinksType) {
151+
self.init(id: id, relationships: relationships, meta: .none, links: links)
152+
}
153+
}
154+
155+
extension Entity where Description.Attributes == NoAttributes, LinksType == NoLinks {
156+
public init(id: Entity.Id, relationships: Description.Relationships, meta: MetaType) {
157+
self.init(id: id, relationships: relationships, meta: meta, links: .none)
158+
}
159+
}
160+
161+
extension Entity where Description.Attributes == NoAttributes, MetaType == NoMetadata, LinksType == NoLinks {
132162
public init(id: Entity.Id, relationships: Description.Relationships) {
133-
self.init(id: id, attributes: NoAttributes(), relationships: relationships)
163+
self.init(id: id, relationships: relationships, links: .none)
134164
}
135165
}
136166

137167
extension Entity where Description.Attributes == NoAttributes, EntityRawIdType: CreatableRawIdType {
168+
public init(relationships: Description.Relationships, meta: MetaType, links: LinksType) {
169+
self.init(attributes: NoAttributes(), relationships: relationships, meta: meta, links: links)
170+
}
171+
}
172+
173+
extension Entity where Description.Attributes == NoAttributes, MetaType == NoMetadata, EntityRawIdType: CreatableRawIdType {
174+
public init(relationships: Description.Relationships, links: LinksType) {
175+
self.init(attributes: NoAttributes(), relationships: relationships, meta: .none, links: links)
176+
}
177+
}
178+
179+
extension Entity where Description.Attributes == NoAttributes, LinksType == NoLinks, EntityRawIdType: CreatableRawIdType {
180+
public init(relationships: Description.Relationships, meta: MetaType) {
181+
self.init(attributes: NoAttributes(), relationships: relationships, meta: meta, links: .none)
182+
}
183+
}
184+
185+
extension Entity where Description.Attributes == NoAttributes, MetaType == NoMetadata, LinksType == NoLinks, EntityRawIdType: CreatableRawIdType {
138186
public init(relationships: Description.Relationships) {
139-
self.init(attributes: NoAttributes(), relationships: relationships)
187+
self.init(attributes: NoAttributes(), relationships: relationships, meta: .none, links: .none)
188+
}
189+
}
190+
191+
extension Entity where Description.Attributes == NoAttributes, EntityRawIdType == Unidentified {
192+
public init(relationships: Description.Relationships, meta: MetaType, links: LinksType) {
193+
self.init(attributes: NoAttributes(), relationships: relationships, meta: meta, links: links)
140194
}
141195
}
142196

143197
extension Entity where Description.Relationships == NoRelationships {
198+
public init(id: Entity.Id, attributes: Description.Attributes, meta: MetaType, links: LinksType) {
199+
self.init(id: id, attributes: attributes, relationships: NoRelationships(), meta: meta, links: links)
200+
}
201+
}
202+
203+
extension Entity where Description.Relationships == NoRelationships, MetaType == NoMetadata {
204+
public init(id: Entity.Id, attributes: Description.Attributes, links: LinksType) {
205+
self.init(id: id, attributes: attributes, meta: .none, links: links)
206+
}
207+
}
208+
209+
extension Entity where Description.Relationships == NoRelationships, LinksType == NoLinks {
210+
public init(id: Entity.Id, attributes: Description.Attributes, meta: MetaType) {
211+
self.init(id: id, attributes: attributes, meta: meta, links: .none)
212+
}
213+
}
214+
215+
extension Entity where Description.Relationships == NoRelationships, MetaType == NoMetadata, LinksType == NoLinks {
144216
public init(id: Entity.Id, attributes: Description.Attributes) {
145-
self.init(id: id, attributes: attributes, relationships: NoRelationships())
217+
self.init(id: id, attributes: attributes, meta: .none, links: .none)
146218
}
147219
}
148220

149221
extension Entity where Description.Relationships == NoRelationships, EntityRawIdType: CreatableRawIdType {
222+
public init(attributes: Description.Attributes, meta: MetaType, links: LinksType) {
223+
self.init(attributes: attributes, relationships: NoRelationships(), meta: meta, links: links)
224+
}
225+
}
226+
227+
extension Entity where Description.Relationships == NoRelationships, MetaType == NoMetadata, EntityRawIdType: CreatableRawIdType {
228+
public init(attributes: Description.Attributes, links: LinksType) {
229+
self.init(attributes: attributes, relationships: NoRelationships(), meta: .none, links: links)
230+
}
231+
}
232+
233+
extension Entity where Description.Relationships == NoRelationships, LinksType == NoLinks, EntityRawIdType: CreatableRawIdType {
234+
public init(attributes: Description.Attributes, meta: MetaType) {
235+
self.init(attributes: attributes, relationships: NoRelationships(), meta: meta, links: .none)
236+
}
237+
}
238+
239+
extension Entity where Description.Relationships == NoRelationships, MetaType == NoMetadata, LinksType == NoLinks, EntityRawIdType: CreatableRawIdType {
150240
public init(attributes: Description.Attributes) {
151-
self.init(attributes: attributes, relationships: NoRelationships())
241+
self.init(attributes: attributes, relationships: NoRelationships(), meta: .none, links: .none)
152242
}
153243
}
154244

155245
extension Entity where Description.Relationships == NoRelationships, EntityRawIdType == Unidentified {
246+
public init(attributes: Description.Attributes, meta: MetaType, links: LinksType) {
247+
self.init(attributes: attributes, relationships: NoRelationships(), meta: meta, links: links)
248+
}
249+
}
250+
251+
extension Entity where Description.Relationships == NoRelationships, MetaType == NoMetadata, EntityRawIdType == Unidentified {
252+
public init(attributes: Description.Attributes, links: LinksType) {
253+
self.init(attributes: attributes, relationships: NoRelationships(), meta: .none, links: links)
254+
}
255+
}
256+
257+
extension Entity where Description.Relationships == NoRelationships, LinksType == NoLinks, EntityRawIdType == Unidentified {
258+
public init(attributes: Description.Attributes, meta: MetaType) {
259+
self.init(attributes: attributes, relationships: NoRelationships(), meta: meta, links: .none)
260+
}
261+
}
262+
263+
extension Entity where Description.Relationships == NoRelationships, MetaType == NoMetadata, LinksType == NoLinks, EntityRawIdType == Unidentified {
156264
public init(attributes: Description.Attributes) {
157-
self.init(attributes: attributes, relationships: NoRelationships())
265+
self.init(attributes: attributes, relationships: NoRelationships(), meta: .none, links: .none)
158266
}
159267
}
160268

161269
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships {
270+
public init(id: Entity.Id, meta: MetaType, links: LinksType) {
271+
self.init(id: id, attributes: NoAttributes(), relationships: NoRelationships(), meta: meta, links: links)
272+
}
273+
}
274+
275+
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships, MetaType == NoMetadata {
276+
public init(id: Entity.Id, links: LinksType) {
277+
self.init(id: id, attributes: NoAttributes(), relationships: NoRelationships(), meta: .none, links: links)
278+
}
279+
}
280+
281+
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships, LinksType == NoLinks {
282+
public init(id: Entity.Id, meta: MetaType) {
283+
self.init(id: id, attributes: NoAttributes(), relationships: NoRelationships(), meta: meta, links: .none)
284+
}
285+
}
286+
287+
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships, MetaType == NoMetadata, LinksType == NoLinks {
162288
public init(id: Entity.Id) {
163-
self.init(id: id, attributes: NoAttributes(), relationships: NoRelationships())
289+
self.init(id: id, attributes: NoAttributes(), relationships: NoRelationships(), meta: .none, links: .none)
164290
}
165291
}
166292

167293
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships, EntityRawIdType: CreatableRawIdType {
294+
public init(meta: MetaType, links: LinksType) {
295+
self.init(attributes: NoAttributes(), relationships: NoRelationships(), meta: meta, links: links)
296+
}
297+
}
298+
299+
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships, MetaType == NoMetadata, EntityRawIdType: CreatableRawIdType {
300+
public init(links: LinksType) {
301+
self.init(attributes: NoAttributes(), relationships: NoRelationships(), meta: .none, links: links)
302+
}
303+
}
304+
305+
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships, LinksType == NoLinks, EntityRawIdType: CreatableRawIdType {
306+
public init(meta: MetaType) {
307+
self.init(attributes: NoAttributes(), relationships: NoRelationships(), meta: meta, links: .none)
308+
}
309+
}
310+
311+
extension Entity where Description.Attributes == NoAttributes, Description.Relationships == NoRelationships, MetaType == NoMetadata, LinksType == NoLinks, EntityRawIdType: CreatableRawIdType {
168312
public init() {
169-
self.init(attributes: NoAttributes(), relationships: NoRelationships())
313+
self.init(attributes: NoAttributes(), relationships: NoRelationships(), meta: .none, links: .none)
314+
}
315+
}
316+
317+
extension Entity where MetaType == NoMetadata {
318+
public init(id: Entity.Id, attributes: Description.Attributes, relationships: Description.Relationships, links: LinksType) {
319+
self.init(id: id, attributes: attributes, relationships: relationships, meta: .none, links: links)
320+
}
321+
}
322+
323+
extension Entity where LinksType == NoLinks {
324+
public init(id: Entity.Id, attributes: Description.Attributes, relationships: Description.Relationships, meta: MetaType) {
325+
self.init(id: id, attributes: attributes, relationships: relationships, meta: meta, links: .none)
326+
}
327+
}
328+
329+
extension Entity where MetaType == NoMetadata, LinksType == NoLinks {
330+
public init(id: Entity.Id, attributes: Description.Attributes, relationships: Description.Relationships) {
331+
self.init(id: id, attributes: attributes, relationships: relationships, meta: .none, links: .none)
170332
}
171333
}
172334

@@ -228,6 +390,8 @@ private enum ResourceObjectCodingKeys: String, CodingKey {
228390
case id = "id"
229391
case attributes = "attributes"
230392
case relationships = "relationships"
393+
case meta = "meta"
394+
case links = "links"
231395
}
232396

233397
public extension Entity {
@@ -247,6 +411,14 @@ public extension Entity {
247411
if Description.Relationships.self != NoRelationships.self {
248412
try container.encode(relationships, forKey: .relationships)
249413
}
414+
415+
if MetaType.self != NoMetadata.self {
416+
try container.encode(meta, forKey: .meta)
417+
}
418+
419+
if LinksType.self != NoLinks.self {
420+
try container.encode(links, forKey: .links)
421+
}
250422
}
251423

252424
public init(from decoder: Decoder) throws {
@@ -265,5 +437,9 @@ public extension Entity {
265437
attributes = try (NoAttributes() as? Description.Attributes) ?? container.decode(Description.Attributes.self, forKey: .attributes)
266438

267439
relationships = try (NoRelationships() as? Description.Relationships) ?? container.decode(Description.Relationships.self, forKey: .relationships)
440+
441+
meta = try (NoMetadata() as? MetaType) ?? container.decode(MetaType.self, forKey: .meta)
442+
443+
links = try (NoLinks() as? LinksType) ?? container.decode(LinksType.self, forKey: .links)
268444
}
269445
}

Tests/JSONAPITests/Attribute/Attribute+FunctorTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extension Attribute_FunctorTests {
6060
public typealias Relationships = NoRelationships
6161
}
6262

63-
typealias TestType = Entity<TestTypeDescription>
63+
typealias TestType = BasicEntity<TestTypeDescription>
6464

6565
enum DoubleToString: Transformer {
6666
public static func transform(_ from: Double) -> String {

Tests/JSONAPITests/Computed Properties/ComputedPropertiesTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,5 @@ extension ComputedPropertiesTests {
5757
}
5858
}
5959

60-
public typealias TestType = Entity<TestTypeDescription>
60+
public typealias TestType = BasicEntity<TestTypeDescription>
6161
}

Tests/JSONAPITests/Document/DocumentTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ extension DocumentTests {
970970
typealias Relationships = NoRelationships
971971
}
972972

973-
typealias Author = Entity<AuthorType>
973+
typealias Author = BasicEntity<AuthorType>
974974

975975
enum ArticleType: EntityDescription {
976976
static var type: String { return "articles" }
@@ -982,7 +982,7 @@ extension DocumentTests {
982982
}
983983
}
984984

985-
typealias Article = Entity<ArticleType>
985+
typealias Article = BasicEntity<ArticleType>
986986

987987
struct TestPageMetadata: JSONAPI.Meta {
988988
let total: Int

0 commit comments

Comments
 (0)