mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-03-30 11:18:38 -07:00
Moved Examples.swift into a Playground, added some initialization code required to create entities and documents in code.
This commit is contained in:
@@ -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<Description: EntityDescription> = Entity<Description, Id<String, Description>>
|
||||
|
||||
// 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<Person>
|
||||
let dogs: ToManyRelationship<Dog>
|
||||
let home: ToOneRelationship<House>
|
||||
}
|
||||
}
|
||||
|
||||
typealias Person = ExampleEntity<PersonDescription>
|
||||
|
||||
enum DogDescription: EntityDescription {
|
||||
|
||||
static var type: String { return "dogs" }
|
||||
|
||||
struct Attributes: JSONAPI.Attributes {
|
||||
let name: String
|
||||
}
|
||||
|
||||
struct Relationships: JSONAPI.Relationships {
|
||||
let owner: ToOneRelationship<Person?>
|
||||
}
|
||||
}
|
||||
|
||||
typealias Dog = ExampleEntity<DogDescription>
|
||||
|
||||
enum HouseDescription: EntityDescription {
|
||||
|
||||
static var type: String { return "houses" }
|
||||
|
||||
typealias Attributes = NoAttributes
|
||||
typealias Relationships = NoRelatives
|
||||
}
|
||||
|
||||
typealias House = ExampleEntity<HouseDescription>
|
||||
|
||||
// MARK: - Parse a response body with one Dog in it
|
||||
typealias SingleDogResponse = JSONAPIDocument<SingleResourceBody<Dog>, 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<ManyResourceBody<Person>, Include2<Dog, House>, 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]
|
||||
@@ -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<SingleResourceBody<Dog>, 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<ManyResourceBody<Person>, Include2<Dog, House>, 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]
|
||||
@@ -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<Description: EntityDescription> = Entity<Description, Id<String, Description>>
|
||||
|
||||
// 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<String>
|
||||
}
|
||||
|
||||
public struct Relationships: JSONAPI.Relationships {
|
||||
public let friends: ToManyRelationship<Person>
|
||||
public let dogs: ToManyRelationship<Dog>
|
||||
public let home: ToOneRelationship<House>
|
||||
}
|
||||
}
|
||||
|
||||
public typealias Person = ExampleEntity<PersonDescription>
|
||||
|
||||
public extension Entity where Description == PersonDescription, Identifier == Id<String, PersonDescription> {
|
||||
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<String>
|
||||
}
|
||||
|
||||
public struct Relationships: JSONAPI.Relationships {
|
||||
public let owner: ToOneRelationship<Person?>
|
||||
}
|
||||
}
|
||||
|
||||
public typealias Dog = ExampleEntity<DogDescription>
|
||||
|
||||
public extension Entity where Description == DogDescription, Identifier == Id<String, DogDescription> {
|
||||
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<HouseDescription>
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
@@ -32,6 +32,20 @@ public struct JSONAPIDocument<ResourceBody: JSONAPI.ResourceBody, Include: Inclu
|
||||
return (primary: body, included: includes)
|
||||
}
|
||||
}
|
||||
|
||||
public init(errors: [Error]) {
|
||||
body = .errors(errors)
|
||||
}
|
||||
|
||||
public init(body: ResourceBody, includes: Includes<Include>) {
|
||||
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 {
|
||||
|
||||
@@ -52,6 +52,12 @@ public struct Includes<I: IncludeDecoder>: Codable, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
extension Includes where I == NoIncludes {
|
||||
public init() {
|
||||
values = []
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Decoding
|
||||
|
||||
func decode<Entity: JSONAPI.EntityType>(_ type: Entity.Type, from container: SingleValueDecodingContainer) throws -> Result<Entity, EncodingError> {
|
||||
@@ -73,7 +79,9 @@ func decode<Entity: JSONAPI.EntityType>(_ type: Entity.Type, from container: Sin
|
||||
|
||||
public protocol _Include0: IncludeDecoder { }
|
||||
public struct Include0: _Include0 {
|
||||
|
||||
|
||||
public init() {}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,18 @@ public protocol ResourceBody: Codable, Equatable {
|
||||
|
||||
public struct SingleResourceBody<Entity: JSONAPI.EntityType>: ResourceBody {
|
||||
public let value: Entity?
|
||||
|
||||
public init(entity: Entity?) {
|
||||
self.value = entity
|
||||
}
|
||||
}
|
||||
|
||||
public struct ManyResourceBody<Entity: JSONAPI.EntityType>: ResourceBody {
|
||||
public let values: [Entity]
|
||||
|
||||
public init(entities: [Entity]) {
|
||||
values = entities
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Decodable
|
||||
|
||||
@@ -16,10 +16,10 @@ public struct TransformAttribute<RawValue: Codable, Transformer: JSONAPI.Transfo
|
||||
}
|
||||
}
|
||||
|
||||
public typealias Attribute<T: Codable> = TransformAttribute<T, IdentityTransformer<T>>
|
||||
|
||||
extension TransformAttribute: Equatable where Transformer.From: Equatable, Transformer.To: Equatable {}
|
||||
|
||||
public typealias Attribute<T: Codable> = TransformAttribute<T, IdentityTransformer<T>>
|
||||
|
||||
// MARK: - Codable
|
||||
extension TransformAttribute {
|
||||
public init(from decoder: Decoder) throws {
|
||||
|
||||
@@ -25,8 +25,8 @@ extension ToOneRelationship where Relatable.WrappedIdentifier == Relatable.Ident
|
||||
}
|
||||
|
||||
extension ToOneRelationship where Relatable.WrappedIdentifier == Optional<Relatable.Identifier> {
|
||||
public init(entity: Entity<Relatable.Description, Relatable.Identifier>) {
|
||||
id = entity.id
|
||||
public init(entity: Entity<Relatable.Description, Relatable.Identifier>?) {
|
||||
id = entity?.id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user