I did some more type wrangling to finally get the Id type to specialize on Entity rather than EntityDescription. The compiler gets into trouble depending on which of a few semantically identical routes are taken, but I finally stumbled upon the correct combination of protocols and extensions to get the job done. this was always the ideal outcome, but I was not sure the Swift compiler would allow it.

This commit is contained in:
Mathew Polzin
2018-11-28 21:13:07 -08:00
parent e67b9fc142
commit 163ac94c51
17 changed files with 110 additions and 75 deletions
@@ -40,10 +40,13 @@ let peopleFromData = peopleResponse.body.primaryData?.values
let dogsFromData = peopleResponse.body.includes?[Dog.self]
let housesFromData = peopleResponse.body.includes?[House.self]
print("-----")
print(peopleResponse)
print("-----")
// MARK: - Pass successfully parsed body to other parts of the code
if case let .data(bodyData) = peopleResponse.body {
print(bodyData)
print("first person's name: \(bodyData.primary.values[0][\.fullName])")
} else {
print("no body data")
+6 -6
View File
@@ -24,7 +24,7 @@ extension String: CreatableRawIdType {
}
// MARK: - Entity typealias for convenience
public typealias ExampleEntity<Description: EntityDescription> = Entity<Description, Id<String, Description>>
public typealias ExampleEntity<Description: EntityDescription> = Entity<Description, String>
// MARK: - A few resource objects (entities)
public enum PersonDescription: EntityDescription {
@@ -60,9 +60,9 @@ public enum PersonDescription: EntityDescription {
public typealias Person = ExampleEntity<PersonDescription>
public extension Entity where Description == PersonDescription, Identifier == Id<String, PersonDescription> {
public init(id: Person.Identifier? = nil,name: [String], favoriteColor: String, friends: [Person], dogs: [Dog], home: House) throws {
self = try Person(id: id ?? Person.Identifier(), 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 extension Entity where Description == PersonDescription, EntityRawIdType == String {
public init(id: Person.Id? = nil,name: [String], favoriteColor: String, friends: [Person], dogs: [Dog], home: House) throws {
self = try Person(id: id ?? Person.Id(), attributes: .init(name: .init(rawValue: name), favoriteColor: .init(rawValue: favoriteColor)), relationships: .init(friends: .init(entities: friends), dogs: .init(entities: dogs), home: .init(entity: home)))
}
}
@@ -89,12 +89,12 @@ public enum DogDescription: EntityDescription {
public typealias Dog = ExampleEntity<DogDescription>
public extension Entity where Description == DogDescription, Identifier == Id<String, DogDescription> {
public extension Entity where Description == DogDescription, EntityRawIdType == String {
public init(name: String, owner: Person?) throws {
self = try Dog(attributes: .init(name: .init(rawValue: name)), relationships: DogDescription.Relationships(owner: .init(entity: owner)))
}
public init(name: String, owner: Person.Identifier) throws {
public init(name: String, owner: Person.Id) throws {
self = try Dog(attributes: .init(name: .init(rawValue: name)), relationships: .init(owner: .init(id: owner)))
}
}