From 3327a93df5ddda5aec6ab5286d68c3848dbc662d Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Sun, 18 Nov 2018 17:47:26 -0800 Subject: [PATCH] Moved Examples.swift into a Playground, added some initialization code required to create entities and documents in code. --- Examples.swift | 76 ------------------ JSONAPI.playground/Contents.swift | 34 +++++++++ JSONAPI.playground/Sources/Entities.swift | 85 +++++++++++++++++++++ JSONAPI.playground/contents.xcplayground | 4 + Sources/JSONAPI/Document/Document.swift | 14 ++++ Sources/JSONAPI/Document/Includes.swift | 10 ++- Sources/JSONAPI/Document/ResourceBody.swift | 8 ++ Sources/JSONAPI/Resource/Attribute.swift | 4 +- Sources/JSONAPI/Resource/Relationship.swift | 4 +- 9 files changed, 158 insertions(+), 81 deletions(-) delete mode 100644 Examples.swift create mode 100644 JSONAPI.playground/Contents.swift create mode 100644 JSONAPI.playground/Sources/Entities.swift create mode 100644 JSONAPI.playground/contents.xcplayground diff --git a/Examples.swift b/Examples.swift deleted file mode 100644 index 9a398de..0000000 --- a/Examples.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// Examples.swift -// JSONAPI -// -// Created by Mathew Polzin on 11/12/18. -// - -import Foundation -import JSONAPI - -/******* - -Please enjoy these examples, but allow me the forced casting and the lack of error checking for the sake of brevity. - -********/ - -typealias ExampleEntity = Entity> - -// MARK: - A few resource objects (entities) -enum PersonDescription: EntityDescription { - - static var type: String { return "people" } - - struct Attributes: JSONAPI.Attributes { - let name: [String] - let favoriteColor: String - } - - struct Relationships: JSONAPI.Relationships { - let friends: ToManyRelationship - let dogs: ToManyRelationship - let home: ToOneRelationship - } -} - -typealias Person = ExampleEntity - -enum DogDescription: EntityDescription { - - static var type: String { return "dogs" } - - struct Attributes: JSONAPI.Attributes { - let name: String - } - - struct Relationships: JSONAPI.Relationships { - let owner: ToOneRelationship - } -} - -typealias Dog = ExampleEntity - -enum HouseDescription: EntityDescription { - - static var type: String { return "houses" } - - typealias Attributes = NoAttributes - typealias Relationships = NoRelatives -} - -typealias House = ExampleEntity - -// MARK: - Parse a response body with one Dog in it -typealias SingleDogResponse = JSONAPIDocument, NoIncludes, BasicJSONAPIError> - -let dummyData = "".data(using: .utf8)! -let dogResponse = try! JSONDecoder().decode(SingleDogResponse.self, from: dummyData) -let dog = dogResponse.body.data?.primary.value - -// MARK: Parse a response body with multiple people in it and dogs and houses included -typealias BatchPeopleResponse = JSONAPIDocument, Include2, BasicJSONAPIError> - -let peopleResponse = try! JSONDecoder().decode(BatchPeopleResponse.self, from: dummyData) -let people = peopleResponse.body.data?.primary.values -let dogs = peopleResponse.body.data?.included[Dog.self] -let houses = peopleResponse.body.data?.included[House.self] diff --git a/JSONAPI.playground/Contents.swift b/JSONAPI.playground/Contents.swift new file mode 100644 index 0000000..9323a13 --- /dev/null +++ b/JSONAPI.playground/Contents.swift @@ -0,0 +1,34 @@ + +import Foundation +import JSONAPI + +/******* + +Please enjoy these examples, but allow me the forced casting and the lack of error checking for the sake of brevity. + +********/ + +// MARK: - Create a request or response body with one Dog in it +let dogFromCode = try! Dog(name: "Buddy", owner: nil) + +typealias SingleDogDocument = JSONAPIDocument, NoIncludes, BasicJSONAPIError> +let singleDogDocument = SingleDogDocument(body: SingleResourceBody(entity: dogFromCode)) + +let singleDogData = try! JSONEncoder().encode(singleDogDocument) + +// MARK: - Parse a request or response body with one Dog in it +let dogResponse = try! JSONDecoder().decode(SingleDogDocument.self, from: singleDogData) +let dogFromData = dogResponse.body.data?.primary.value + +// MARK: - Create a request or response with multiple people and dogs and houses included +//let people + +//typealias BatchPeopleDocument = JSONAPIDocument, Include2, BasicJSONAPIError> + + +// MARK: - Parse a request or response body with multiple people in it and dogs and houses included + +//let peopleResponse = try! JSONDecoder().decode(BatchPeopleResponse.self, from: dummyData) +//let people = peopleResponse.body.data?.primary.values +//let dogs = peopleResponse.body.data?.included[Dog.self] +//let houses = peopleResponse.body.data?.included[House.self] diff --git a/JSONAPI.playground/Sources/Entities.swift b/JSONAPI.playground/Sources/Entities.swift new file mode 100644 index 0000000..78f2cca --- /dev/null +++ b/JSONAPI.playground/Sources/Entities.swift @@ -0,0 +1,85 @@ +// +// Examples.swift +// JSONAPI +// +// Created by Mathew Polzin on 11/12/18. +// + +import Foundation +import JSONAPI + +/******* + +Please enjoy these examples, but allow me the forced casting and the lack of error checking for the sake of brevity. + +********/ + +// MARK: - String as CreatableRawIdType +var GlobalStringId: Int = 0 +extension String: CreatableRawIdType { + public static func unique() -> String { + GlobalStringId += 1 + return String(GlobalStringId) + } +} + +// MARK: - Entity typealias for convenience +public typealias ExampleEntity = Entity> + +// MARK: - A few resource objects (entities) +public enum PersonDescription: EntityDescription { + + public static var type: String { return "people" } + + public struct Attributes: JSONAPI.Attributes { + public let name: Attribute<[String]> + public let favoriteColor: Attribute + } + + public struct Relationships: JSONAPI.Relationships { + public let friends: ToManyRelationship + public let dogs: ToManyRelationship + public let home: ToOneRelationship + } +} + +public typealias Person = ExampleEntity + +public extension Entity where Description == PersonDescription, Identifier == Id { + public init(name: [String], favoriteColor: String, friends: [Person], dogs: [Dog], home: House) throws { + self = try Person(attributes: .init(name: .init(rawValue: name), favoriteColor: .init(rawValue: favoriteColor)), relationships: .init(friends: .init(entities: friends), dogs: .init(entities: dogs), home: .init(entity: home))) + } +} + +public enum DogDescription: EntityDescription { + + public static var type: String { return "dogs" } + + public struct Attributes: JSONAPI.Attributes { + public let name: Attribute + } + + public struct Relationships: JSONAPI.Relationships { + public let owner: ToOneRelationship + } +} + +public typealias Dog = ExampleEntity + +public extension Entity where Description == DogDescription, Identifier == Id { + public init(name: String, owner: Person?) throws { + self = try Dog(attributes: .init(name: .init(rawValue: name)), relationships: DogDescription.Relationships(owner: .init(entity: owner))) + } +} + +public enum HouseDescription: EntityDescription { + + public static var type: String { return "houses" } + + public typealias Attributes = NoAttributes + public typealias Relationships = NoRelatives +} + +public typealias House = ExampleEntity + + diff --git a/JSONAPI.playground/contents.xcplayground b/JSONAPI.playground/contents.xcplayground new file mode 100644 index 0000000..a93d484 --- /dev/null +++ b/JSONAPI.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Sources/JSONAPI/Document/Document.swift b/Sources/JSONAPI/Document/Document.swift index 4c5f873..62eaa68 100644 --- a/Sources/JSONAPI/Document/Document.swift +++ b/Sources/JSONAPI/Document/Document.swift @@ -32,6 +32,20 @@ public struct JSONAPIDocument) { + self.body = .data(primary: body, included: includes) + } +} + +extension JSONAPIDocument where Include == NoIncludes { + public init(body: ResourceBody) { + self.body = .data(primary: body, included: .none) + } } extension JSONAPIDocument: Codable { diff --git a/Sources/JSONAPI/Document/Includes.swift b/Sources/JSONAPI/Document/Includes.swift index 5ccaac7..dd9492e 100644 --- a/Sources/JSONAPI/Document/Includes.swift +++ b/Sources/JSONAPI/Document/Includes.swift @@ -52,6 +52,12 @@ public struct Includes: Codable, Equatable { } } +extension Includes where I == NoIncludes { + public init() { + values = [] + } +} + // MARK: - Decoding func decode(_ type: Entity.Type, from container: SingleValueDecodingContainer) throws -> Result { @@ -73,7 +79,9 @@ func decode(_ type: Entity.Type, from container: Sin public protocol _Include0: IncludeDecoder { } public struct Include0: _Include0 { - + + public init() {} + public init(from decoder: Decoder) throws { } diff --git a/Sources/JSONAPI/Document/ResourceBody.swift b/Sources/JSONAPI/Document/ResourceBody.swift index 62bfec0..746cfb4 100644 --- a/Sources/JSONAPI/Document/ResourceBody.swift +++ b/Sources/JSONAPI/Document/ResourceBody.swift @@ -10,10 +10,18 @@ public protocol ResourceBody: Codable, Equatable { public struct SingleResourceBody: ResourceBody { public let value: Entity? + + public init(entity: Entity?) { + self.value = entity + } } public struct ManyResourceBody: ResourceBody { public let values: [Entity] + + public init(entities: [Entity]) { + values = entities + } } // MARK: Decodable diff --git a/Sources/JSONAPI/Resource/Attribute.swift b/Sources/JSONAPI/Resource/Attribute.swift index 1acba4e..7671d7c 100644 --- a/Sources/JSONAPI/Resource/Attribute.swift +++ b/Sources/JSONAPI/Resource/Attribute.swift @@ -16,10 +16,10 @@ public struct TransformAttribute = TransformAttribute> - extension TransformAttribute: Equatable where Transformer.From: Equatable, Transformer.To: Equatable {} +public typealias Attribute = TransformAttribute> + // MARK: - Codable extension TransformAttribute { public init(from decoder: Decoder) throws { diff --git a/Sources/JSONAPI/Resource/Relationship.swift b/Sources/JSONAPI/Resource/Relationship.swift index e114479..776f0c7 100644 --- a/Sources/JSONAPI/Resource/Relationship.swift +++ b/Sources/JSONAPI/Resource/Relationship.swift @@ -25,8 +25,8 @@ extension ToOneRelationship where Relatable.WrappedIdentifier == Relatable.Ident } extension ToOneRelationship where Relatable.WrappedIdentifier == Optional { - public init(entity: Entity) { - id = entity.id + public init(entity: Entity?) { + id = entity?.id } }