Skip to content

Commit

Permalink
Conditional Codable for Relations (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
KazaiMazai authored Aug 15, 2024
1 parent a820c3e commit 4c26623
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Sources/SwiftletModel/Model/EntityModelProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

public protocol EntityModelProtocol {
// swiftlint:disable:next type_name
associatedtype ID: Hashable, Codable, LosslessStringConvertible
associatedtype ID: Hashable, LosslessStringConvertible

var id: ID { get }

Expand Down
24 changes: 14 additions & 10 deletions Sources/SwiftletModel/Relationship/Relation+Codable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

// MARK: - Codable

extension Relation: Codable where Entity: Codable {
extension Relation: Codable where Entity: Codable, Entity.ID: Codable {
public func encode(to encoder: any Encoder) throws {
switch encoder.relationEncodingStrategy {
case .plain:
Expand Down Expand Up @@ -42,7 +42,7 @@ extension Relation: Codable where Entity: Codable {

// MARK: - Codable Explicitly

extension Relation where Entity: Codable {
extension Relation where Entity: Codable, Entity.ID: Codable {
enum RelationCodingKeys: String, CodingKey {
case id = "id"
case entity = "object"
Expand Down Expand Up @@ -99,7 +99,7 @@ extension Relation where Entity: Codable {

// MARK: - Codable Exactly

extension Relation where Entity: Codable {
extension Relation where Entity: Codable, Entity.ID: Codable {
enum RelationExplicitCodingKeys: String, CodingKey {
case id = "id"
case entity = "object"
Expand Down Expand Up @@ -169,21 +169,25 @@ extension Relation where Entity: Codable {

// MARK: - Codable Flattaned

extension Relation where Entity: Codable {
extension Relation.ID: Codable where Entity.ID: Codable {

}

extension Relation where Entity: Codable, Entity.ID: Codable {
// swiftlint:disable:next type_name
struct ID<T: EntityModelProtocol>: Codable {
let id: T.ID
struct ID {
let id: Entity.ID
}

func encodePlainContainer(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch state {
case .id(let value):
try container.encode(value.map { ID<Entity>(id: $0) })
try container.encode(value.map { ID(id: $0) })
case .entity(let value, _):
try container.encode(value)
case .ids(let value, _):
try container.encode(value.map { ID<Entity>(id: $0) })
try container.encode(value.map { ID(id: $0) })
case .entities(let value, _, _):
try container.encode(value)
case .none:
Expand All @@ -200,15 +204,15 @@ extension Relation where Entity: Codable {
return Relation(state: .entity(entity: value, fragment: false))
}

if let value = try? container.decode(ID<Entity>?.self) {
if let value = try? container.decode(ID?.self) {
return Relation(state: .id(id: value.id))
}

if let value = try? container.decode([Entity].self) {
return Relation(state: .entities(entities: value, slice: false, fragment: false))
}

if let value = try? container.decode([ID<Entity>].self) {
if let value = try? container.decode([ID].self) {
return Relation(state: .ids(ids: value.map { $0.id }, slice: false))
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftletModel/Relationship/Relation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ extension Relation {

// MARK: - Codable

extension Relation.State: Codable where T: Codable { }
extension Relation.State: Codable where T: Codable, T.ID: Codable { }

// MARK: - Sendable

Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftletModel/Relationship/Relationship.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public extension Relationship where Directionality == Relations.OneWay,

// MARK: - Codable

extension Relationship: Codable where Value: Codable, Entity: Codable {
extension Relationship: Codable where Value: Codable, Entity: Codable, Entity.ID: Codable {

public func encode(to encoder: Encoder) throws {
try relation.encode(to: encoder)
Expand Down

0 comments on commit 4c26623

Please sign in to comment.