Rename EntityType generics and associated types to EntityDescription

This commit is contained in:
Mathew Polzin
2018-11-15 17:24:17 -08:00
parent ee364216bb
commit ea85593655
6 changed files with 50 additions and 62 deletions
+4 -4
View File
@@ -42,14 +42,14 @@ public struct Includes<I: IncludeDecoder>: Decodable {
// MARK: - Decoding
func decode<EntityType: JSONAPI.EntityDescription>(_ type: EntityType.Type, from container: SingleValueDecodingContainer) throws -> Result<Entity<EntityType>, EncodingError> {
let ret: Result<Entity<EntityType>, EncodingError>
func decode<EntityDescription: JSONAPI.EntityDescription>(_ type: EntityDescription.Type, from container: SingleValueDecodingContainer) throws -> Result<Entity<EntityDescription>, EncodingError> {
let ret: Result<Entity<EntityDescription>, EncodingError>
do {
ret = try .success(container.decode(Entity<EntityType>.self))
ret = try .success(container.decode(Entity<EntityDescription>.self))
} catch (let err as EncodingError) {
ret = .failure(err)
} catch (let err) {
ret = .failure(EncodingError.invalidValue(EntityType.self,
ret = .failure(EncodingError.invalidValue(EntityDescription.self,
.init(codingPath: container.codingPath,
debugDescription: err.localizedDescription,
underlyingError: err)))
+7 -9
View File
@@ -6,32 +6,30 @@
//
public protocol ResourceBody: Decodable {
typealias Single<EntityType: JSONAPI.EntityDescription> = SingleResourceBody<EntityType>
typealias Many<EntityType: JSONAPI.EntityDescription> = ManyResourceBody<EntityType>
}
public struct SingleResourceBody<EntityType: JSONAPI.EntityDescription>: ResourceBody {
public let value: Entity<EntityType>?
public struct SingleResourceBody<EntityDescription: JSONAPI.EntityDescription>: ResourceBody {
public let value: Entity<EntityDescription>?
}
public struct ManyResourceBody<EntityType: JSONAPI.EntityDescription>: ResourceBody {
public let values: [Entity<EntityType>]
public struct ManyResourceBody<EntityDescription: JSONAPI.EntityDescription>: ResourceBody {
public let values: [Entity<EntityDescription>]
}
// MARK: Decodable
extension SingleResourceBody {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
value = try container.decode(Entity<EntityType>.self)
value = try container.decode(Entity<EntityDescription>.self)
}
}
extension ManyResourceBody {
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var valueAggregator = [Entity<EntityType>]()
var valueAggregator = [Entity<EntityDescription>]()
while !container.isAtEnd {
valueAggregator.append(try container.decode(Entity<EntityType>.self))
valueAggregator.append(try container.decode(Entity<EntityDescription>.self))
}
values = valueAggregator
}
+33 -33
View File
@@ -55,11 +55,11 @@ public protocol UnidentifiedEntityDescription: EntityDescription where Identifie
/// encoded to or decoded from a JSON API
/// "Resource Object."
/// See https://jsonapi.org/format/#document-resource-objects
public struct Entity<EntityType: JSONAPI.EntityDescription>: Codable, Equatable {
public typealias Identifier = EntityType.Identifier
public struct Entity<EntityDescription: JSONAPI.EntityDescription>: Codable, Equatable {
public typealias Identifier = EntityDescription.Identifier
/// The JSON API compliant "type" of this `Entity`.
public static var type: String { return EntityType.type }
public static var type: String { return EntityDescription.type }
/// The `Entity`'s Id. This can be of type `Unidentified` if
/// the entity is being created clientside and the
@@ -68,12 +68,12 @@ public struct Entity<EntityType: JSONAPI.EntityDescription>: Codable, Equatable
public let id: Identifier
/// The JSON API compliant attributes of this `Entity`.
public let attributes: EntityType.Attributes
public let attributes: EntityDescription.Attributes
/// The JSON API compliant relationships of this `Entity`.
public let relationships: EntityType.Relationships
public let relationships: EntityDescription.Relationships
public init(id: EntityType.Identifier, attributes: EntityType.Attributes, relationships: EntityType.Relationships) {
public init(id: EntityDescription.Identifier, attributes: EntityDescription.Attributes, relationships: EntityDescription.Relationships) {
self.id = id
self.attributes = attributes
self.relationships = relationships
@@ -81,52 +81,52 @@ public struct Entity<EntityType: JSONAPI.EntityDescription>: Codable, Equatable
}
// MARK: Convenience initializers
extension Entity where EntityType.Identifier: CreatableIdType {
public init(attributes: EntityType.Attributes, relationships: EntityType.Relationships) {
self.id = EntityType.Identifier()
extension Entity where EntityDescription.Identifier: CreatableIdType {
public init(attributes: EntityDescription.Attributes, relationships: EntityDescription.Relationships) {
self.id = EntityDescription.Identifier()
self.attributes = attributes
self.relationships = relationships
}
}
extension Entity where EntityType.Attributes == NoAttributes {
public init(id: EntityType.Identifier, relationships: EntityType.Relationships) {
extension Entity where EntityDescription.Attributes == NoAttributes {
public init(id: EntityDescription.Identifier, relationships: EntityDescription.Relationships) {
self.init(id: id, attributes: NoAttributes(), relationships: relationships)
}
}
extension Entity where EntityType.Attributes == NoAttributes, EntityType.Identifier: CreatableIdType {
public init(relationships: EntityType.Relationships) {
extension Entity where EntityDescription.Attributes == NoAttributes, EntityDescription.Identifier: CreatableIdType {
public init(relationships: EntityDescription.Relationships) {
self.init(attributes: NoAttributes(), relationships: relationships)
}
}
extension Entity where EntityType.Relationships == NoRelatives {
public init(id: EntityType.Identifier, attributes: EntityType.Attributes) {
extension Entity where EntityDescription.Relationships == NoRelatives {
public init(id: EntityDescription.Identifier, attributes: EntityDescription.Attributes) {
self.init(id: id, attributes: attributes, relationships: NoRelatives())
}
}
extension Entity where EntityType.Relationships == NoRelatives, EntityType.Identifier: CreatableIdType {
public init(attributes: EntityType.Attributes) {
extension Entity where EntityDescription.Relationships == NoRelatives, EntityDescription.Identifier: CreatableIdType {
public init(attributes: EntityDescription.Attributes) {
self.init(attributes: attributes, relationships: NoRelatives())
}
}
extension Entity where EntityType.Attributes == NoAttributes, EntityType.Relationships == NoRelatives {
public init(id: EntityType.Identifier) {
extension Entity where EntityDescription.Attributes == NoAttributes, EntityDescription.Relationships == NoRelatives {
public init(id: EntityDescription.Identifier) {
self.init(id: id, attributes: NoAttributes(), relationships: NoRelatives())
}
}
extension Entity where EntityType.Attributes == NoAttributes, EntityType.Relationships == NoRelatives, EntityType.Identifier: CreatableIdType {
extension Entity where EntityDescription.Attributes == NoAttributes, EntityDescription.Relationships == NoRelatives, EntityDescription.Identifier: CreatableIdType {
public init() {
self.init(attributes: NoAttributes(), relationships: NoRelatives())
}
}
// MARK: Pointer for Relationships use.
public extension Entity where EntityType.Identifier: IdType {
public extension Entity where EntityDescription.Identifier: IdType {
/// Get a pointer to this entity that can be used as a
/// relationship to another entity.
public var pointer: ToOneRelationship<Entity> {
@@ -139,21 +139,21 @@ public extension Entity {
/// Access the attribute at the given keypath. This just
/// allows you to write `entity[\.propertyName]` instead
/// of `entity.relationships.propertyName`.
subscript<T, TFRM: Transformer>(_ path: KeyPath<EntityType.Attributes, TransformAttribute<T, TFRM>>) -> TFRM.To {
subscript<T, TFRM: Transformer>(_ path: KeyPath<EntityDescription.Attributes, TransformAttribute<T, TFRM>>) -> TFRM.To {
return attributes[keyPath: path].value
}
/// Access the attribute at the given keypath. This just
/// allows you to write `entity[\.propertyName]` instead
/// of `entity.relationships.propertyName`.
subscript<T, TFRM: Transformer>(_ path: KeyPath<EntityType.Attributes, TransformAttribute<T, TFRM>?>) -> TFRM.To? {
subscript<T, TFRM: Transformer>(_ path: KeyPath<EntityDescription.Attributes, TransformAttribute<T, TFRM>?>) -> TFRM.To? {
return attributes[keyPath: path]?.value
}
/// Access the attribute at the given keypath. This just
/// allows you to write `entity[\.propertyName]` instead
/// of `entity.relationships.propertyName`.
subscript<T, TFRM: Transformer, U>(_ path: KeyPath<EntityType.Attributes, TransformAttribute<T, TFRM>?>) -> U? where TFRM.To == U? {
subscript<T, TFRM: Transformer, U>(_ path: KeyPath<EntityDescription.Attributes, TransformAttribute<T, TFRM>?>) -> U? where TFRM.To == U? {
return attributes[keyPath: path].flatMap { $0.value }
}
}
@@ -163,14 +163,14 @@ public extension Entity {
/// Access to an Id of a `ToOneRelationship`.
/// This allows you to write `entity ~> \.other` instead
/// of `entity.relationships.other.id`.
public static func ~><OtherEntity: OptionalRelatable>(entity: Entity, path: KeyPath<EntityType.Relationships, ToOneRelationship<OtherEntity>>) -> OtherEntity.Identifier {
public static func ~><OtherEntity: OptionalRelatable>(entity: Entity, path: KeyPath<EntityDescription.Relationships, ToOneRelationship<OtherEntity>>) -> OtherEntity.Identifier {
return entity.relationships[keyPath: path].id
}
/// Access to all Ids of a `ToManyRelationship`.
/// This allows you to write `entity ~> \.others` instead
/// of `entity.relationships.others.ids`.
public static func ~><OtherEntity: Relatable>(entity: Entity, path: KeyPath<EntityType.Relationships, ToManyRelationship<OtherEntity>>) -> [OtherEntity.Identifier] {
public static func ~><OtherEntity: Relatable>(entity: Entity, path: KeyPath<EntityDescription.Relationships, ToManyRelationship<OtherEntity>>) -> [OtherEntity.Identifier] {
return entity.relationships[keyPath: path].ids
}
}
@@ -191,15 +191,15 @@ public extension Entity {
try container.encode(Entity.type, forKey: .type)
if EntityType.Identifier.self != Unidentified.self {
if EntityDescription.Identifier.self != Unidentified.self {
try container.encode(id, forKey: .id)
}
if EntityType.Attributes.self != NoAttributes.self {
if EntityDescription.Attributes.self != NoAttributes.self {
try container.encode(attributes, forKey: .attributes)
}
if EntityType.Relationships.self != NoRelatives.self {
if EntityDescription.Relationships.self != NoRelatives.self {
try container.encode(relationships, forKey: .relationships)
}
}
@@ -211,13 +211,13 @@ public extension Entity {
let type = try container.decode(String.self, forKey: .type)
guard Entity.type == type else {
throw JSONAPIEncodingError.typeMismatch(expected: EntityType.type, found: type)
throw JSONAPIEncodingError.typeMismatch(expected: EntityDescription.type, found: type)
}
id = try (Unidentified() as? EntityType.Identifier) ?? container.decode(EntityType.Identifier.self, forKey: .id)
id = try (Unidentified() as? EntityDescription.Identifier) ?? container.decode(EntityDescription.Identifier.self, forKey: .id)
attributes = try (NoAttributes() as? EntityType.Attributes) ?? container.decode(EntityType.Attributes.self, forKey: .attributes)
attributes = try (NoAttributes() as? EntityDescription.Attributes) ?? container.decode(EntityDescription.Attributes.self, forKey: .attributes)
relationships = try (NoRelatives() as? EntityType.Relationships) ?? container.decode(EntityType.Relationships.self, forKey: .relationships)
relationships = try (NoRelatives() as? EntityDescription.Relationships) ?? container.decode(EntityDescription.Relationships.self, forKey: .relationships)
}
}
+2 -2
View File
@@ -31,7 +31,7 @@ public struct Unidentified: Identifier, CustomStringConvertible {
}
public protocol IdType: Identifier, CustomStringConvertible {
associatedtype EntityType: JSONAPI.EntityDescription
associatedtype EntityDescription: JSONAPI.EntityDescription
associatedtype RawType: RawIdType
var rawValue: RawType { get }
@@ -47,7 +47,7 @@ public protocol CreatableIdType: IdType {
/// An Entity ID. These IDs can be encoded to or decoded from
/// JSON API IDs.
public struct Id<RawType: RawIdType, EntityType: JSONAPI.EntityDescription>: IdType {
public struct Id<RawType: RawIdType, EntityDescription: JSONAPI.EntityDescription>: IdType {
public let rawValue: RawType
public init(rawValue: RawType) {
+2 -12
View File
@@ -5,16 +5,6 @@
// Created by Mathew Polzin on 8/31/18.
//
/// An Entity relationship that can be encoded to or decoded from
/// a JSON API "Resource Linkage."
/// You should use the `ToOneRelationship` and `ToManyRelationship`
/// concrete types.
/// See https://jsonapi.org/format/#document-resource-object-linkage
//public protocol Relationship: Equatable, Encodable, CustomStringConvertible {
// associatedtype EntityType: JSONAPI.EntityDescription where EntityType.Identifier: IdType
// var ids: [EntityType.Identifier] { get }
//}
/// An Entity relationship that can be encoded to or decoded from
/// a JSON API "Resource Linkage."
/// See https://jsonapi.org/format/#document-resource-object-linkage
@@ -72,8 +62,8 @@ public protocol OptionalRelatable {
/// has an EntityDescription
public protocol Relatable: OptionalRelatable {}
extension Entity: Relatable, OptionalRelatable where EntityType.Identifier: IdType {
public typealias Description = EntityType
extension Entity: Relatable, OptionalRelatable where EntityDescription.Identifier: IdType {
public typealias Description = EntityDescription
}
extension Optional: OptionalRelatable where Wrapped: Relatable {