diff --git a/Sources/AtprotoTypes/LexiconTypes/Union.swift b/Sources/AtprotoTypes/LexiconTypes/Union.swift index 4b0573a..f3f8e9b 100644 --- a/Sources/AtprotoTypes/LexiconTypes/Union.swift +++ b/Sources/AtprotoTypes/LexiconTypes/Union.swift @@ -16,7 +16,7 @@ import Foundation ///Currently implemented as a union of records but could be any lexicon schema public protocol LexiconUnion: Codable, Sendable { static var members: [Atproto.Ref: any Atproto.Schema.Type] { get } - + init(object: any Codable) throws } @@ -28,7 +28,7 @@ extension LexiconUnion { public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: TypeHeader.self) let ref = try container.decode(Atproto.Ref.self, forKey: .type) - + let type = try Self.members[ref].tryUnwrap( LexionUnionError.unknownType(ref) ) diff --git a/Tests/AtprotoTypesTests/UnionTests.swift b/Tests/AtprotoTypesTests/UnionTests.swift index 30696a2..009da54 100644 --- a/Tests/AtprotoTypesTests/UnionTests.swift +++ b/Tests/AtprotoTypesTests/UnionTests.swift @@ -22,12 +22,18 @@ struct UnionTests { [SimpleRelationshipResult].self, from: Self.relationshipJsonString.utf8Data ) - print(result) + + let encoded = try JSONEncoder().encode(result) + + let _ = try JSONDecoder().decode( + [SimpleRelationshipResult].self, + from: encoded + ) } } -//taken from //c +//taken from https://docs.bsky.app/docs/api/app-bsky-graph-get-relationships enum SimpleRelationshipResult { case relationship(Relationships) case notFound(NotFoundActor) @@ -36,6 +42,8 @@ enum SimpleRelationshipResult { static var ref: Atproto.Ref { .init(string: "app.bsky.graph.defs#relationship") } + //for encoding + private(set) var ref: Atproto.Ref? = ref let did: Atproto.DID let blocking: Atproto.ATURI? let blockedBy: Atproto.ATURI? @@ -43,31 +51,49 @@ enum SimpleRelationshipResult { let followedBy: Atproto.ATURI? let blockedByList: Atproto.ATURI? let blockingbyList: Atproto.ATURI? + + enum CodingKeys: String, CodingKey { + case ref = "$type" + case did + case blocking + case blockedBy + case following + case followedBy + case blockedByList + case blockingbyList + } } struct NotFoundActor: Atproto.Schema { static var ref: Atproto.Ref { .init(string: "app.bsky.graph.defs#notFoundActor") } - + + //for encoding + private(set) var ref: Atproto.Ref? = ref public let actor: LexiconString.AtIdentifier var notFound: Bool = true public init(actor: LexiconString.AtIdentifier) { self.actor = actor } + + enum CodingKeys: String, CodingKey { + case ref = "$type" + case actor + case notFound + } } } extension SimpleRelationshipResult: LexiconUnion { - static var members: [Atproto.Ref : any Atproto.Schema.Type] { + static var members: [Atproto.Ref: any Atproto.Schema.Type] { [ Relationships.ref: Relationships.self, - NotFoundActor.ref: NotFoundActor.self + NotFoundActor.ref: NotFoundActor.self, ] } - init(object: any Codable) throws { if let relationships = object as? Relationships { self = .relationship(relationships) @@ -77,4 +103,14 @@ extension SimpleRelationshipResult: LexiconUnion { throw LexionUnionError.unknownObject } } + + func encode(to encoder: any Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case .relationship(let relationships): + try container.encode(relationships) + case .notFound(let notFound): + try container.encode(notFound) + } + } }