Compare commits

...

5 Commits

Author SHA1 Message Date
Mathew Polzin fcc1796731 Expose Entity properties on EntityType protocol. 2018-11-27 18:58:48 -08:00
Mathew Polzin 921bcef05d Ids are now Hashable 2018-11-27 18:39:57 -08:00
Mathew Polzin 661ff6eca5 A little renaming and easier access to important types under the JSONAPIDocument protocol 2018-11-27 18:20:01 -08:00
Mathew Polzin e36180c9b9 Make properties of Body.Data public 2018-11-27 18:05:02 -08:00
Mathew Polzin abee0c4d0e Add body variable to JSONAPIDocument protocol 2018-11-27 17:55:56 -08:00
5 changed files with 50 additions and 23 deletions
@@ -47,3 +47,13 @@ if case let .data(bodyData) = peopleResponse.body {
} else {
print("no body data")
}
// MARK: - Work in the abstract
func process<T: JSONAPIDocument>(document: T) {
guard case let .data(body) = document.body else {
return
}
let x: T.BodyData = body
}
process(document: peopleResponse)
+23 -18
View File
@@ -6,11 +6,16 @@
//
public protocol JSONAPIDocument: Codable, Equatable {
associatedtype ResourceBody: JSONAPI.ResourceBody
associatedtype PrimaryResourceBody: JSONAPI.ResourceBody
associatedtype MetaType: JSONAPI.Meta
associatedtype LinksType: JSONAPI.Links
associatedtype IncludeType: JSONAPI.Include
associatedtype Error: JSONAPIError
typealias Body = Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, Error>.Body
typealias BodyData = Body.Data
var body: Body { get }
}
/// A JSON API Document represents the entire body
@@ -20,7 +25,7 @@ public protocol JSONAPIDocument: Codable, Equatable {
/// API uses snake case, you will want to use
/// a conversion such as the one offerred by the
/// Foundation JSONEncoder/Decoder: `KeyDecodingStrategy`
public struct Document<ResourceBody: JSONAPI.ResourceBody, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links, IncludeType: JSONAPI.Include, Error: JSONAPIError>: JSONAPIDocument {
public struct Document<PrimaryResourceBody: JSONAPI.ResourceBody, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links, IncludeType: JSONAPI.Include, Error: JSONAPIError>: JSONAPIDocument {
public typealias Include = IncludeType
public let body: Body
@@ -31,10 +36,10 @@ public struct Document<ResourceBody: JSONAPI.ResourceBody, MetaType: JSONAPI.Met
case data(Data)
public struct Data: Equatable {
let primary: ResourceBody
let includes: Includes<Include>
let meta: MetaType
let links: LinksType
public let primary: PrimaryResourceBody
public let includes: Includes<Include>
public let meta: MetaType
public let links: LinksType
}
public var isError: Bool {
@@ -47,7 +52,7 @@ public struct Document<ResourceBody: JSONAPI.ResourceBody, MetaType: JSONAPI.Met
return errors
}
public var primaryData: ResourceBody? {
public var primaryData: PrimaryResourceBody? {
guard case let .data(data) = self else { return nil }
return data.primary
}
@@ -84,49 +89,49 @@ public struct Document<ResourceBody: JSONAPI.ResourceBody, MetaType: JSONAPI.Met
body = .errors(errors, meta: meta, links: links)
}
public init(body: ResourceBody, includes: Includes<Include>, meta: MetaType, links: LinksType) {
public init(body: PrimaryResourceBody, includes: Includes<Include>, meta: MetaType, links: LinksType) {
self.body = .data(.init(primary: body, includes: includes, meta: meta, links: links))
}
}
extension Document where IncludeType == NoIncludes {
public init(body: ResourceBody, meta: MetaType, links: LinksType) {
public init(body: PrimaryResourceBody, meta: MetaType, links: LinksType) {
self.body = .data(.init(primary: body, includes: .none, meta: meta, links: links))
}
}
extension Document where MetaType == NoMetadata {
public init(body: ResourceBody, includes: Includes<Include>, links: LinksType) {
public init(body: PrimaryResourceBody, includes: Includes<Include>, links: LinksType) {
self.body = .data(.init(primary: body, includes: includes, meta: .none, links: links))
}
}
extension Document where LinksType == NoLinks {
public init(body: ResourceBody, includes: Includes<Include>, meta: MetaType) {
public init(body: PrimaryResourceBody, includes: Includes<Include>, meta: MetaType) {
self.body = .data(.init(primary: body, includes: includes, meta: meta, links: .none))
}
}
extension Document where IncludeType == NoIncludes, LinksType == NoLinks {
public init(body: ResourceBody, meta: MetaType) {
public init(body: PrimaryResourceBody, meta: MetaType) {
self.body = .data(.init(primary: body, includes: .none, meta: meta, links: .none))
}
}
extension Document where IncludeType == NoIncludes, MetaType == NoMetadata {
public init(body: ResourceBody, links: LinksType) {
public init(body: PrimaryResourceBody, links: LinksType) {
self.body = .data(.init(primary: body, includes: .none, meta: .none, links: links))
}
}
extension Document where MetaType == NoMetadata, LinksType == NoLinks {
public init(body: ResourceBody, includes: Includes<Include>) {
public init(body: PrimaryResourceBody, includes: Includes<Include>) {
self.body = .data(.init(primary: body, includes: includes, meta: .none, links: .none))
}
}
extension Document where IncludeType == NoIncludes, MetaType == NoMetadata, LinksType == NoLinks {
public init(body: ResourceBody) {
public init(body: PrimaryResourceBody) {
self.body = .data(.init(primary: body, includes: .none, meta: .none, links: .none))
}
}
@@ -174,11 +179,11 @@ extension Document {
return
}
let data: ResourceBody
if let noData = NoResourceBody() as? ResourceBody {
let data: PrimaryResourceBody
if let noData = NoResourceBody() as? PrimaryResourceBody {
data = noData
} else {
data = try container.decode(ResourceBody.self, forKey: .data)
data = try container.decode(PrimaryResourceBody.self, forKey: .data)
}
let maybeIncludes = try container.decodeIfPresent(Includes<Include>.self, forKey: .included)
+3 -3
View File
@@ -1,5 +1,5 @@
//
// ResourceBody.swift
// PrimaryResourceBody.swift
// JSONAPI
//
// Created by Mathew Polzin on 11/10/18.
@@ -80,12 +80,12 @@ extension ManyResourceBody {
extension SingleResourceBody: CustomStringConvertible {
public var description: String {
return "ResourceBody(\(String(describing: value)))"
return "PrimaryResourceBody(\(String(describing: value)))"
}
}
extension ManyResourceBody: CustomStringConvertible {
public var description: String {
return "ResourceBody(\(String(describing: values)))"
return "PrimaryResourceBody(\(String(describing: values)))"
}
}
+12
View File
@@ -43,6 +43,18 @@ public protocol EntityType: PrimaryResource {
typealias Attributes = Description.Attributes
typealias Relationships = Description.Relationships
/// The `Entity`'s Id. This can be of type `Unidentified` if
/// the entity is being created clientside and the
/// server is being asked to create a unique Id. Otherwise,
/// this should be of a type conforming to `IdType`.
var id: Identifier { get }
/// The JSON API compliant attributes of this `Entity`.
var attributes: Attributes { get }
/// The JSON API compliant relationships of this `Entity`.
var relationships: Relationships { get }
}
/// An `Entity` is a single model type that can be
+2 -2
View File
@@ -8,7 +8,7 @@
/// Any type that you would like to be encoded to and
/// decoded from JSON API ids should conform to this
/// protocol. Conformance for `String` is given.
public protocol RawIdType: Codable, Equatable {}
public protocol RawIdType: Codable, Hashable {}
/// If you would like to be able to create new
/// Entities with Ids backed by a RawIdType then
@@ -32,7 +32,7 @@ public struct Unidentified<EntityDescription: JSONAPI.EntityDescription>: Identi
public var description: String { return "Id(Unidentified)" }
}
public protocol IdType: Identifier, CustomStringConvertible {
public protocol IdType: Identifier, Hashable, CustomStringConvertible {
associatedtype RawType: RawIdType
var rawValue: RawType { get }