lots of comparison code, a few small breaking changes

This commit is contained in:
Mathew Polzin
2019-11-05 19:03:51 -08:00
parent 1a15ab6f9d
commit f7bfa91ccc
21 changed files with 1431 additions and 15 deletions
+14 -7
View File
@@ -20,7 +20,16 @@ public protocol EncodableJSONAPIDocument: Equatable, Encodable {
typealias Body = Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body
/// The Body of the Document. This body is either one or more errors
/// with links and metadata attempted to parse but not guaranteed or
/// it is a successful data struct containing all the primary and
/// included resources, the metadata, and the links that this
/// document type specifies.
var body: Body { get }
/// The JSON API Spec calls this the JSON:API Object. It contains version
/// and metadata information about the API itself.
var apiDescription: APIDescription { get }
}
/// A `JSONAPIDocument` supports encoding and decoding of a JSON:API
@@ -30,6 +39,7 @@ public protocol JSONAPIDocument: EncodableJSONAPIDocument, Decodable where Prima
/// A JSON API Document represents the entire body
/// of a JSON API request or the entire body of
/// a JSON API response.
///
/// Note that this type uses Camel case. If your
/// API uses snake case, you will want to use
/// a conversion such as the one offerred by the
@@ -37,15 +47,10 @@ public protocol JSONAPIDocument: EncodableJSONAPIDocument, Decodable where Prima
public struct Document<PrimaryResourceBody: JSONAPI.EncodableResourceBody, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links, IncludeType: JSONAPI.Include, APIDescription: APIDescriptionType, Error: JSONAPIError>: EncodableJSONAPIDocument {
public typealias Include = IncludeType
/// The JSON API Spec calls this the JSON:API Object. It contains version
/// and metadata information about the API itself.
// See `EncodableJSONAPIDocument` for documentation.
public let apiDescription: APIDescription
/// The Body of the Document. This body is either one or more errors
/// with links and metadata attempted to parse but not guaranteed or
/// it is a successful data struct containing all the primary and
/// included resources, the metadata, and the links that this
/// document type specifies.
// See `EncodableJSONAPIDocument` for documentation.
public let body: Body
public enum Body: Equatable {
@@ -423,6 +428,7 @@ extension Document {
@dynamicMemberLookup
public struct ErrorDocument: EncodableJSONAPIDocument {
public var body: Document.Body { return document.body }
public var apiDescription: APIDescription { return document.apiDescription }
private let document: Document
@@ -450,6 +456,7 @@ extension Document {
@dynamicMemberLookup
public struct SuccessDocument: EncodableJSONAPIDocument {
public var body: Document.Body { return document.body }
public var apiDescription: APIDescription { return document.apiDescription }
private let document: Document
+3 -3
View File
@@ -14,15 +14,15 @@ public typealias Include = EncodableJSONPoly
///
/// If you have
///
/// `let includes: Includes<Include2<Thing1, Thing2>> = ...`
/// let includes: Includes<Include2<Thing1, Thing2>> = ...
///
/// then you can access all `Thing1` included resources with
///
/// `let includedThings = includes[Thing1.self]`
/// let includedThings = includes[Thing1.self]
public struct Includes<I: Include>: Encodable, Equatable {
public static var none: Includes { return .init(values: []) }
let values: [I]
public let values: [I]
public init(values: [I]) {
self.values = values
@@ -6,7 +6,7 @@
//
/// Most of the JSON:API Spec defined Error fields.
public struct BasicJSONAPIErrorPayload<IdType: Codable & Equatable>: Codable, Equatable, ErrorDictType {
public struct BasicJSONAPIErrorPayload<IdType: Codable & Equatable>: Codable, Equatable, ErrorDictType, CustomStringConvertible {
/// a unique identifier for this particular occurrence of the problem
public let id: IdType?
// public let links: Links? // we skip this for now to avoid adding complexity to using this basic type.
@@ -61,6 +61,10 @@ public struct BasicJSONAPIErrorPayload<IdType: Codable & Equatable>: Codable, Eq
].compactMap { $0 }
return Dictionary(uniqueKeysWithValues: keysAndValues)
}
public var description: String {
return definedFields.map { "\($0.key): \($0.value)" }.sorted().joined(separator: ", ")
}
}
/// `BasicJSONAPIError` optionally decodes many possible fields
@@ -8,7 +8,7 @@
/// `GenericJSONAPIError` can be used to specify whatever error
/// payload you expect to need to parse in responses and handle any
/// other payload structure as `.unknownError`.
public enum GenericJSONAPIError<ErrorPayload: Codable & Equatable>: JSONAPIError {
public enum GenericJSONAPIError<ErrorPayload: Codable & Equatable>: JSONAPIError, CustomStringConvertible {
case unknownError
case error(ErrorPayload)
@@ -35,6 +35,15 @@ public enum GenericJSONAPIError<ErrorPayload: Codable & Equatable>: JSONAPIError
public static var unknown: Self {
return .unknownError
}
public var description: String {
switch self {
case .unknownError:
return "unknown error"
case .error(let payload):
return String(describing: payload)
}
}
}
public extension GenericJSONAPIError {
@@ -102,6 +102,12 @@ extension ResourceObjectProxy {
public protocol ResourceObjectType: ResourceObjectProxy, PrimaryResource where Description: ResourceObjectDescription {
associatedtype Meta: JSONAPI.Meta
associatedtype Links: JSONAPI.Links
/// Any additional metadata packaged with the entity.
var meta: Meta { get }
/// Links related to the entity.
var links: Links { get }
}
public protocol IdentifiableResourceObjectType: ResourceObjectType, Relatable where EntityRawIdType: JSONAPI.RawIdType {}