├── Tools ├── Empty.swift ├── .gitignore ├── Package.swift └── Package.resolved ├── .gitmodules ├── Sources ├── ATProto │ └── Export.swift ├── ATProtoXRPC │ ├── Export.swift │ ├── XRPC │ │ ├── SessionProvider.swift │ │ ├── XRPCClient.swift │ │ ├── XRPCRequest.swift │ │ ├── XRPCRequests.swift │ │ ├── XRPCRequestParameterConvertible.swift │ │ └── XRPCSessionClient.swift │ ├── Entities │ │ ├── XRPCErrorResponse.swift │ │ ├── UnionCodable.swift │ │ ├── XRPCError.swift │ │ ├── Session.swift │ │ ├── SafeURL.swift │ │ ├── Union.swift.gyb │ │ ├── Indirect.swift │ │ └── Union.generated.swift │ └── Extensions │ │ ├── URLSessionExtensions.swift │ │ └── JSONDecoderExtensions.swift ├── ATProtoMacro │ └── LexiconDefID.swift ├── ATProtoMacroPlugin │ ├── ATProtoMacroPlugin.swift │ └── LexiconDefIDMacro.swift └── ATProtoCore │ └── Entities │ ├── LexiconDefinitionID.swift │ ├── NSID.swift │ └── ATURI.swift ├── .gitignore ├── Scripts └── run-gyb.sh ├── Makefile ├── .github └── workflows │ ├── ci.yml │ └── update-lexicon.yml ├── LICENSE.md ├── Tests ├── ATProtoXRPCTests │ ├── Extensions │ │ └── JSONDecoderExtensionsTests.swift │ └── Entities │ │ ├── UnionCodableTests.swift │ │ └── IndirectTests.swift ├── ATProtoCoreTests │ └── Entities │ │ ├── LexiconDefinitionIDTests.swift │ │ ├── NSIDTests.swift │ │ └── ATURITests.swift └── ATProtoMacroPluginTests │ └── LexiconDefIDMacroTests.swift ├── Package.resolved ├── README.md └── Package.swift /Tools/Empty.swift: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "atproto"] 2 | path = atproto 3 | url = https://github.com/bluesky-social/atproto.git 4 | -------------------------------------------------------------------------------- /Sources/ATProto/Export.swift: -------------------------------------------------------------------------------- 1 | @_exported import ATProtoAPI 2 | @_exported import ATProtoXRPC 3 | @_exported import ATProtoCore 4 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Export.swift: -------------------------------------------------------------------------------- 1 | #if canImport(FoundationNetworking) 2 | @_exported import FoundationNetworking 3 | #endif 4 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/XRPC/SessionProvider.swift: -------------------------------------------------------------------------------- 1 | public protocol SessionProvider { 2 | var session: Session? { get nonmutating set } 3 | } 4 | -------------------------------------------------------------------------------- /Tools/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .build 3 | /Packages 4 | /*.xcodeproj 5 | xcuserdata/ 6 | DerivedData/ 7 | .swiftpm/config/registries.json 8 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 9 | .netrc 10 | 11 | # gyb 12 | /gyb 13 | -------------------------------------------------------------------------------- /Sources/ATProtoMacro/LexiconDefID.swift: -------------------------------------------------------------------------------- 1 | import ATProtoCore 2 | 3 | @freestanding(expression) 4 | public macro LexiconDefID(_ stringLiteral: String) -> LexiconDefinitionID = #externalMacro( 5 | module: "ATProtoMacroPlugin", 6 | type: "LexiconDefIDMacro" 7 | ) 8 | -------------------------------------------------------------------------------- /Sources/ATProtoMacroPlugin/ATProtoMacroPlugin.swift: -------------------------------------------------------------------------------- 1 | import SwiftCompilerPlugin 2 | import SwiftSyntaxMacros 3 | 4 | @main 5 | struct ATProtoMacroPlugin: CompilerPlugin { 6 | let providingMacros: [any Macro.Type] = [ 7 | LexiconDefIDMacro.self, 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/XRPCErrorResponse.swift: -------------------------------------------------------------------------------- 1 | public struct XRPCErrorResponse: Hashable, Decodable { 2 | public let error: XRPCError 3 | public let message: String? 4 | 5 | public init(error: XRPCError, message: String?) { 6 | self.error = error 7 | self.message = message 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/UnionCodable.swift: -------------------------------------------------------------------------------- 1 | import ATProtoCore 2 | 3 | public typealias UnionCodable = UnionEncodable & UnionDecodable 4 | 5 | public protocol UnionEncodable: Encodable { 6 | static var typeValue: LexiconDefinitionID { get } 7 | } 8 | 9 | public protocol UnionDecodable: Decodable { 10 | static var typeValue: LexiconDefinitionID { get } 11 | } 12 | -------------------------------------------------------------------------------- /Tools/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.9 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "Tools", 7 | platforms: [ 8 | .macOS(.v13) 9 | ], 10 | dependencies: [ 11 | .package(url: "https://github.com/andooown/lexicon-gen.git", revision: "0.0.7"), 12 | ], 13 | targets: [ 14 | .target(name: "Tools", path: "") 15 | ] 16 | ) 17 | -------------------------------------------------------------------------------- /Scripts/run-gyb.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | if [ ! -e "gyb" ]; then 4 | mkdir "gyb" 5 | curl "https://raw.githubusercontent.com/apple/swift/master/utils/gyb.py" -o "gyb/gyb.py" 6 | curl "https://raw.githubusercontent.com/apple/swift/master/utils/gyb" -o "gyb/gyb" 7 | chmod +x gyb/gyb 8 | fi 9 | 10 | ROOT_DIR=$(pwd) 11 | 12 | ./gyb/gyb "$ROOT_DIR/Sources/ATProtoXRPC/Entities/Union.swift.gyb" -o "$ROOT_DIR/Sources/ATProtoXRPC/Entities/Union.generated.swift" --line-directive "" 13 | 14 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/XRPCError.swift: -------------------------------------------------------------------------------- 1 | public enum XRPCError: Hashable, Decodable { 2 | public enum XRPCErrorCode: String { 3 | case expiredToken = "ExpiredToken" 4 | } 5 | 6 | case errorCode(XRPCErrorCode) 7 | case unknown(String) 8 | 9 | public init(from decoder: Decoder) throws { 10 | let container = try decoder.singleValueContainer() 11 | let value = try container.decode(String.self) 12 | self = XRPCErrorCode(rawValue: value).map(XRPCError.errorCode) ?? .unknown(value) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/XRPC/XRPCClient.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public protocol XRPCClient { 4 | func send(_ request: R) async throws -> R.Output where R: XRPCRequest 5 | } 6 | 7 | public extension XRPCClient { 8 | func send(_ request: R) async throws where R: XRPCRequest, R.Output == EmptyOutput { 9 | _ = try await send(request) 10 | } 11 | } 12 | 13 | public struct XRPCClientMock: XRPCClient { 14 | public init() {} 15 | 16 | public func send(_ request: R) async throws -> R.Output where R: XRPCRequest { 17 | throw NSError(domain: "Unimplemented", code: -1) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TOOLS_PACKAGE_PATH := Tools 2 | TOOLS_PATH := ${TOOLS_PACKAGE_PATH}/.build/release 3 | 4 | 5 | .PHONY: gyb 6 | gyb: 7 | @Scripts/run-gyb.sh 8 | 9 | .PHONY: build-tools 10 | build-tools: 11 | @swift build -c release --package-path ${TOOLS_PACKAGE_PATH} --product lexicon-gen 12 | 13 | .PHONY: lexicon-gen 14 | lexicon-gen: 15 | @${TOOLS_PATH}/lexicon-gen \ 16 | --source-directory atproto/lexicons \ 17 | --output-file Sources/ATProtoAPI/Lexicons.generated.swift 18 | 19 | .PHONY: build 20 | build: 21 | @swift build 22 | 23 | .PHONY: test 24 | test: 25 | @swift test 26 | 27 | .PHONY: clean 28 | clean: 29 | @rm -rf \ 30 | ./.build 31 | 32 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/Session.swift: -------------------------------------------------------------------------------- 1 | public struct AccessToken: Codable { 2 | public let rawValue: String 3 | 4 | public init(rawValue: String) { 5 | self.rawValue = rawValue 6 | } 7 | } 8 | 9 | public struct RefreshToken: Codable { 10 | public let rawValue: String 11 | 12 | public init(rawValue: String) { 13 | self.rawValue = rawValue 14 | } 15 | } 16 | 17 | public struct Session: Codable { 18 | public let accessJWT: AccessToken 19 | public let refreshJWT: RefreshToken 20 | 21 | public init(accessJWT: AccessToken, refreshJWT: RefreshToken) { 22 | self.accessJWT = accessJWT 23 | self.refreshJWT = refreshJWT 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/SafeURL.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct SafeURL: Codable, Hashable { 4 | public let rawValue: String 5 | public let url: URL? 6 | 7 | public init(string: String) { 8 | self.rawValue = string 9 | self.url = URL(string: string) 10 | } 11 | 12 | public init(from decoder: Decoder) throws { 13 | let container = try decoder.singleValueContainer() 14 | 15 | let rawValue = try container.decode(String.self) 16 | self.rawValue = rawValue 17 | 18 | self.url = URL(string: rawValue) 19 | } 20 | 21 | public func encode(to encoder: Encoder) throws { 22 | var container = encoder.singleValueContainer() 23 | try container.encode(rawValue) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/XRPC/XRPCRequest.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct EmptyInput: Encodable { 4 | public init() {} 5 | } 6 | 7 | public struct EmptyOutput: Decodable { 8 | public init() {} 9 | } 10 | 11 | public enum XRPCRequestType { 12 | case query 13 | case procedure 14 | } 15 | 16 | public protocol XRPCRequest { 17 | associatedtype Parameters: XRPCRequestParametersConvertible = EmptyParameters 18 | associatedtype Input: Encodable = EmptyInput 19 | associatedtype Output: Decodable = EmptyOutput 20 | 21 | var type: XRPCRequestType { get } 22 | var requestIdentifier: String { get } 23 | var parameters: Parameters { get } 24 | var input: Input? { get } 25 | } 26 | 27 | public extension XRPCRequest { 28 | var input: Input? { nil } 29 | } 30 | 31 | public extension XRPCRequest where Parameters == EmptyParameters { 32 | var parameters: Parameters { 33 | EmptyParameters() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Extensions/URLSessionExtensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if canImport(FoundationNetworking) 4 | extension URLSession { 5 | func data(for request: URLRequest) async throws -> (Data, URLResponse) { 6 | try await withCheckedThrowingContinuation { continuation in 7 | dataTask(with: request) { data, response, error in 8 | if let error = error { 9 | continuation.resume(throwing: error) 10 | return 11 | } 12 | 13 | guard let data = data, let response = response else { 14 | continuation.resume(throwing: NSError(domain: "unknown", code: -1)) 15 | return 16 | } 17 | 18 | continuation.resume(returning: (data, response)) 19 | } 20 | .resume() 21 | } 22 | } 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /Tools/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "lexicon-gen", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/andooown/lexicon-gen.git", 7 | "state" : { 8 | "branch" : "0.0.7", 9 | "revision" : "fe53757fb5ef62dbce8c234c7e8f765b1105af55" 10 | } 11 | }, 12 | { 13 | "identity" : "swift-argument-parser", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/apple/swift-argument-parser.git", 16 | "state" : { 17 | "revision" : "9f39744e025c7d377987f30b03770805dcb0bcd1", 18 | "version" : "1.1.4" 19 | } 20 | }, 21 | { 22 | "identity" : "swift-syntax", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/apple/swift-syntax.git", 25 | "state" : { 26 | "branch" : "509.0.0", 27 | "revision" : "74203046135342e4a4a627476dd6caf8b28fe11b" 28 | } 29 | } 30 | ], 31 | "version" : 2 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Build (${{ matrix.os }}, Swift ${{ matrix.swift-version }}) 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest, macos-13] 16 | swift-version: ["5.9"] 17 | steps: 18 | - uses: swift-actions/setup-swift@v1 19 | with: 20 | swift-version: ${{ matrix.swift-version }} 21 | - uses: actions/checkout@v3 22 | - name: Build 23 | run: make build 24 | 25 | test: 26 | name: Test (${{ matrix.os }}, Swift ${{ matrix.swift-version }}) 27 | runs-on: ${{ matrix.os }} 28 | strategy: 29 | matrix: 30 | os: [ubuntu-latest, macos-13] 31 | swift-version: ["5.9"] 32 | steps: 33 | - uses: swift-actions/setup-swift@v1 34 | with: 35 | swift-version: ${{ matrix.swift-version }} 36 | - uses: actions/checkout@v3 37 | - name: Test 38 | run: make test 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 andooown 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Tests/ATProtoXRPCTests/Extensions/JSONDecoderExtensionsTests.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | 4 | @testable import ATProtoXRPC 5 | 6 | final class JSONDecoderExtensionsTests: XCTestCase { 7 | func testDateDecode() throws { 8 | // https://atproto.com/specs/lexicon#datetime 9 | 10 | let cases = [ 11 | // preferred 12 | "1985-04-12T23:20:50.123Z", 13 | "1985-04-12T23:20:50.123456Z", 14 | "1985-04-12T23:20:50.120Z", 15 | "1985-04-12T23:20:50.120000Z", 16 | // supported 17 | "1985-04-12T23:20:50.1235678912345Z", 18 | "1985-04-12T23:20:50.100Z", 19 | "1985-04-12T23:20:50Z", 20 | "1985-04-12T23:20:50.0Z", 21 | "1985-04-12T23:20:50.123+00:00", 22 | "1985-04-12T23:20:50.123-07:00", 23 | 24 | // Possible cases that was in actual response from bsky.social 25 | "2023-08-18T06:45:26.132861", 26 | ] 27 | for c in cases { 28 | let data = ("\"" + c + "\"").data(using: .utf8)! 29 | XCTAssertNoThrow(try JSONDecoder.forXRPC.decode(Date.self, from: data)) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/ATProtoCoreTests/Entities/LexiconDefinitionIDTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | @testable import ATProtoCore 4 | 5 | final class LexiconDefinitionIDTests: XCTestCase { 6 | func testInitWithString() throws { 7 | let id1 = try LexiconDefinitionID(string: "com.example.foo#bar") 8 | XCTAssertEqual(id1.nsid, try NSID(string: "com.example.foo")) 9 | XCTAssertEqual(id1.fragment, "bar") 10 | XCTAssertEqual(id1.isMain, false) 11 | XCTAssertEqual(id1.toString(), "com.example.foo#bar") 12 | 13 | let id2 = try LexiconDefinitionID(string: "com.example.foo") 14 | XCTAssertEqual(id2.nsid, try NSID(string: "com.example.foo")) 15 | XCTAssertEqual(id2.fragment, nil) 16 | XCTAssertEqual(id2.isMain, true) 17 | XCTAssertEqual(id2.toString(), "com.example.foo#main") 18 | 19 | let id3 = try LexiconDefinitionID(string: "com.example.foo#main") 20 | XCTAssertEqual(id3.nsid, try NSID(string: "com.example.foo")) 21 | XCTAssertEqual(id3.fragment, nil) 22 | XCTAssertEqual(id3.isMain, true) 23 | XCTAssertEqual(id3.toString(), "com.example.foo#main") 24 | 25 | XCTAssertNotEqual(id1, id2) 26 | XCTAssertEqual(id2, id3) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/ATProtoMacroPlugin/LexiconDefIDMacro.swift: -------------------------------------------------------------------------------- 1 | import ATProtoCore 2 | import Foundation 3 | import SwiftSyntax 4 | import SwiftSyntaxMacros 5 | 6 | public enum LexiconDefIDMacro: ExpressionMacro { 7 | private enum MacroError: Error, CustomStringConvertible { 8 | case noStaticStringLiteral 9 | case malformedID(ExprSyntax) 10 | 11 | var description: String { 12 | switch self { 13 | case .noStaticStringLiteral: 14 | return "#LexiconDefID requires a static string literal" 15 | 16 | case .malformedID(let value): 17 | return "Malformed ID string: \(value)" 18 | } 19 | } 20 | } 21 | 22 | public static func expansion( 23 | of node: some FreestandingMacroExpansionSyntax, 24 | in context: some MacroExpansionContext 25 | ) throws -> ExprSyntax { 26 | guard let argument = node.argumentList.first?.expression, 27 | let segments = argument.as(StringLiteralExprSyntax.self)?.segments, 28 | segments.count == 1, 29 | case .stringSegment(let literalSegment)? = segments.first 30 | else { 31 | throw MacroError.noStaticStringLiteral 32 | } 33 | 34 | do { 35 | _ = try LexiconDefinitionID(string: literalSegment.content.text) 36 | } catch { 37 | throw MacroError.malformedID(argument) 38 | } 39 | 40 | return "try! LexiconDefinitionID(string: \(argument))" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "swift-case-paths", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/pointfreeco/swift-case-paths", 7 | "state" : { 8 | "revision" : "5da6989aae464f324eef5c5b52bdb7974725ab81", 9 | "version" : "1.0.0" 10 | } 11 | }, 12 | { 13 | "identity" : "swift-collections", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/apple/swift-collections.git", 16 | "state" : { 17 | "revision" : "a902f1823a7ff3c9ab2fba0f992396b948eda307", 18 | "version" : "1.0.5" 19 | } 20 | }, 21 | { 22 | "identity" : "swift-parsing", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/pointfreeco/swift-parsing.git", 25 | "state" : { 26 | "revision" : "a0e7d73f462c1c38c59dc40a3969ac40cea42950", 27 | "version" : "0.13.0" 28 | } 29 | }, 30 | { 31 | "identity" : "swift-syntax", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/apple/swift-syntax.git", 34 | "state" : { 35 | "revision" : "74203046135342e4a4a627476dd6caf8b28fe11b", 36 | "version" : "509.0.0" 37 | } 38 | }, 39 | { 40 | "identity" : "xctest-dynamic-overlay", 41 | "kind" : "remoteSourceControl", 42 | "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", 43 | "state" : { 44 | "revision" : "23cbf2294e350076ea4dbd7d5d047c1e76b03631", 45 | "version" : "1.0.2" 46 | } 47 | } 48 | ], 49 | "version" : 2 50 | } 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swift-atproto ![CI](https://github.com/andooown/swift-atproto/actions/workflows/ci.yml/badge.svg?branch=main) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fandooown%2Fswift-atproto%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/andooown/swift-atproto) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fandooown%2Fswift-atproto%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/andooown/swift-atproto) 2 | 3 | Swift package that provides a AT Protocol libraries. 4 | 5 | 🚧 This package is under development. 🚧 6 | 7 | ## Requirements 8 | - Swift 5.9 or later 9 | 10 | ## Overview 11 | swift-atproto includes the following libraries. 12 | 13 | ### ATProto 14 | `ATProto` is a umbrella library that includes all libraries in swift-atproto. 15 | 16 | ### ATProtoAPI 17 | `ATProtoAPI` includes auto-generated Swift code from lexicon files in [bluesky-social/atproto](https://github.com/bluesky-social/atproto). Code is generated by [andooown/lexicon-gen](https://github.com/andooown/lexicon-gen). 18 | 19 | ### ATProtoXRPC 20 | `ATProtoXRPC` is a library that provides XRPC client and fundamental types for XRPC. 21 | 22 | ### ATProtoCore 23 | `ATProtoCore` is a library that provides fundamental types for AT Protocol. 24 | 25 | ### ATProtoMacro 26 | `ATProtoMacro` is a library that provides some Swift Macros for AT Protocol. 27 | 28 | - [`#LexiconDefID(_:)`](https://github.com/andooown/swift-atproto/blob/main/Sources/ATProtoMacro/LexiconDefID.swift) 29 | 30 | ## Author 31 | - [andooown](https://github.com/andooown) 32 | 33 | ## License 34 | swift-atproto is available under the MIT license. See the LICENSE file for more info. 35 | -------------------------------------------------------------------------------- /Tests/ATProtoMacroPluginTests/LexiconDefIDMacroTests.swift: -------------------------------------------------------------------------------- 1 | import SwiftSyntaxMacros 2 | import SwiftSyntaxMacrosTestSupport 3 | import XCTest 4 | 5 | @testable import ATProtoMacroPlugin 6 | 7 | final class LexiconDefIDMacroTests: XCTestCase { 8 | private let macros = ["LexiconDefID": LexiconDefIDMacro.self] 9 | 10 | func testExpansion() { 11 | assertMacroExpansion( 12 | """ 13 | let valid = #LexiconDefID("com.example.foo") 14 | """, 15 | expandedSource: """ 16 | let valid = try! LexiconDefinitionID(string: "com.example.foo") 17 | """, 18 | macros: macros 19 | ) 20 | } 21 | 22 | func testExpansionWithNonStaticString() { 23 | assertMacroExpansion( 24 | #""" 25 | let invalid = #LexiconDefID("com.example.\(name)") 26 | """#, 27 | expandedSource: #""" 28 | let invalid = #LexiconDefID("com.example.\(name)") 29 | """#, 30 | diagnostics: [ 31 | DiagnosticSpec(message: #"#LexiconDefID requires a static string literal"#, line: 1, column: 15, severity: .error), 32 | ], 33 | macros: macros 34 | ) 35 | } 36 | 37 | func testExpansionWithInvalidID() { 38 | assertMacroExpansion( 39 | """ 40 | let invalid = #LexiconDefID("invalid.") 41 | """, 42 | expandedSource: """ 43 | let invalid = #LexiconDefID("invalid.") 44 | """, 45 | diagnostics: [ 46 | DiagnosticSpec(message: #"Malformed ID string: "invalid.""#, line: 1, column: 15, severity: .error), 47 | ], 48 | macros: macros 49 | ) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/XRPC/XRPCRequests.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public enum XRPCRequests { 4 | public struct CreateSession: XRPCRequest { 5 | public struct Input: Encodable { 6 | public let identifier: String 7 | public let password: String 8 | 9 | public init( 10 | identifier: String, 11 | password: String 12 | ) { 13 | self.identifier = identifier 14 | self.password = password 15 | } 16 | } 17 | 18 | public typealias Output = SessionResponse 19 | 20 | public init( 21 | input: Input 22 | ) { 23 | self.input = input 24 | } 25 | 26 | public let type = XRPCRequestType.procedure 27 | public let requestIdentifier = "com.atproto.server.createSession" 28 | public let input: Input? 29 | } 30 | 31 | public struct RefreshSession: XRPCRequest { 32 | public typealias Output = SessionResponse 33 | 34 | public init() {} 35 | 36 | public let type: XRPCRequestType = .procedure 37 | public let requestIdentifier = "com.atproto.server.refreshSession" 38 | } 39 | 40 | public struct SessionResponse: Decodable { 41 | public enum CodingKeys: String, CodingKey { 42 | case accessJWT = "accessJwt" 43 | case refreshJWT = "refreshJwt" 44 | case handle 45 | case did 46 | } 47 | 48 | public let accessJWT: String 49 | public let refreshJWT: String 50 | public let handle: String 51 | public let did: String 52 | 53 | public func toSession() -> Session { 54 | Session( 55 | accessJWT: AccessToken(rawValue: accessJWT), 56 | refreshJWT: RefreshToken(rawValue: refreshJWT) 57 | ) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Tests/ATProtoXRPCTests/Entities/UnionCodableTests.swift: -------------------------------------------------------------------------------- 1 | import ATProtoCore 2 | import ATProtoMacro 3 | import XCTest 4 | 5 | @testable import ATProtoXRPC 6 | 7 | final class UnionCodableTests: XCTestCase { 8 | struct TestStructA: UnionCodable, Equatable { 9 | static let typeValue = #LexiconDefID("com.example.testStructA") 10 | 11 | let val: Int 12 | } 13 | 14 | struct TestStructB: UnionCodable, Equatable { 15 | static let typeValue = #LexiconDefID("com.example.testStructB#frag") 16 | 17 | let val: String 18 | } 19 | 20 | typealias Union = Union2 21 | 22 | func testEncode() throws { 23 | let encoder = JSONEncoder() 24 | 25 | let dataA = try encoder.encode(Union.type0(.init(val: 0))) 26 | let jsonA = try XCTUnwrap(JSONSerialization.jsonObject(with: dataA) as? [String: Any]) 27 | XCTAssertEqual(jsonA.count, 2) 28 | XCTAssertEqual(jsonA["$type"] as? String, "com.example.testStructA") 29 | XCTAssertEqual(jsonA["val"] as? Int, 0) 30 | 31 | let dataB = try encoder.encode(Union.type1(.init(val: "VALUE"))) 32 | let jsonB = try XCTUnwrap(JSONSerialization.jsonObject(with: dataB) as? [String: Any]) 33 | XCTAssertEqual(jsonB.count, 2) 34 | XCTAssertEqual(jsonB["$type"] as? String, "com.example.testStructB#frag") 35 | XCTAssertEqual(jsonB["val"] as? String, "VALUE") 36 | } 37 | 38 | func testDecode() throws { 39 | let decoder = JSONDecoder() 40 | 41 | XCTAssertEqual( 42 | try decoder.decode(Union.self, from: #"{"$type":"com.example.testStructA","val":0}"#.data(using: .utf8)!), 43 | Union.type0(.init(val: 0)) 44 | ) 45 | XCTAssertEqual( 46 | try decoder.decode(Union.self, from: #"{"$type":"com.example.testStructA#main","val":0}"#.data(using: .utf8)!), 47 | Union.type0(.init(val: 0)) 48 | ) 49 | 50 | XCTAssertEqual( 51 | try decoder.decode(Union.self, from: #"{"$type":"com.example.testStructB#frag","val":"VALUE"}"#.data(using: .utf8)!), 52 | Union.type1(.init(val: "VALUE")) 53 | ) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sources/ATProtoCore/Entities/LexiconDefinitionID.swift: -------------------------------------------------------------------------------- 1 | public struct LexiconDefinitionID: Hashable { 2 | public var nsid: NSID 3 | public var fragment: String? 4 | 5 | public init(nsid: NSID, fragment: String?) { 6 | self.nsid = nsid 7 | self.fragment = fragment == "main" ? nil : fragment 8 | } 9 | 10 | public init(string: String) throws { 11 | let parts = string.split(separator: "#").map(String.init) 12 | 13 | switch parts.count { 14 | case 1: 15 | self.init( 16 | nsid: try NSID(string: parts[0]), 17 | fragment: nil 18 | ) 19 | 20 | case 2: 21 | self.init( 22 | nsid: try NSID(string: parts[0]), 23 | fragment: parts[1] 24 | ) 25 | 26 | default: 27 | throw InvalidLexiconDefinitionIDError.invalidPartsCount 28 | } 29 | } 30 | 31 | public var isMain: Bool { 32 | fragment == nil 33 | } 34 | 35 | public func toString(fullStyle: Bool = true) -> String { 36 | if let fragment = fragment { 37 | return nsid.toString() + "#" + fragment 38 | } else { 39 | return nsid.toString() + (fullStyle ? "#main" : "") 40 | } 41 | } 42 | } 43 | 44 | private extension LexiconDefinitionID { 45 | enum InvalidLexiconDefinitionIDError: Error { 46 | case invalidPartsCount 47 | } 48 | } 49 | 50 | extension LexiconDefinitionID: Encodable { 51 | public func encode(to encoder: Encoder) throws { 52 | var container = encoder.singleValueContainer() 53 | try container.encode(self.toString(fullStyle: false)) 54 | } 55 | } 56 | 57 | extension LexiconDefinitionID: Decodable { 58 | public init(from decoder: Decoder) throws { 59 | let container = try decoder.singleValueContainer() 60 | let string = try container.decode(String.self) 61 | 62 | do { 63 | self = try LexiconDefinitionID(string: string) 64 | } catch { 65 | throw DecodingError.dataCorruptedError( 66 | in: container, 67 | debugDescription: "Invalid ID string: \(string). Got error: \(error)" 68 | ) 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/XRPC/XRPCRequestParameterConvertible.swift: -------------------------------------------------------------------------------- 1 | import ATProtoCore 2 | import Foundation 3 | 4 | public protocol XRPCRequestParameterConvertible { 5 | func toQueryItems(name: String) -> [URLQueryItem] 6 | } 7 | 8 | public protocol XRPCRequestParametersConvertible { 9 | var queryItems: [URLQueryItem] { get } 10 | } 11 | 12 | public struct EmptyParameters: XRPCRequestParametersConvertible { 13 | public init() {} 14 | 15 | public let queryItems: [URLQueryItem] = [] 16 | } 17 | 18 | extension String: XRPCRequestParameterConvertible { 19 | public func toQueryItems(name: String) -> [URLQueryItem] { 20 | [URLQueryItem(name: name, value: self)] 21 | } 22 | } 23 | 24 | extension Int: XRPCRequestParameterConvertible { 25 | public func toQueryItems(name: String) -> [URLQueryItem] { 26 | [URLQueryItem(name: name, value: "\(self)")] 27 | } 28 | } 29 | 30 | extension Bool: XRPCRequestParameterConvertible { 31 | public func toQueryItems(name: String) -> [URLQueryItem] { 32 | [URLQueryItem(name: name, value: self ? "true" : "false")] 33 | } 34 | } 35 | 36 | extension Date: XRPCRequestParameterConvertible { 37 | public func toQueryItems(name: String) -> [URLQueryItem] { 38 | let formatter = ISO8601DateFormatter() 39 | formatter.formatOptions.insert(.withFractionalSeconds) 40 | return [URLQueryItem(name: name, value: formatter.string(from: self))] 41 | } 42 | } 43 | 44 | extension ATURI: XRPCRequestParameterConvertible { 45 | public func toQueryItems(name: String) -> [URLQueryItem] { 46 | [URLQueryItem(name: name, value: toString())] 47 | } 48 | } 49 | 50 | extension SafeURL: XRPCRequestParameterConvertible { 51 | public func toQueryItems(name: String) -> [URLQueryItem] { 52 | [URLQueryItem(name: name, value: rawValue)] 53 | } 54 | } 55 | 56 | extension Optional: XRPCRequestParameterConvertible where Wrapped: XRPCRequestParameterConvertible { 57 | public func toQueryItems(name: String) -> [URLQueryItem] { 58 | switch self { 59 | case .some(let wrapped): 60 | return wrapped.toQueryItems(name: name) 61 | 62 | case .none: 63 | return [] 64 | } 65 | } 66 | } 67 | 68 | extension Array: XRPCRequestParameterConvertible where Element: XRPCRequestParameterConvertible { 69 | public func toQueryItems(name: String) -> [URLQueryItem] { 70 | flatMap { 71 | $0.toQueryItems(name: name) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Tests/ATProtoXRPCTests/Entities/IndirectTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | @testable import ATProtoXRPC 4 | 5 | final class IndirectTests: XCTestCase { 6 | func testEncoding() throws { 7 | let encoder = JSONEncoder() 8 | encoder.dateEncodingStrategy = .iso8601 9 | 10 | XCTAssertEqual( 11 | String(data: try encoder.encode(Indirect.wrapped("TEXT")), encoding: .utf8), 12 | #""TEXT""# 13 | ) 14 | XCTAssertEqual( 15 | String(data: try encoder.encode(Indirect.wrapped(URL(string: "https://example.com/")!)), encoding: .utf8), 16 | #""https:\/\/example.com\/""# 17 | ) 18 | XCTAssertEqual( 19 | String(data: try encoder.encode(Indirect.wrapped(Date(timeIntervalSince1970: 0))), encoding: .utf8), 20 | #""1970-01-01T00:00:00Z""# 21 | ) 22 | 23 | XCTAssertEqual( 24 | String(data: try encoder.encode(Object(value: 0)), encoding: .utf8), 25 | #"{"value":0}"# 26 | ) 27 | XCTAssertEqual( 28 | String(data: try encoder.encode(Object(value: nil)), encoding: .utf8), 29 | #"{}"# 30 | ) 31 | } 32 | 33 | func testDecoding() throws { 34 | let decoder = JSONDecoder() 35 | 36 | XCTAssertEqual( 37 | try decoder.decode(String.self, from: #""TEXT""#.data(using: .utf8)!), 38 | "TEXT" 39 | ) 40 | XCTAssertEqual( 41 | try decoder.decode(Indirect.self, from: #""TEXT""#.data(using: .utf8)!), 42 | .wrapped("TEXT") 43 | ) 44 | XCTAssertEqual( 45 | try decoder.decode(URL.self, from: #""https://example.com/""#.data(using: .utf8)!), 46 | URL(string: "https://example.com/")! 47 | ) 48 | XCTAssertEqual( 49 | try decoder.decode( 50 | Indirect.self, 51 | from: #""https://example.com/""#.data(using: .utf8)! 52 | ), 53 | .wrapped(URL(string: "https://example.com/")!) 54 | ) 55 | XCTAssertEqual( 56 | try decoder.decode( 57 | Indirect.self, 58 | from: #""https://example.com/""#.data(using: .utf8)! 59 | ), 60 | .wrapped(URL(string: "https://example.com/")!) 61 | ) 62 | } 63 | } 64 | 65 | private extension IndirectTests { 66 | struct Object: Encodable { 67 | @Indirect 68 | var value: Int? 69 | 70 | init(value: Int?) { 71 | self._value = .wrapped(value) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /.github/workflows/update-lexicon.yml: -------------------------------------------------------------------------------- 1 | name: Update Lexicons 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | jobs: 11 | create-pr: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: swift-actions/setup-swift@v1 15 | with: 16 | swift-version: 5.9 17 | - uses: actions/checkout@v3 18 | with: 19 | ref: main 20 | submodules: true 21 | - name: Configure git 22 | run: | 23 | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" 24 | git config --global user.name "github-actions[bot]" 25 | - name: Switch to new branch 26 | id: switch-branch 27 | run: | 28 | BRANCH_NAME="update-lexicon/$(date "+%Y-%m-%d-%H-%M-%S")" 29 | echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT 30 | git switch -c $BRANCH_NAME 31 | - name: Update submodule 32 | run: git submodule update --remote --recursive atproto 33 | - name: Commit updates of submodule 34 | id: commit-submodule 35 | run: | 36 | if [ -n "$(git status --porcelain)" ]; then 37 | git add . 38 | git commit -m "Update bluesky-social/atproto to $(git submodule status atproto | awk '{ print $1 }') at $(date "+DATE: %Y-%m-%d TIME: %H:%M:%S")" 39 | echo "commit=true" >> $GITHUB_OUTPUT 40 | fi 41 | - uses: actions/cache@v3 42 | id: tools-cache 43 | with: 44 | path: Tools/.build 45 | key: ${{ runner.os }}-spm-tools-${{ hashFiles('**/Tools/Package.resolved') }} 46 | restore-keys: | 47 | ${{ runner.os }}-spm-tools- 48 | - name: Build tools 49 | if: steps.tools-cache.outputs.cache-hit != 'true' 50 | run: make build-tools 51 | - name: Generate 52 | run: make lexicon-gen 53 | - name: Commit updates of generated files 54 | id: commit-generated 55 | run: | 56 | if [ -n "$(git status --porcelain)" ]; then 57 | git add . 58 | git commit -m "Update submodules at $(date "+DATE: %Y-%m-%d TIME: %H:%M:%S")" 59 | echo "commit=true" >> $GITHUB_OUTPUT 60 | fi 61 | - name: Create PR 62 | if: ${{ steps.commit-submodule.outputs.commit == 'true' || steps.commit-generated.outputs.commit == 'true' }} 63 | env: 64 | GH_TOKEN: ${{ github.token }} 65 | run: | 66 | git push origin ${{ steps.switch-branch.outputs.branch-name }} 67 | 68 | TITLE="Update bluesky-social/atproto to $(git submodule status atproto | awk '{ print $1 }')" 69 | gh pr create -B main -t "$TITLE" -b "" 70 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/Union.swift.gyb: -------------------------------------------------------------------------------- 1 | 2 | %{ 3 | maxUnionSize = 20 4 | 5 | def typeParameter(i): 6 | return "T{}".format(i) 7 | 8 | def caseName(i): 9 | return "type{}".format(i) 10 | 11 | def asVariableName(i): 12 | return "asType{}".format(i) 13 | }% 14 | 15 | import ATProtoCore 16 | import Foundation 17 | 18 | private enum UnionTypeCodingKeys: String, CodingKey { 19 | case type = "$type" 20 | } 21 | 22 | % for unionSize in range(1, maxUnionSize + 1): 23 | % unionTypeParameters = ", ".join([typeParameter(i) for i in range(unionSize)]) 24 | 25 | // Union${unionSize} 26 | 27 | public enum Union${unionSize}<${unionTypeParameters}> { 28 | 29 | % for i in range(unionSize): 30 | case ${caseName(i)}(${typeParameter(i)}) 31 | % end 32 | 33 | % for i in range(unionSize): 34 | public var ${asVariableName(i)}: ${typeParameter(i)}? { 35 | guard case .${caseName(i)}(let value) = self else { 36 | return nil 37 | } 38 | return value 39 | } 40 | % end 41 | 42 | } 43 | 44 | extension Union${unionSize}: Encodable where ${", ".join([typeParameter(i) + ": UnionEncodable" for i in range(unionSize)])} { 45 | public func encode(to encoder: Encoder) throws { 46 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 47 | 48 | switch self { 49 | % for i in range(unionSize): 50 | case .${caseName(i)}(let value): 51 | try typeContainer.encode(${typeParameter(i)}.typeValue, forKey: .type) 52 | try value.encode(to: encoder) 53 | % end 54 | } 55 | } 56 | } 57 | 58 | extension Union${unionSize}: Decodable where ${", ".join([typeParameter(i) + ": UnionDecodable" for i in range(unionSize)])} { 59 | public init(from decoder: Decoder) throws { 60 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 61 | 62 | let typeValue = try container.decode(String.self, forKey: .type) 63 | let defID = try LexiconDefinitionID(string: typeValue) 64 | switch defID { 65 | % for i in range(unionSize): 66 | case ${typeParameter(i)}.typeValue: 67 | self = .${caseName(i)}(try ${typeParameter(i)}(from: decoder)) 68 | % end 69 | default: 70 | throw DecodingError.dataCorrupted( 71 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 72 | ) 73 | } 74 | } 75 | } 76 | 77 | extension Union${unionSize}: Equatable where ${", ".join([typeParameter(i) + ": Equatable" for i in range(unionSize)])} {} 78 | extension Union${unionSize}: Hashable where ${", ".join([typeParameter(i) + ": Hashable" for i in range(unionSize)])} {} 79 | 80 | % end 81 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.9 2 | 3 | import CompilerPluginSupport 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "swift-atproto", 8 | platforms: [ 9 | .iOS(.v16), 10 | .macOS(.v13), 11 | ], 12 | products: [ 13 | .library( 14 | name: "ATProto", 15 | targets: ["ATProto"] 16 | ), 17 | .library( 18 | name: "ATProtoAPI", 19 | targets: ["ATProtoAPI"] 20 | ), 21 | .library( 22 | name: "ATProtoXRPC", 23 | targets: ["ATProtoXRPC"] 24 | ), 25 | .library( 26 | name: "ATProtoCore", 27 | targets: ["ATProtoCore"] 28 | ), 29 | .library( 30 | name: "ATProtoMacro", 31 | targets: ["ATProtoMacro"] 32 | ), 33 | ], 34 | dependencies: [ 35 | .package(url: "https://github.com/pointfreeco/swift-parsing.git", from: "0.13.0"), 36 | .package(url: "https://github.com/apple/swift-collections.git", from: "1.0.0"), 37 | .package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"), 38 | ], 39 | targets: [ 40 | .target( 41 | name: "ATProto", 42 | dependencies: [ 43 | "ATProtoAPI", 44 | "ATProtoXRPC", 45 | "ATProtoCore", 46 | ] 47 | ), 48 | .target( 49 | name: "ATProtoAPI", 50 | dependencies: [ 51 | "ATProtoXRPC", 52 | "ATProtoCore", 53 | "ATProtoMacro", 54 | ] 55 | ), 56 | .target( 57 | name: "ATProtoXRPC", 58 | dependencies: [ 59 | .target(name: "ATProtoCore"), 60 | .product(name: "Parsing", package: "swift-parsing"), 61 | ], 62 | exclude: [ 63 | "Entities/Union.swift.gyb" 64 | ] 65 | ), 66 | .testTarget( 67 | name: "ATProtoXRPCTests", 68 | dependencies: [ 69 | "ATProtoXRPC", 70 | "ATProtoMacro", 71 | ] 72 | ), 73 | .target( 74 | name: "ATProtoCore", 75 | dependencies: [ 76 | .product(name: "OrderedCollections", package: "swift-collections"), 77 | ] 78 | ), 79 | .testTarget( 80 | name: "ATProtoCoreTests", 81 | dependencies: [ 82 | "ATProtoCore" 83 | ] 84 | ), 85 | .target( 86 | name: "ATProtoMacro", 87 | dependencies: [ 88 | "ATProtoMacroPlugin" 89 | ] 90 | ), 91 | .macro( 92 | name: "ATProtoMacroPlugin", 93 | dependencies: [ 94 | "ATProtoCore", 95 | .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), 96 | .product(name: "SwiftCompilerPlugin", package: "swift-syntax"), 97 | ] 98 | ), 99 | .testTarget( 100 | name: "ATProtoMacroPluginTests", 101 | dependencies: [ 102 | "ATProtoMacroPlugin", 103 | .product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"), 104 | ] 105 | ), 106 | ] 107 | ) 108 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/Indirect.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Property Wrapper to avoid recursive struct definition in generated schema 4 | /// https://forums.swift.org/t/using-indirect-modifier-for-struct-properties/37600/14 5 | @propertyWrapper 6 | public indirect enum Indirect { 7 | case wrapped(T) 8 | 9 | public var wrappedValue: T { 10 | get { 11 | switch self { 12 | case .wrapped(let x): return x 13 | } 14 | } 15 | set { self = .wrapped(newValue) } 16 | } 17 | } 18 | 19 | public protocol IndirectLexiconEncodable { 20 | func encode(forIndirectTo encoder: Encoder) throws 21 | } 22 | 23 | extension Date: IndirectLexiconEncodable { 24 | public func encode(forIndirectTo encoder: Encoder) throws { 25 | var container = encoder.singleValueContainer() 26 | try container.encode(self) 27 | } 28 | } 29 | 30 | extension URL: IndirectLexiconEncodable { 31 | public func encode(forIndirectTo encoder: Encoder) throws { 32 | var container = encoder.singleValueContainer() 33 | try container.encode(self) 34 | } 35 | } 36 | 37 | extension Indirect: Encodable where T: Encodable { 38 | public func encode(to encoder: Encoder) throws { 39 | switch self { 40 | case .wrapped(let x): 41 | if let encodableX = x as? IndirectLexiconEncodable { 42 | try encodableX.encode(forIndirectTo: encoder) 43 | } else { 44 | try x.encode(to: encoder) 45 | } 46 | } 47 | } 48 | } 49 | 50 | public protocol IndirectLexiconDecodable { 51 | init(forIndirect decoder: Decoder) throws 52 | } 53 | 54 | extension Date: IndirectLexiconDecodable { 55 | public init(forIndirect decoder: Decoder) throws { 56 | let container = try decoder.singleValueContainer() 57 | self = try container.decode(Date.self) 58 | } 59 | } 60 | 61 | extension URL: IndirectLexiconDecodable { 62 | public init(forIndirect decoder: Decoder) throws { 63 | let container = try decoder.singleValueContainer() 64 | self = try container.decode(URL.self) 65 | } 66 | } 67 | 68 | extension Indirect: Decodable where T: Decodable { 69 | public init(from decoder: Decoder) throws { 70 | if let decodableType = T.self as? IndirectLexiconDecodable.Type { 71 | self = .wrapped(try decodableType.init(forIndirect: decoder) as! T) 72 | } else { 73 | self = .wrapped(try T(from: decoder)) 74 | } 75 | } 76 | } 77 | 78 | extension Indirect: Equatable where T: Equatable {} 79 | extension Indirect: Hashable where T: Hashable {} 80 | 81 | // Workaround: 82 | // Property Wrapper is decoded by decode(_:forKey:) even though T is Optional. 83 | // It causes keyNotFound error during decoding. This extension can prevent this 84 | // issue. 85 | // https://forums.swift.org/t/using-property-wrappers-with-codable/29804/12 86 | public extension KeyedDecodingContainer { 87 | func decode(_ type: Indirect.Type, forKey key: Self.Key) throws -> Indirect 88 | where T: Decodable { 89 | return try decodeIfPresent(type, forKey: key) ?? .wrapped(nil) 90 | } 91 | } 92 | 93 | public extension KeyedEncodingContainer { 94 | mutating func encode(_ value: Indirect, forKey key: KeyedEncodingContainer.Key) throws where T : Encodable { 95 | try encodeIfPresent(value.wrappedValue, forKey: key) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Extensions/JSONDecoderExtensions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Parsing 3 | 4 | extension JSONDecoder { 5 | static let forXRPC: JSONDecoder = { 6 | let decoder = JSONDecoder() 7 | decoder.dateDecodingStrategy = .custom { decoder in 8 | let container = try decoder.singleValueContainer() 9 | let string = try container.decode(String.self) 10 | 11 | if let date = ISO8601DateFormatter.withFractionalSeconds.date(from: string) { 12 | return date 13 | } 14 | if let date = ISO8601DateFormatter.withTimeZone.date(from: string) { 15 | return date 16 | } 17 | if let date = try DateParsing().parse(string) { 18 | return date 19 | } 20 | 21 | throw DecodingError.dataCorruptedError( 22 | in: container, 23 | debugDescription: "Invalid date string: \(string)" 24 | ) 25 | } 26 | 27 | return decoder 28 | }() 29 | } 30 | 31 | private extension ISO8601DateFormatter { 32 | convenience init(options: Options) { 33 | self.init() 34 | formatOptions = options 35 | } 36 | 37 | static let withFractionalSeconds = ISO8601DateFormatter(options: [.withInternetDateTime, .withFractionalSeconds]) 38 | static let withTimeZone = ISO8601DateFormatter(options: [.withInternetDateTime, .withTimeZone]) 39 | } 40 | 41 | private struct DateParsing: Parser { 42 | var body: some Parser { 43 | Parse(Date.init(year:month:day:hour:minute:second:nanosecond:timeZone:)) { 44 | Digits(4) 45 | "-".utf8 46 | Digits(2).filter { (1...12).contains($0) } 47 | "-".utf8 48 | Digits(2).filter { (1...31).contains($0) } 49 | "T".utf8 50 | Digits(2).filter { $0 < 24 } 51 | ":".utf8 52 | Digits(2).filter { $0 < 60 } 53 | ":".utf8 54 | Digits(2).filter { $0 <= 60 } 55 | Parse { 56 | ".".utf8 57 | Prefix(1...9, while: (UInt8(ascii: "0")...UInt8(ascii: "9")).contains) 58 | .compactMap { n in Int(Substring(n)).map { $0 * Int(pow(10, 9 - Double(n.count))) } } 59 | } 60 | .replaceError(with: 0) 61 | OneOf { 62 | "Z".utf8.map { 0 } 63 | Parse { 64 | OneOf { 65 | "+".utf8.map { 1 } 66 | "-".utf8.map { -1 } 67 | } 68 | Digits(2).filter { $0 < 24 }.map { $0 * 60 * 60 } 69 | ":".utf8 70 | Digits(2).filter { $0 < 60 }.map { $0 * 60 } 71 | } 72 | .map { $0 * ($1 + $2) } 73 | } 74 | .replaceError(with: 0) 75 | } 76 | } 77 | } 78 | 79 | private extension Date { 80 | init?( 81 | year: Int, 82 | month: Int, 83 | day: Int, 84 | hour: Int, 85 | minute: Int, 86 | second: Int, 87 | nanosecond: Int, 88 | timeZone: Int 89 | ) { 90 | let component = DateComponents( 91 | calendar: Calendar(identifier: .gregorian), 92 | timeZone: TimeZone(secondsFromGMT: 0), 93 | year: year, 94 | month: month, 95 | day: day, 96 | hour: hour, 97 | minute: minute, 98 | second: second, 99 | nanosecond: nanosecond 100 | ) 101 | 102 | guard let date = component.date else { 103 | return nil 104 | } 105 | 106 | self = date.addingTimeInterval(TimeInterval(-timeZone)) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Sources/ATProtoCore/Entities/NSID.swift: -------------------------------------------------------------------------------- 1 | import RegexBuilder 2 | 3 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/src/nsid.ts 4 | 5 | public struct NSID: Hashable { 6 | public var segments: [String] 7 | 8 | public init(string: String) throws { 9 | try NSID.ensureValid(string: string) 10 | 11 | self.segments = string.split(separator: ".", omittingEmptySubsequences: false).map(String.init) 12 | } 13 | 14 | public init(authority: String, name: String) throws { 15 | let segments = authority.split(separator: ".", omittingEmptySubsequences: false).reversed().map(String.init) 16 | try self.init(string: (segments + [name]).joined(separator: ".")) 17 | } 18 | 19 | public var authority: String { 20 | segments.dropLast().reversed().joined(separator: ".") 21 | } 22 | 23 | public var name: String { 24 | segments.last! 25 | } 26 | 27 | public func toString() -> String { 28 | segments.joined(separator: ".") 29 | } 30 | } 31 | 32 | extension NSID { 33 | public static func ensureValid(string: String) throws { 34 | guard (try? Self.validCharactersRegex.wholeMatch(in: string)) != nil else { 35 | throw InvalidNSIDError.invalidCharacters 36 | } 37 | 38 | guard string.count <= 253 + 1 + 63 else { 39 | throw InvalidNSIDError.tooLong 40 | } 41 | 42 | let labels = string.split(separator: ".", omittingEmptySubsequences: false) 43 | guard labels.count >= 3 else { 44 | throw InvalidNSIDError.tooFewParts 45 | } 46 | 47 | for (i, label) in labels.enumerated() { 48 | guard !label.isEmpty else { 49 | throw InvalidNSIDError.emptyPart 50 | } 51 | 52 | guard label.count <= 63 else { 53 | throw InvalidNSIDError.partTooLong 54 | } 55 | 56 | guard !label.hasPrefix("-") && !label.hasSuffix("-") else { 57 | throw InvalidNSIDError.startOrEndWithHyphen 58 | } 59 | 60 | guard label.first!.isNumber == false || i != 0 else { 61 | throw InvalidNSIDError.firstPartStartsWithDigit 62 | } 63 | 64 | guard (try? Self.alphaCharactersRegex.wholeMatch(in: label)) != nil || i != labels.count - 1 else { 65 | throw InvalidNSIDError.namePartOnlyLetters 66 | } 67 | } 68 | } 69 | 70 | private enum InvalidNSIDError: Error { 71 | case invalidCharacters 72 | case tooLong 73 | case tooFewParts 74 | case emptyPart 75 | case partTooLong 76 | case startOrEndWithHyphen 77 | case firstPartStartsWithDigit 78 | case namePartOnlyLetters 79 | } 80 | 81 | private static let validCharactersRegex = Regex { 82 | ZeroOrMore { 83 | CharacterClass( 84 | ("a"..."z"), 85 | ("A"..."Z"), 86 | ("0"..."9"), 87 | .anyOf(".-") 88 | ) 89 | } 90 | } 91 | private static let alphaCharactersRegex = Regex { 92 | OneOrMore { 93 | CharacterClass( 94 | ("a"..."z"), 95 | ("A"..."Z") 96 | ) 97 | } 98 | } 99 | } 100 | 101 | extension NSID: Encodable { 102 | public func encode(to encoder: Encoder) throws { 103 | var container = encoder.singleValueContainer() 104 | try container.encode(self.toString()) 105 | } 106 | } 107 | 108 | extension NSID: Decodable { 109 | public init(from decoder: Decoder) throws { 110 | let container = try decoder.singleValueContainer() 111 | let string = try container.decode(String.self) 112 | 113 | do { 114 | self = try NSID(string: string) 115 | } catch { 116 | throw DecodingError.dataCorruptedError( 117 | in: container, 118 | debugDescription: "Invalid NSID string: \(string). Got error: \(error)" 119 | ) 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/XRPC/XRPCSessionClient.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct XRPCSessionClient { 4 | public enum Error: Swift.Error { 5 | case buildingURLRequestFailed 6 | case unacceptableStatusCode(Int, errorResponse: XRPCErrorResponse?) 7 | case decodingResponseFailed(error: Swift.Error, data: Data) 8 | case refresingSessionFailed(by: Swift.Error, original: Swift.Error) 9 | case unknown(underlying: Swift.Error?) 10 | } 11 | 12 | private let baseURL: URL 13 | private let urlSession: URLSession 14 | private let sessionProvider: SessionProvider 15 | 16 | public init( 17 | baseURL: URL, 18 | urlSession: URLSession, 19 | sessionProvider: SessionProvider 20 | ) { 21 | self.baseURL = baseURL 22 | self.urlSession = urlSession 23 | self.sessionProvider = sessionProvider 24 | } 25 | } 26 | 27 | extension XRPCSessionClient: XRPCClient { 28 | public func send(_ request: R) async throws -> R.Output where R: XRPCRequest { 29 | let originalError: Swift.Error 30 | do { 31 | let urlRequest = try buildRequest(from: request) 32 | let response = try await sendRequest(urlRequest, type: R.Output.self) 33 | return response 34 | } catch { 35 | guard 36 | case .unacceptableStatusCode(_, errorResponse: let errorResponse?) = error as? Error, 37 | case .errorCode(.expiredToken) = errorResponse.error 38 | else { 39 | throw error 40 | } 41 | 42 | originalError = error 43 | } 44 | 45 | do { 46 | try await refreshSession() 47 | } catch { 48 | throw Error.refresingSessionFailed(by: error, original: originalError) 49 | } 50 | 51 | let urlRequest = try buildRequest(from: request) 52 | return try await sendRequest(urlRequest, type: R.Output.self) 53 | } 54 | } 55 | 56 | private extension XRPCSessionClient { 57 | var encoder: JSONEncoder { 58 | let encoder = JSONEncoder() 59 | encoder.dateEncodingStrategy = .iso8601 60 | 61 | return encoder 62 | } 63 | 64 | var decoder: JSONDecoder { 65 | JSONDecoder.forXRPC 66 | } 67 | 68 | func buildRequest(from request: R) throws -> URLRequest where R: XRPCRequest { 69 | guard 70 | var urlComponent = URLComponents( 71 | url: baseURL.appendingPathComponent(request.requestIdentifier), 72 | resolvingAgainstBaseURL: false 73 | ) 74 | else { 75 | throw Error.buildingURLRequestFailed 76 | } 77 | urlComponent.queryItems = request.parameters.queryItems 78 | 79 | guard let url = urlComponent.url else { 80 | throw Error.buildingURLRequestFailed 81 | } 82 | 83 | var urlRequest = URLRequest(url: url) 84 | urlRequest.httpMethod = request.type.httpMethod 85 | 86 | if let input = request.input { 87 | urlRequest.httpBody = try encoder.encode(input) 88 | } 89 | if urlRequest.httpBody != nil { 90 | urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") 91 | } 92 | 93 | if let accessJWT = sessionProvider.session?.accessJWT { 94 | urlRequest.setValue("Bearer \(accessJWT.rawValue)", forHTTPHeaderField: "Authorization") 95 | } 96 | 97 | return urlRequest 98 | } 99 | 100 | func sendRequest(_ request: URLRequest, type: Response.Type) async throws -> Response 101 | where Response: Decodable { 102 | let (data, response) = try await urlSession.data(for: request) 103 | guard let httpResponse = response as? HTTPURLResponse else { 104 | throw Error.unknown(underlying: nil) 105 | } 106 | 107 | switch httpResponse.statusCode { 108 | case 200..<300 where Response.self == EmptyOutput.self: 109 | return EmptyOutput() as! Response 110 | 111 | case 200..<300: 112 | let decoded: Response 113 | do { 114 | decoded = try decoder.decode(Response.self, from: data) 115 | } catch { 116 | throw Error.decodingResponseFailed(error: error, data: data) 117 | } 118 | 119 | return decoded 120 | 121 | default: 122 | let errorResponse = try? decoder.decode(XRPCErrorResponse.self, from: data) 123 | throw Error.unacceptableStatusCode( 124 | httpResponse.statusCode, 125 | errorResponse: errorResponse 126 | ) 127 | } 128 | } 129 | 130 | func refreshSession() async throws { 131 | var urlRequest = try buildRequest(from: XRPCRequests.RefreshSession()) 132 | urlRequest.setValue( 133 | "Bearer \(sessionProvider.session?.refreshJWT.rawValue ?? "")", 134 | forHTTPHeaderField: "Authorization" 135 | ) 136 | 137 | let response = try await sendRequest( 138 | urlRequest, 139 | type: XRPCRequests.RefreshSession.Output.self 140 | ) 141 | sessionProvider.session = response.toSession() 142 | } 143 | } 144 | 145 | private extension XRPCRequestType { 146 | var httpMethod: String { 147 | switch self { 148 | case .query: 149 | return "GET" 150 | 151 | case .procedure: 152 | return "POST" 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /Sources/ATProtoCore/Entities/ATURI.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import OrderedCollections 3 | import RegexBuilder 4 | 5 | // https://github.com/bluesky-social/atproto/blob/0533fab68ea32df4e00948ddfc2422c6f900223a/packages/syntax/src/aturi.ts 6 | 7 | public struct ATURI: Hashable { 8 | public var host: String 9 | public var path: String? 10 | public var query: OrderedDictionary 11 | public var hash: String? 12 | 13 | // TODO: Support relative URIs 14 | public init?(string: String) { 15 | guard let match = try? Self.atURIRegex.wholeMatch(in: string) else { 16 | return nil 17 | } 18 | 19 | self.host = String(match[Self.hostRef]) 20 | self.path = match[Self.pathRef].map(String.init) 21 | 22 | let queryStr = match[Self.queryRef].map(String.init) 23 | var query = OrderedDictionary() 24 | for pair in queryStr?.split(separator: "&") ?? [] { 25 | let parts = pair.split(separator: "=") 26 | if parts.count == 1 { 27 | query[String(parts[0])] = nil 28 | } else { 29 | query[String(parts[0])] = String(parts[1]) 30 | } 31 | } 32 | self.query = query 33 | 34 | self.hash = match[Self.hashRef].map(String.init) 35 | } 36 | 37 | public var collection: String? { 38 | self.path?.split(separator: "/").filter { !$0.isEmpty }.first.map(String.init) 39 | } 40 | 41 | public var rkey: String? { 42 | self.path?.split(separator: "/").filter { !$0.isEmpty }.dropFirst().first.map(String.init) 43 | } 44 | 45 | public func toString() -> String { 46 | var path = self.path ?? "/" 47 | if !path.hasPrefix("/") { 48 | path = "/\(path)" 49 | } 50 | 51 | var qs = self.query.map { $0.key + ($0.value.map { "=\($0)" } ?? "") }.joined(separator: "&") 52 | if !qs.isEmpty && !qs.hasPrefix("?") { 53 | qs = "?\(qs)" 54 | } 55 | 56 | var hash = self.hash ?? "" 57 | if !hash.isEmpty && !hash.hasPrefix("#") { 58 | hash = "#\(hash)" 59 | } 60 | 61 | return "at://\(self.host)\(path)\(qs)\(hash)" 62 | } 63 | } 64 | 65 | extension ATURI: Encodable { 66 | public func encode(to encoder: Encoder) throws { 67 | var container = encoder.singleValueContainer() 68 | try container.encode(self.toString()) 69 | } 70 | } 71 | 72 | extension ATURI: Decodable { 73 | public init(from decoder: Decoder) throws { 74 | let container = try decoder.singleValueContainer() 75 | let string = try container.decode(String.self) 76 | 77 | guard let atURI = Self(string: string) else { 78 | throw DecodingError.dataCorruptedError( 79 | in: container, 80 | debugDescription: "Invalid AT URI string: \(string)" 81 | ) 82 | } 83 | 84 | self = atURI 85 | } 86 | } 87 | 88 | private extension ATURI { 89 | static let hostRef = Reference(Substring.self) 90 | static let pathRef = Reference(Substring?.self) 91 | static let queryRef = Reference(Substring?.self) 92 | static let hashRef = Reference(Substring?.self) 93 | 94 | static let atURIRegex = Regex { 95 | Optionally { 96 | Capture { 97 | "at://" 98 | } 99 | } 100 | // Host 101 | Capture(as: hostRef) { 102 | ChoiceOf { 103 | Regex { 104 | "did:" 105 | OneOrMore { 106 | CharacterClass( 107 | .anyOf(":%-"), 108 | ("a"..."z"), 109 | ("0"..."9") 110 | ) 111 | } 112 | } 113 | Regex { 114 | CharacterClass( 115 | ("a"..."z"), 116 | ("0"..."9") 117 | ) 118 | ZeroOrMore { 119 | CharacterClass( 120 | .anyOf(".:-"), 121 | ("a"..."z"), 122 | ("0"..."9") 123 | ) 124 | } 125 | } 126 | } 127 | } 128 | // Path 129 | Optionally { 130 | Capture(as: pathRef) { 131 | Regex { 132 | "/" 133 | ZeroOrMore { 134 | CharacterClass( 135 | .anyOf("?#"), 136 | .whitespace 137 | ) 138 | .inverted 139 | } 140 | } 141 | } transform: { $0 } 142 | } 143 | // Query 144 | Optionally { 145 | "?" 146 | Capture(as: queryRef) { 147 | Regex { 148 | OneOrMore { 149 | CharacterClass( 150 | .anyOf("#"), 151 | .whitespace 152 | ) 153 | .inverted 154 | } 155 | } 156 | } transform: { $0 } 157 | } 158 | // Hash 159 | Optionally { 160 | Capture(as: hashRef) { 161 | Regex { 162 | "#" 163 | OneOrMore(.whitespace.inverted) 164 | } 165 | } transform: { $0 } 166 | } 167 | } 168 | .ignoresCase() 169 | } 170 | -------------------------------------------------------------------------------- /Tests/ATProtoCoreTests/Entities/NSIDTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | @testable import ATProtoCore 4 | 5 | final class NSIDTests: XCTestCase { 6 | func testInitWithString() throws { 7 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/tests/nsid.test.ts#L11-L22 8 | 9 | let value1 = try NSID(string: "com.example.foo") 10 | XCTAssertEqual(value1.authority, "example.com") 11 | XCTAssertEqual(value1.name, "foo") 12 | XCTAssertEqual(value1.toString(), "com.example.foo") 13 | 14 | let value2 = try NSID(string: "com.long-thing1.cool.fooBarBaz") 15 | XCTAssertEqual(value2.authority, "cool.long-thing1.com") 16 | XCTAssertEqual(value2.name, "fooBarBaz") 17 | XCTAssertEqual(value2.toString(), "com.long-thing1.cool.fooBarBaz") 18 | } 19 | 20 | func testInitWithAuthorityAndName() throws { 21 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/tests/nsid.test.ts#L24-L38 22 | 23 | let value1 = try NSID(authority: "example.com", name: "foo") 24 | XCTAssertEqual(value1.authority, "example.com") 25 | XCTAssertEqual(value1.name, "foo") 26 | XCTAssertEqual(value1.toString(), "com.example.foo") 27 | 28 | let value2 = try NSID(authority: "cool.long-thing1.com", name: "fooBarBaz") 29 | XCTAssertEqual(value2.authority, "cool.long-thing1.com") 30 | XCTAssertEqual(value2.name, "fooBarBaz") 31 | XCTAssertEqual(value2.toString(), "com.long-thing1.cool.fooBarBaz") 32 | } 33 | 34 | // enforces spec details 35 | func testEnsureValid_EnforcesSpecDetails() throws { 36 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/tests/nsid.test.ts#L50-L112 37 | 38 | XCTAssertNoThrow(try NSID.ensureValid(string: "com.example.foo")) 39 | 40 | let longNSID = "com." + String(repeating: "o", count: 63) + ".foo" 41 | XCTAssertNoThrow(try NSID.ensureValid(string: longNSID)) 42 | 43 | let tooLongNSID = "com." + String(repeating: "o", count: 64) + ".foo" 44 | XCTAssertThrowsError(try NSID.ensureValid(string: tooLongNSID)) 45 | 46 | let longEnd = "com.example." + String(repeating: "o", count: 63) 47 | XCTAssertNoThrow(try NSID.ensureValid(string: longEnd)) 48 | 49 | let tooLongEnd = "com.example." + String(repeating: "o", count: 64) 50 | XCTAssertThrowsError(try NSID.ensureValid(string: tooLongEnd)) 51 | 52 | let longOverall = "com." + String(repeating: "middle.", count: 40) + "foo" 53 | XCTAssertEqual(longOverall.count, 287) 54 | XCTAssertNoThrow(try NSID.ensureValid(string: longOverall)) 55 | 56 | let tooLongOverall = "com." + String(repeating: "middle.", count: 50) + "foo" 57 | XCTAssertEqual(tooLongOverall.count, 357) 58 | XCTAssertThrowsError(try NSID.ensureValid(string: tooLongOverall)) 59 | 60 | XCTAssertNoThrow(try NSID.ensureValid(string: "com.example.fooBar")) 61 | XCTAssertNoThrow(try NSID.ensureValid(string: "net.users.bob.ping")) 62 | XCTAssertNoThrow(try NSID.ensureValid(string: "a.b.c")) 63 | XCTAssertNoThrow(try NSID.ensureValid(string: "m.xn--masekowski-d0b.pl")) 64 | XCTAssertNoThrow(try NSID.ensureValid(string: "one.two.three")) 65 | XCTAssertNoThrow(try NSID.ensureValid(string: "one.two.three.four-and.FiVe")) 66 | XCTAssertNoThrow(try NSID.ensureValid(string: "one.2.three")) 67 | XCTAssertNoThrow(try NSID.ensureValid(string: "a-0.b-1.c")) 68 | XCTAssertNoThrow(try NSID.ensureValid(string: "a0.b1.cc")) 69 | XCTAssertNoThrow(try NSID.ensureValid(string: "cn.8.lex.stuff")) 70 | XCTAssertNoThrow(try NSID.ensureValid(string: "test.12345.record")) 71 | XCTAssertNoThrow(try NSID.ensureValid(string: "a01.thing.record")) 72 | XCTAssertNoThrow(try NSID.ensureValid(string: "a.0.c")) 73 | XCTAssertNoThrow(try NSID.ensureValid(string: "xn--fiqs8s.xn--fiqa61au8b7zsevnm8ak20mc4a87e.record.two")) 74 | 75 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.example.foo.*")) 76 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.example.foo.blah*")) 77 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.example.foo.*blah")) 78 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.example.f00")) 79 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.exa💩ple.thing")) 80 | XCTAssertThrowsError(try NSID.ensureValid(string: "a-0.b-1.c-3")) 81 | XCTAssertThrowsError(try NSID.ensureValid(string: "a-0.b-1.c-o")) 82 | XCTAssertThrowsError(try NSID.ensureValid(string: "a0.b1.c3")) 83 | XCTAssertThrowsError(try NSID.ensureValid(string: "1.0.0.127.record")) 84 | XCTAssertThrowsError(try NSID.ensureValid(string: "0two.example.foo")) 85 | XCTAssertThrowsError(try NSID.ensureValid(string: "example.com")) 86 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.example")) 87 | XCTAssertThrowsError(try NSID.ensureValid(string: "a.")) 88 | XCTAssertThrowsError(try NSID.ensureValid(string: ".one.two.three")) 89 | XCTAssertThrowsError(try NSID.ensureValid(string: "one.two.three ")) 90 | XCTAssertThrowsError(try NSID.ensureValid(string: "one.two..three")) 91 | XCTAssertThrowsError(try NSID.ensureValid(string: "one .two.three")) 92 | XCTAssertThrowsError(try NSID.ensureValid(string: " one.two.three")) 93 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.exa💩ple.thing")) 94 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.atproto.feed.p@st")) 95 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.atproto.feed.p_st")) 96 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.atproto.feed.p*st")) 97 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.atproto.feed.po#t")) 98 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.atproto.feed.p!ot")) 99 | XCTAssertThrowsError(try NSID.ensureValid(string: "com.example-.foo")) 100 | } 101 | 102 | // allows onion (Tor) NSIDs 103 | func testEnsureValid_AllowsOnionNSIDs() throws { 104 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/tests/nsid.test.ts#L114-L119 105 | 106 | XCTAssertNoThrow(try NSID.ensureValid(string: "onion.expyuzz4wqqyqhjn.spec.getThing")) 107 | XCTAssertNoThrow(try NSID.ensureValid(string: "onion.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing")) 108 | } 109 | 110 | // allows starting-with-numeric segments (same as domains) 111 | func testEnsureValid_AllowsStartingWithNumericSegments() throws { 112 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/tests/nsid.test.ts#L121-L127 113 | 114 | XCTAssertNoThrow(try NSID.ensureValid(string: "org.4chan.lex.getThing")) 115 | XCTAssertNoThrow(try NSID.ensureValid(string: "cn.8.lex.stuff")) 116 | XCTAssertNoThrow(try NSID.ensureValid(string: "onion.2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing")) 117 | } 118 | 119 | // conforms to interop valid NSIDs 120 | func testEnsureValid_ConformsToInteropValidNSIDs() throws { 121 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/tests/nsid.test.ts#L129-L142 122 | 123 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/interop-test-files/syntax/nsid_syntax_valid.txt 124 | let strings = [ 125 | // length checks 126 | "com.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.foo", 127 | "com.example.ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", 128 | "com.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.foo", 129 | // valid examples 130 | "com.example.fooBar", 131 | "net.users.bob.ping", 132 | "a.b.c", 133 | "m.xn--masekowski-d0b.pl", 134 | "one.two.three", 135 | "one.two.three.four-and.FiVe", 136 | "one.2.three", 137 | "a-0.b-1.c", 138 | "a0.b1.cc", 139 | "cn.8.lex.stuff", 140 | "test.12345.record", 141 | "a01.thing.record", 142 | "a.0.c", 143 | "xn--fiqs8s.xn--fiqa61au8b7zsevnm8ak20mc4a87e.record.two", 144 | // allows onion (Tor) NSIDs 145 | "onion.expyuzz4wqqyqhjn.spec.getThing", 146 | "onion.g2zyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing", 147 | // allows starting-with-numeric segments (same as domains) 148 | "org.4chan.lex.getThing", 149 | "cn.8.lex.stuff", 150 | "onion.2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.lex.deleteThing", 151 | ] 152 | 153 | for string in strings { 154 | XCTAssertNoThrow(try NSID.ensureValid(string: string), string) 155 | } 156 | } 157 | 158 | // conforms to interop invalid NSIDs 159 | func testEnsureValid_ConformsToInteropInvalidNSIDs() throws { 160 | // https://github.com/bluesky-social/atproto/blob/44ea5e80fa6f8a8724ff29a06f7fa8fc5d7f57ef/packages/syntax/tests/nsid.test.ts#L144-L158 161 | 162 | // https://github.com/bluesky-social/atproto/blob/main/interop-test-files/syntax/nsid_syntax_invalid.txt 163 | let strings = [ 164 | // length checks 165 | "com.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.foo", 166 | "com.example.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", 167 | "com.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.middle.foo", 168 | // invliad examples 169 | "com.example.foo.*", 170 | "com.example.foo.blah*", 171 | "com.example.foo.*blah", 172 | "com.example.f00", 173 | "com.exa💩ple.thing", 174 | "a-0.b-1.c-3", 175 | "a-0.b-1.c-o", 176 | "a0.b1.c3", 177 | "1.0.0.127.record", 178 | "0two.example.foo", 179 | "example.com", 180 | "com.example", 181 | "a.", 182 | ".one.two.three", 183 | "one.two.three ", 184 | "one.two..three", 185 | "one .two.three", 186 | " one.two.three", 187 | "com.exa💩ple.thing", 188 | "com.atproto.feed.p@st", 189 | "com.atproto.feed.p_st", 190 | "com.atproto.feed.p*st", 191 | "com.atproto.feed.po#t", 192 | "com.atproto.feed.p!ot", 193 | "com.example-.foo", 194 | ] 195 | 196 | for string in strings { 197 | XCTAssertThrowsError(try NSID.ensureValid(string: string), string) 198 | } 199 | } 200 | 201 | func testEncoding() throws { 202 | let nsid = try NSID(string: "com.example.foo") 203 | 204 | let encoder = JSONEncoder() 205 | XCTAssertEqual( 206 | String(data: try encoder.encode(nsid), encoding: .utf8), 207 | #""com.example.foo""# 208 | ) 209 | } 210 | 211 | func testDecoding() throws { 212 | let nsid = try NSID(string: "com.example.foo") 213 | 214 | let decoder = JSONDecoder() 215 | XCTAssertEqual( 216 | try decoder.decode(NSID.self, from: #""com.example.foo""#.data(using: .utf8)!), 217 | nsid 218 | ) 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /Tests/ATProtoCoreTests/Entities/ATURITests.swift: -------------------------------------------------------------------------------- 1 | import OrderedCollections 2 | import XCTest 3 | 4 | @testable import ATProtoCore 5 | 6 | final class ATURITests: XCTestCase { 7 | // https://github.com/bluesky-social/atproto/blob/0533fab68ea32df4e00948ddfc2422c6f900223a/packages/syntax/tests/aturi.test.ts#L4 8 | func testParsing() throws { 9 | let cases: [(String, String, String?, OrderedDictionary, String?, UInt)] = [ 10 | ("foo.com", "foo.com", nil, [:], nil, #line), 11 | ("at://foo.com", "foo.com", nil, [:], nil, #line), 12 | ("at://foo.com/", "foo.com", "/", [:], nil, #line), 13 | ("at://foo.com/foo", "foo.com", "/foo", [:], nil, #line), 14 | ("at://foo.com/foo/", "foo.com", "/foo/", [:], nil, #line), 15 | ("at://foo.com/foo/bar", "foo.com", "/foo/bar", [:], nil, #line), 16 | ("at://foo.com?foo=bar", "foo.com", nil, ["foo": "bar"], nil, #line), 17 | ("at://foo.com?foo=bar&baz=buux", "foo.com", nil, ["foo": "bar", "baz": "buux"], nil, #line), 18 | ("at://foo.com/?foo=bar", "foo.com", "/", ["foo": "bar"], nil, #line), 19 | ("at://foo.com/foo?foo=bar", "foo.com", "/foo", ["foo": "bar"], nil, #line), 20 | ("at://foo.com/foo/?foo=bar", "foo.com", "/foo/", ["foo": "bar"], nil, #line), 21 | ("at://foo.com#hash", "foo.com", nil, [:], "#hash", #line), 22 | ("at://foo.com/#hash", "foo.com", "/", [:], "#hash", #line), 23 | ("at://foo.com/foo#hash", "foo.com", "/foo", [:], "#hash", #line), 24 | ("at://foo.com/foo/#hash", "foo.com", "/foo/", [:], "#hash", #line), 25 | ("at://foo.com?foo=bar#hash", "foo.com", nil, ["foo": "bar"], "#hash", #line), 26 | ( 27 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 28 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 29 | nil, 30 | [:], 31 | nil, 32 | #line 33 | ), 34 | ( 35 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 36 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 37 | nil, 38 | [:], 39 | nil, 40 | #line 41 | ), 42 | ( 43 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/", 44 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 45 | "/", 46 | [:], 47 | nil, 48 | #line 49 | ), 50 | ( 51 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo", 52 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 53 | "/foo", 54 | [:], 55 | nil, 56 | #line 57 | ), 58 | ( 59 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/", 60 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 61 | "/foo/", 62 | [:], 63 | nil, 64 | #line 65 | ), 66 | ( 67 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/bar", 68 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 69 | "/foo/bar", 70 | [:], 71 | nil, 72 | #line 73 | ), 74 | ( 75 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw?foo=bar", 76 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 77 | nil, 78 | ["foo": "bar"], 79 | nil, 80 | #line 81 | ), 82 | ( 83 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw?foo=bar&baz=buux", 84 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 85 | nil, 86 | ["foo": "bar", "baz": "buux"], 87 | nil, 88 | #line 89 | ), 90 | ( 91 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/?foo=bar", 92 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 93 | "/", 94 | ["foo": "bar"], 95 | nil, 96 | #line 97 | ), 98 | ( 99 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo?foo=bar", 100 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 101 | "/foo", 102 | ["foo": "bar"], 103 | nil, 104 | #line 105 | ), 106 | ( 107 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/?foo=bar", 108 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 109 | "/foo/", 110 | ["foo": "bar"], 111 | nil, 112 | #line 113 | ), 114 | ( 115 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw#hash", 116 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 117 | nil, 118 | [:], 119 | "#hash", 120 | #line 121 | ), 122 | ( 123 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/#hash", 124 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 125 | "/", 126 | [:], 127 | "#hash", 128 | #line 129 | ), 130 | ( 131 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo#hash", 132 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 133 | "/foo", 134 | [:], 135 | "#hash", 136 | #line 137 | ), 138 | ( 139 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw/foo/#hash", 140 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 141 | "/foo/", 142 | [:], 143 | "#hash", 144 | #line 145 | ), 146 | ( 147 | "at://did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw?foo=bar#hash", 148 | "did:example:EiAnKD8-jfdd0MDcZUjAbRgaThBrMxPTFOxcnfJhI7Ukaw", 149 | nil, 150 | ["foo": "bar"], 151 | "#hash", 152 | #line 153 | ), 154 | 155 | ("did:web:localhost%3A1234", "did:web:localhost%3A1234", nil, [:], nil, #line), 156 | ("at://did:web:localhost%3A1234", "did:web:localhost%3A1234", nil, [:], nil, #line), 157 | ( 158 | "at://did:web:localhost%3A1234/", 159 | "did:web:localhost%3A1234", 160 | "/", 161 | [:], 162 | nil, 163 | #line 164 | ), 165 | ( 166 | "at://did:web:localhost%3A1234/foo", 167 | "did:web:localhost%3A1234", 168 | "/foo", 169 | [:], 170 | nil, 171 | #line 172 | ), 173 | ( 174 | "at://did:web:localhost%3A1234/foo/", 175 | "did:web:localhost%3A1234", 176 | "/foo/", 177 | [:], 178 | nil, 179 | #line 180 | ), 181 | ( 182 | "at://did:web:localhost%3A1234/foo/bar", 183 | "did:web:localhost%3A1234", 184 | "/foo/bar", 185 | [:], 186 | nil, 187 | #line 188 | ), 189 | ( 190 | "at://did:web:localhost%3A1234?foo=bar", 191 | "did:web:localhost%3A1234", 192 | nil, 193 | ["foo": "bar"], 194 | nil, 195 | #line 196 | ), 197 | ( 198 | "at://did:web:localhost%3A1234?foo=bar&baz=buux", 199 | "did:web:localhost%3A1234", 200 | nil, 201 | ["foo": "bar", "baz": "buux"], 202 | nil, 203 | #line 204 | ), 205 | ( 206 | "at://did:web:localhost%3A1234/?foo=bar", 207 | "did:web:localhost%3A1234", 208 | "/", 209 | ["foo": "bar"], 210 | nil, 211 | #line 212 | ), 213 | ( 214 | "at://did:web:localhost%3A1234/foo?foo=bar", 215 | "did:web:localhost%3A1234", 216 | "/foo", 217 | ["foo": "bar"], 218 | nil, 219 | #line 220 | ), 221 | ( 222 | "at://did:web:localhost%3A1234/foo/?foo=bar", 223 | "did:web:localhost%3A1234", 224 | "/foo/", 225 | ["foo": "bar"], 226 | nil, 227 | #line 228 | ), 229 | ( 230 | "at://did:web:localhost%3A1234#hash", 231 | "did:web:localhost%3A1234", 232 | nil, 233 | [:], 234 | "#hash", 235 | #line 236 | ), 237 | ( 238 | "at://did:web:localhost%3A1234/#hash", 239 | "did:web:localhost%3A1234", 240 | "/", 241 | [:], 242 | "#hash", 243 | #line 244 | ), 245 | ( 246 | "at://did:web:localhost%3A1234/foo#hash", 247 | "did:web:localhost%3A1234", 248 | "/foo", 249 | [:], 250 | "#hash", 251 | #line 252 | ), 253 | ( 254 | "at://did:web:localhost%3A1234/foo/#hash", 255 | "did:web:localhost%3A1234", 256 | "/foo/", 257 | [:], 258 | "#hash", 259 | #line 260 | ), 261 | ( 262 | "at://did:web:localhost%3A1234?foo=bar#hash", 263 | "did:web:localhost%3A1234", 264 | nil, 265 | ["foo": "bar"], 266 | "#hash", 267 | #line 268 | ), 269 | ( 270 | "at://4513echo.bsky.social/app.bsky.feed.post/3jsrpdyf6ss23", 271 | "4513echo.bsky.social", 272 | "/app.bsky.feed.post/3jsrpdyf6ss23", 273 | [:], 274 | nil, 275 | #line 276 | ), 277 | ] 278 | 279 | for (input, host, path, query, hash, line) in cases { 280 | let uri = try XCTUnwrap(ATURI(string: input), line: line) 281 | 282 | XCTAssertEqual(uri.host, host, line: line) 283 | XCTAssertEqual(uri.path, path, line: line) 284 | XCTAssertEqual(uri.query, query, line: line) 285 | XCTAssertEqual(uri.hash, hash, line: line) 286 | } 287 | } 288 | 289 | // https://github.com/bluesky-social/atproto/blob/0533fab68ea32df4e00948ddfc2422c6f900223a/packages/syntax/tests/aturi.test.ts#L258 290 | func testATProtoSpecificParsing() throws { 291 | let cases: [(String, String?, String?, UInt)] = [ 292 | ("at://foo.com", nil, nil, #line), 293 | ("at://foo.com/com.example.foo", "com.example.foo", nil, #line), 294 | ("at://foo.com/com.example.foo/123", "com.example.foo", "123", #line), 295 | ] 296 | 297 | for (input, collection, rkey, line) in cases { 298 | let uri = try XCTUnwrap(ATURI(string: input), line: line) 299 | 300 | XCTAssertEqual(uri.collection, collection, line: line) 301 | XCTAssertEqual(uri.rkey, rkey, line: line) 302 | } 303 | } 304 | 305 | // https://github.com/bluesky-social/atproto/blob/0533fab68ea32df4e00948ddfc2422c6f900223a/packages/syntax/tests/aturi.test.ts#L276 306 | func testModification() throws { 307 | var uri = try XCTUnwrap(ATURI(string: "at://foo.com")) 308 | XCTAssertEqual(uri.toString(), "at://foo.com/") 309 | 310 | uri.host = "bar.com" 311 | XCTAssertEqual(uri.toString(), "at://bar.com/") 312 | uri.host = "did:web:localhost%3A1234" 313 | XCTAssertEqual(uri.toString(), "at://did:web:localhost%3A1234/") 314 | uri.host = "foo.com" 315 | 316 | uri.path = "/" 317 | XCTAssertEqual(uri.toString(), "at://foo.com/") 318 | uri.path = "/foo" 319 | XCTAssertEqual(uri.toString(), "at://foo.com/foo") 320 | uri.path = "foo" 321 | XCTAssertEqual(uri.toString(), "at://foo.com/foo") 322 | 323 | // TODO: Support modifying collection & rkey 324 | 325 | uri.query = ["foo": "bar"] 326 | XCTAssertEqual(uri.toString(), "at://foo.com/foo?foo=bar") 327 | uri.query["baz"] = "buux" 328 | XCTAssertEqual(uri.toString(), "at://foo.com/foo?foo=bar&baz=buux") 329 | 330 | uri.hash = "#hash" 331 | XCTAssertEqual(uri.toString(), "at://foo.com/foo?foo=bar&baz=buux#hash") 332 | uri.hash = "hash" 333 | XCTAssertEqual(uri.toString(), "at://foo.com/foo?foo=bar&baz=buux#hash") 334 | } 335 | 336 | func testEncoding() throws { 337 | let uri = try XCTUnwrap(ATURI(string: "at://did:A:B/collection/rkey?foo=bar#hash")) 338 | 339 | let encoder = JSONEncoder() 340 | XCTAssertEqual( 341 | String(data: try encoder.encode(uri), encoding: .utf8), 342 | #""at:\/\/did:A:B\/collection\/rkey?foo=bar#hash""# 343 | ) 344 | } 345 | 346 | func testDecoding() throws { 347 | let uri = try XCTUnwrap(ATURI(string: "at://did:A:B/collection/rkey?foo=bar#hash")) 348 | 349 | let decoder = JSONDecoder() 350 | XCTAssertEqual( 351 | try decoder.decode(ATURI.self, from: #""at:\/\/did:A:B\/collection\/rkey?foo=bar#hash""#.data(using: .utf8)!), 352 | uri 353 | ) 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /Sources/ATProtoXRPC/Entities/Union.generated.swift: -------------------------------------------------------------------------------- 1 | 2 | 3 | import ATProtoCore 4 | import Foundation 5 | 6 | private enum UnionTypeCodingKeys: String, CodingKey { 7 | case type = "$type" 8 | } 9 | 10 | 11 | // Union1 12 | 13 | public enum Union1 { 14 | 15 | case type0(T0) 16 | 17 | public var asType0: T0? { 18 | guard case .type0(let value) = self else { 19 | return nil 20 | } 21 | return value 22 | } 23 | 24 | } 25 | 26 | extension Union1: Encodable where T0: UnionEncodable { 27 | public func encode(to encoder: Encoder) throws { 28 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 29 | 30 | switch self { 31 | case .type0(let value): 32 | try typeContainer.encode(T0.typeValue, forKey: .type) 33 | try value.encode(to: encoder) 34 | } 35 | } 36 | } 37 | 38 | extension Union1: Decodable where T0: UnionDecodable { 39 | public init(from decoder: Decoder) throws { 40 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 41 | 42 | let typeValue = try container.decode(String.self, forKey: .type) 43 | let defID = try LexiconDefinitionID(string: typeValue) 44 | switch defID { 45 | case T0.typeValue: 46 | self = .type0(try T0(from: decoder)) 47 | default: 48 | throw DecodingError.dataCorrupted( 49 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 50 | ) 51 | } 52 | } 53 | } 54 | 55 | extension Union1: Equatable where T0: Equatable {} 56 | extension Union1: Hashable where T0: Hashable {} 57 | 58 | 59 | // Union2 60 | 61 | public enum Union2 { 62 | 63 | case type0(T0) 64 | case type1(T1) 65 | 66 | public var asType0: T0? { 67 | guard case .type0(let value) = self else { 68 | return nil 69 | } 70 | return value 71 | } 72 | public var asType1: T1? { 73 | guard case .type1(let value) = self else { 74 | return nil 75 | } 76 | return value 77 | } 78 | 79 | } 80 | 81 | extension Union2: Encodable where T0: UnionEncodable, T1: UnionEncodable { 82 | public func encode(to encoder: Encoder) throws { 83 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 84 | 85 | switch self { 86 | case .type0(let value): 87 | try typeContainer.encode(T0.typeValue, forKey: .type) 88 | try value.encode(to: encoder) 89 | case .type1(let value): 90 | try typeContainer.encode(T1.typeValue, forKey: .type) 91 | try value.encode(to: encoder) 92 | } 93 | } 94 | } 95 | 96 | extension Union2: Decodable where T0: UnionDecodable, T1: UnionDecodable { 97 | public init(from decoder: Decoder) throws { 98 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 99 | 100 | let typeValue = try container.decode(String.self, forKey: .type) 101 | let defID = try LexiconDefinitionID(string: typeValue) 102 | switch defID { 103 | case T0.typeValue: 104 | self = .type0(try T0(from: decoder)) 105 | case T1.typeValue: 106 | self = .type1(try T1(from: decoder)) 107 | default: 108 | throw DecodingError.dataCorrupted( 109 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 110 | ) 111 | } 112 | } 113 | } 114 | 115 | extension Union2: Equatable where T0: Equatable, T1: Equatable {} 116 | extension Union2: Hashable where T0: Hashable, T1: Hashable {} 117 | 118 | 119 | // Union3 120 | 121 | public enum Union3 { 122 | 123 | case type0(T0) 124 | case type1(T1) 125 | case type2(T2) 126 | 127 | public var asType0: T0? { 128 | guard case .type0(let value) = self else { 129 | return nil 130 | } 131 | return value 132 | } 133 | public var asType1: T1? { 134 | guard case .type1(let value) = self else { 135 | return nil 136 | } 137 | return value 138 | } 139 | public var asType2: T2? { 140 | guard case .type2(let value) = self else { 141 | return nil 142 | } 143 | return value 144 | } 145 | 146 | } 147 | 148 | extension Union3: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable { 149 | public func encode(to encoder: Encoder) throws { 150 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 151 | 152 | switch self { 153 | case .type0(let value): 154 | try typeContainer.encode(T0.typeValue, forKey: .type) 155 | try value.encode(to: encoder) 156 | case .type1(let value): 157 | try typeContainer.encode(T1.typeValue, forKey: .type) 158 | try value.encode(to: encoder) 159 | case .type2(let value): 160 | try typeContainer.encode(T2.typeValue, forKey: .type) 161 | try value.encode(to: encoder) 162 | } 163 | } 164 | } 165 | 166 | extension Union3: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable { 167 | public init(from decoder: Decoder) throws { 168 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 169 | 170 | let typeValue = try container.decode(String.self, forKey: .type) 171 | let defID = try LexiconDefinitionID(string: typeValue) 172 | switch defID { 173 | case T0.typeValue: 174 | self = .type0(try T0(from: decoder)) 175 | case T1.typeValue: 176 | self = .type1(try T1(from: decoder)) 177 | case T2.typeValue: 178 | self = .type2(try T2(from: decoder)) 179 | default: 180 | throw DecodingError.dataCorrupted( 181 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 182 | ) 183 | } 184 | } 185 | } 186 | 187 | extension Union3: Equatable where T0: Equatable, T1: Equatable, T2: Equatable {} 188 | extension Union3: Hashable where T0: Hashable, T1: Hashable, T2: Hashable {} 189 | 190 | 191 | // Union4 192 | 193 | public enum Union4 { 194 | 195 | case type0(T0) 196 | case type1(T1) 197 | case type2(T2) 198 | case type3(T3) 199 | 200 | public var asType0: T0? { 201 | guard case .type0(let value) = self else { 202 | return nil 203 | } 204 | return value 205 | } 206 | public var asType1: T1? { 207 | guard case .type1(let value) = self else { 208 | return nil 209 | } 210 | return value 211 | } 212 | public var asType2: T2? { 213 | guard case .type2(let value) = self else { 214 | return nil 215 | } 216 | return value 217 | } 218 | public var asType3: T3? { 219 | guard case .type3(let value) = self else { 220 | return nil 221 | } 222 | return value 223 | } 224 | 225 | } 226 | 227 | extension Union4: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable { 228 | public func encode(to encoder: Encoder) throws { 229 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 230 | 231 | switch self { 232 | case .type0(let value): 233 | try typeContainer.encode(T0.typeValue, forKey: .type) 234 | try value.encode(to: encoder) 235 | case .type1(let value): 236 | try typeContainer.encode(T1.typeValue, forKey: .type) 237 | try value.encode(to: encoder) 238 | case .type2(let value): 239 | try typeContainer.encode(T2.typeValue, forKey: .type) 240 | try value.encode(to: encoder) 241 | case .type3(let value): 242 | try typeContainer.encode(T3.typeValue, forKey: .type) 243 | try value.encode(to: encoder) 244 | } 245 | } 246 | } 247 | 248 | extension Union4: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable { 249 | public init(from decoder: Decoder) throws { 250 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 251 | 252 | let typeValue = try container.decode(String.self, forKey: .type) 253 | let defID = try LexiconDefinitionID(string: typeValue) 254 | switch defID { 255 | case T0.typeValue: 256 | self = .type0(try T0(from: decoder)) 257 | case T1.typeValue: 258 | self = .type1(try T1(from: decoder)) 259 | case T2.typeValue: 260 | self = .type2(try T2(from: decoder)) 261 | case T3.typeValue: 262 | self = .type3(try T3(from: decoder)) 263 | default: 264 | throw DecodingError.dataCorrupted( 265 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 266 | ) 267 | } 268 | } 269 | } 270 | 271 | extension Union4: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable {} 272 | extension Union4: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable {} 273 | 274 | 275 | // Union5 276 | 277 | public enum Union5 { 278 | 279 | case type0(T0) 280 | case type1(T1) 281 | case type2(T2) 282 | case type3(T3) 283 | case type4(T4) 284 | 285 | public var asType0: T0? { 286 | guard case .type0(let value) = self else { 287 | return nil 288 | } 289 | return value 290 | } 291 | public var asType1: T1? { 292 | guard case .type1(let value) = self else { 293 | return nil 294 | } 295 | return value 296 | } 297 | public var asType2: T2? { 298 | guard case .type2(let value) = self else { 299 | return nil 300 | } 301 | return value 302 | } 303 | public var asType3: T3? { 304 | guard case .type3(let value) = self else { 305 | return nil 306 | } 307 | return value 308 | } 309 | public var asType4: T4? { 310 | guard case .type4(let value) = self else { 311 | return nil 312 | } 313 | return value 314 | } 315 | 316 | } 317 | 318 | extension Union5: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable { 319 | public func encode(to encoder: Encoder) throws { 320 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 321 | 322 | switch self { 323 | case .type0(let value): 324 | try typeContainer.encode(T0.typeValue, forKey: .type) 325 | try value.encode(to: encoder) 326 | case .type1(let value): 327 | try typeContainer.encode(T1.typeValue, forKey: .type) 328 | try value.encode(to: encoder) 329 | case .type2(let value): 330 | try typeContainer.encode(T2.typeValue, forKey: .type) 331 | try value.encode(to: encoder) 332 | case .type3(let value): 333 | try typeContainer.encode(T3.typeValue, forKey: .type) 334 | try value.encode(to: encoder) 335 | case .type4(let value): 336 | try typeContainer.encode(T4.typeValue, forKey: .type) 337 | try value.encode(to: encoder) 338 | } 339 | } 340 | } 341 | 342 | extension Union5: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable { 343 | public init(from decoder: Decoder) throws { 344 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 345 | 346 | let typeValue = try container.decode(String.self, forKey: .type) 347 | let defID = try LexiconDefinitionID(string: typeValue) 348 | switch defID { 349 | case T0.typeValue: 350 | self = .type0(try T0(from: decoder)) 351 | case T1.typeValue: 352 | self = .type1(try T1(from: decoder)) 353 | case T2.typeValue: 354 | self = .type2(try T2(from: decoder)) 355 | case T3.typeValue: 356 | self = .type3(try T3(from: decoder)) 357 | case T4.typeValue: 358 | self = .type4(try T4(from: decoder)) 359 | default: 360 | throw DecodingError.dataCorrupted( 361 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 362 | ) 363 | } 364 | } 365 | } 366 | 367 | extension Union5: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable {} 368 | extension Union5: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable {} 369 | 370 | 371 | // Union6 372 | 373 | public enum Union6 { 374 | 375 | case type0(T0) 376 | case type1(T1) 377 | case type2(T2) 378 | case type3(T3) 379 | case type4(T4) 380 | case type5(T5) 381 | 382 | public var asType0: T0? { 383 | guard case .type0(let value) = self else { 384 | return nil 385 | } 386 | return value 387 | } 388 | public var asType1: T1? { 389 | guard case .type1(let value) = self else { 390 | return nil 391 | } 392 | return value 393 | } 394 | public var asType2: T2? { 395 | guard case .type2(let value) = self else { 396 | return nil 397 | } 398 | return value 399 | } 400 | public var asType3: T3? { 401 | guard case .type3(let value) = self else { 402 | return nil 403 | } 404 | return value 405 | } 406 | public var asType4: T4? { 407 | guard case .type4(let value) = self else { 408 | return nil 409 | } 410 | return value 411 | } 412 | public var asType5: T5? { 413 | guard case .type5(let value) = self else { 414 | return nil 415 | } 416 | return value 417 | } 418 | 419 | } 420 | 421 | extension Union6: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable { 422 | public func encode(to encoder: Encoder) throws { 423 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 424 | 425 | switch self { 426 | case .type0(let value): 427 | try typeContainer.encode(T0.typeValue, forKey: .type) 428 | try value.encode(to: encoder) 429 | case .type1(let value): 430 | try typeContainer.encode(T1.typeValue, forKey: .type) 431 | try value.encode(to: encoder) 432 | case .type2(let value): 433 | try typeContainer.encode(T2.typeValue, forKey: .type) 434 | try value.encode(to: encoder) 435 | case .type3(let value): 436 | try typeContainer.encode(T3.typeValue, forKey: .type) 437 | try value.encode(to: encoder) 438 | case .type4(let value): 439 | try typeContainer.encode(T4.typeValue, forKey: .type) 440 | try value.encode(to: encoder) 441 | case .type5(let value): 442 | try typeContainer.encode(T5.typeValue, forKey: .type) 443 | try value.encode(to: encoder) 444 | } 445 | } 446 | } 447 | 448 | extension Union6: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable { 449 | public init(from decoder: Decoder) throws { 450 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 451 | 452 | let typeValue = try container.decode(String.self, forKey: .type) 453 | let defID = try LexiconDefinitionID(string: typeValue) 454 | switch defID { 455 | case T0.typeValue: 456 | self = .type0(try T0(from: decoder)) 457 | case T1.typeValue: 458 | self = .type1(try T1(from: decoder)) 459 | case T2.typeValue: 460 | self = .type2(try T2(from: decoder)) 461 | case T3.typeValue: 462 | self = .type3(try T3(from: decoder)) 463 | case T4.typeValue: 464 | self = .type4(try T4(from: decoder)) 465 | case T5.typeValue: 466 | self = .type5(try T5(from: decoder)) 467 | default: 468 | throw DecodingError.dataCorrupted( 469 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 470 | ) 471 | } 472 | } 473 | } 474 | 475 | extension Union6: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable {} 476 | extension Union6: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable {} 477 | 478 | 479 | // Union7 480 | 481 | public enum Union7 { 482 | 483 | case type0(T0) 484 | case type1(T1) 485 | case type2(T2) 486 | case type3(T3) 487 | case type4(T4) 488 | case type5(T5) 489 | case type6(T6) 490 | 491 | public var asType0: T0? { 492 | guard case .type0(let value) = self else { 493 | return nil 494 | } 495 | return value 496 | } 497 | public var asType1: T1? { 498 | guard case .type1(let value) = self else { 499 | return nil 500 | } 501 | return value 502 | } 503 | public var asType2: T2? { 504 | guard case .type2(let value) = self else { 505 | return nil 506 | } 507 | return value 508 | } 509 | public var asType3: T3? { 510 | guard case .type3(let value) = self else { 511 | return nil 512 | } 513 | return value 514 | } 515 | public var asType4: T4? { 516 | guard case .type4(let value) = self else { 517 | return nil 518 | } 519 | return value 520 | } 521 | public var asType5: T5? { 522 | guard case .type5(let value) = self else { 523 | return nil 524 | } 525 | return value 526 | } 527 | public var asType6: T6? { 528 | guard case .type6(let value) = self else { 529 | return nil 530 | } 531 | return value 532 | } 533 | 534 | } 535 | 536 | extension Union7: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable { 537 | public func encode(to encoder: Encoder) throws { 538 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 539 | 540 | switch self { 541 | case .type0(let value): 542 | try typeContainer.encode(T0.typeValue, forKey: .type) 543 | try value.encode(to: encoder) 544 | case .type1(let value): 545 | try typeContainer.encode(T1.typeValue, forKey: .type) 546 | try value.encode(to: encoder) 547 | case .type2(let value): 548 | try typeContainer.encode(T2.typeValue, forKey: .type) 549 | try value.encode(to: encoder) 550 | case .type3(let value): 551 | try typeContainer.encode(T3.typeValue, forKey: .type) 552 | try value.encode(to: encoder) 553 | case .type4(let value): 554 | try typeContainer.encode(T4.typeValue, forKey: .type) 555 | try value.encode(to: encoder) 556 | case .type5(let value): 557 | try typeContainer.encode(T5.typeValue, forKey: .type) 558 | try value.encode(to: encoder) 559 | case .type6(let value): 560 | try typeContainer.encode(T6.typeValue, forKey: .type) 561 | try value.encode(to: encoder) 562 | } 563 | } 564 | } 565 | 566 | extension Union7: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable { 567 | public init(from decoder: Decoder) throws { 568 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 569 | 570 | let typeValue = try container.decode(String.self, forKey: .type) 571 | let defID = try LexiconDefinitionID(string: typeValue) 572 | switch defID { 573 | case T0.typeValue: 574 | self = .type0(try T0(from: decoder)) 575 | case T1.typeValue: 576 | self = .type1(try T1(from: decoder)) 577 | case T2.typeValue: 578 | self = .type2(try T2(from: decoder)) 579 | case T3.typeValue: 580 | self = .type3(try T3(from: decoder)) 581 | case T4.typeValue: 582 | self = .type4(try T4(from: decoder)) 583 | case T5.typeValue: 584 | self = .type5(try T5(from: decoder)) 585 | case T6.typeValue: 586 | self = .type6(try T6(from: decoder)) 587 | default: 588 | throw DecodingError.dataCorrupted( 589 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 590 | ) 591 | } 592 | } 593 | } 594 | 595 | extension Union7: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable {} 596 | extension Union7: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable {} 597 | 598 | 599 | // Union8 600 | 601 | public enum Union8 { 602 | 603 | case type0(T0) 604 | case type1(T1) 605 | case type2(T2) 606 | case type3(T3) 607 | case type4(T4) 608 | case type5(T5) 609 | case type6(T6) 610 | case type7(T7) 611 | 612 | public var asType0: T0? { 613 | guard case .type0(let value) = self else { 614 | return nil 615 | } 616 | return value 617 | } 618 | public var asType1: T1? { 619 | guard case .type1(let value) = self else { 620 | return nil 621 | } 622 | return value 623 | } 624 | public var asType2: T2? { 625 | guard case .type2(let value) = self else { 626 | return nil 627 | } 628 | return value 629 | } 630 | public var asType3: T3? { 631 | guard case .type3(let value) = self else { 632 | return nil 633 | } 634 | return value 635 | } 636 | public var asType4: T4? { 637 | guard case .type4(let value) = self else { 638 | return nil 639 | } 640 | return value 641 | } 642 | public var asType5: T5? { 643 | guard case .type5(let value) = self else { 644 | return nil 645 | } 646 | return value 647 | } 648 | public var asType6: T6? { 649 | guard case .type6(let value) = self else { 650 | return nil 651 | } 652 | return value 653 | } 654 | public var asType7: T7? { 655 | guard case .type7(let value) = self else { 656 | return nil 657 | } 658 | return value 659 | } 660 | 661 | } 662 | 663 | extension Union8: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable { 664 | public func encode(to encoder: Encoder) throws { 665 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 666 | 667 | switch self { 668 | case .type0(let value): 669 | try typeContainer.encode(T0.typeValue, forKey: .type) 670 | try value.encode(to: encoder) 671 | case .type1(let value): 672 | try typeContainer.encode(T1.typeValue, forKey: .type) 673 | try value.encode(to: encoder) 674 | case .type2(let value): 675 | try typeContainer.encode(T2.typeValue, forKey: .type) 676 | try value.encode(to: encoder) 677 | case .type3(let value): 678 | try typeContainer.encode(T3.typeValue, forKey: .type) 679 | try value.encode(to: encoder) 680 | case .type4(let value): 681 | try typeContainer.encode(T4.typeValue, forKey: .type) 682 | try value.encode(to: encoder) 683 | case .type5(let value): 684 | try typeContainer.encode(T5.typeValue, forKey: .type) 685 | try value.encode(to: encoder) 686 | case .type6(let value): 687 | try typeContainer.encode(T6.typeValue, forKey: .type) 688 | try value.encode(to: encoder) 689 | case .type7(let value): 690 | try typeContainer.encode(T7.typeValue, forKey: .type) 691 | try value.encode(to: encoder) 692 | } 693 | } 694 | } 695 | 696 | extension Union8: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable { 697 | public init(from decoder: Decoder) throws { 698 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 699 | 700 | let typeValue = try container.decode(String.self, forKey: .type) 701 | let defID = try LexiconDefinitionID(string: typeValue) 702 | switch defID { 703 | case T0.typeValue: 704 | self = .type0(try T0(from: decoder)) 705 | case T1.typeValue: 706 | self = .type1(try T1(from: decoder)) 707 | case T2.typeValue: 708 | self = .type2(try T2(from: decoder)) 709 | case T3.typeValue: 710 | self = .type3(try T3(from: decoder)) 711 | case T4.typeValue: 712 | self = .type4(try T4(from: decoder)) 713 | case T5.typeValue: 714 | self = .type5(try T5(from: decoder)) 715 | case T6.typeValue: 716 | self = .type6(try T6(from: decoder)) 717 | case T7.typeValue: 718 | self = .type7(try T7(from: decoder)) 719 | default: 720 | throw DecodingError.dataCorrupted( 721 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 722 | ) 723 | } 724 | } 725 | } 726 | 727 | extension Union8: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable {} 728 | extension Union8: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable {} 729 | 730 | 731 | // Union9 732 | 733 | public enum Union9 { 734 | 735 | case type0(T0) 736 | case type1(T1) 737 | case type2(T2) 738 | case type3(T3) 739 | case type4(T4) 740 | case type5(T5) 741 | case type6(T6) 742 | case type7(T7) 743 | case type8(T8) 744 | 745 | public var asType0: T0? { 746 | guard case .type0(let value) = self else { 747 | return nil 748 | } 749 | return value 750 | } 751 | public var asType1: T1? { 752 | guard case .type1(let value) = self else { 753 | return nil 754 | } 755 | return value 756 | } 757 | public var asType2: T2? { 758 | guard case .type2(let value) = self else { 759 | return nil 760 | } 761 | return value 762 | } 763 | public var asType3: T3? { 764 | guard case .type3(let value) = self else { 765 | return nil 766 | } 767 | return value 768 | } 769 | public var asType4: T4? { 770 | guard case .type4(let value) = self else { 771 | return nil 772 | } 773 | return value 774 | } 775 | public var asType5: T5? { 776 | guard case .type5(let value) = self else { 777 | return nil 778 | } 779 | return value 780 | } 781 | public var asType6: T6? { 782 | guard case .type6(let value) = self else { 783 | return nil 784 | } 785 | return value 786 | } 787 | public var asType7: T7? { 788 | guard case .type7(let value) = self else { 789 | return nil 790 | } 791 | return value 792 | } 793 | public var asType8: T8? { 794 | guard case .type8(let value) = self else { 795 | return nil 796 | } 797 | return value 798 | } 799 | 800 | } 801 | 802 | extension Union9: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable { 803 | public func encode(to encoder: Encoder) throws { 804 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 805 | 806 | switch self { 807 | case .type0(let value): 808 | try typeContainer.encode(T0.typeValue, forKey: .type) 809 | try value.encode(to: encoder) 810 | case .type1(let value): 811 | try typeContainer.encode(T1.typeValue, forKey: .type) 812 | try value.encode(to: encoder) 813 | case .type2(let value): 814 | try typeContainer.encode(T2.typeValue, forKey: .type) 815 | try value.encode(to: encoder) 816 | case .type3(let value): 817 | try typeContainer.encode(T3.typeValue, forKey: .type) 818 | try value.encode(to: encoder) 819 | case .type4(let value): 820 | try typeContainer.encode(T4.typeValue, forKey: .type) 821 | try value.encode(to: encoder) 822 | case .type5(let value): 823 | try typeContainer.encode(T5.typeValue, forKey: .type) 824 | try value.encode(to: encoder) 825 | case .type6(let value): 826 | try typeContainer.encode(T6.typeValue, forKey: .type) 827 | try value.encode(to: encoder) 828 | case .type7(let value): 829 | try typeContainer.encode(T7.typeValue, forKey: .type) 830 | try value.encode(to: encoder) 831 | case .type8(let value): 832 | try typeContainer.encode(T8.typeValue, forKey: .type) 833 | try value.encode(to: encoder) 834 | } 835 | } 836 | } 837 | 838 | extension Union9: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable { 839 | public init(from decoder: Decoder) throws { 840 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 841 | 842 | let typeValue = try container.decode(String.self, forKey: .type) 843 | let defID = try LexiconDefinitionID(string: typeValue) 844 | switch defID { 845 | case T0.typeValue: 846 | self = .type0(try T0(from: decoder)) 847 | case T1.typeValue: 848 | self = .type1(try T1(from: decoder)) 849 | case T2.typeValue: 850 | self = .type2(try T2(from: decoder)) 851 | case T3.typeValue: 852 | self = .type3(try T3(from: decoder)) 853 | case T4.typeValue: 854 | self = .type4(try T4(from: decoder)) 855 | case T5.typeValue: 856 | self = .type5(try T5(from: decoder)) 857 | case T6.typeValue: 858 | self = .type6(try T6(from: decoder)) 859 | case T7.typeValue: 860 | self = .type7(try T7(from: decoder)) 861 | case T8.typeValue: 862 | self = .type8(try T8(from: decoder)) 863 | default: 864 | throw DecodingError.dataCorrupted( 865 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 866 | ) 867 | } 868 | } 869 | } 870 | 871 | extension Union9: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable {} 872 | extension Union9: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable {} 873 | 874 | 875 | // Union10 876 | 877 | public enum Union10 { 878 | 879 | case type0(T0) 880 | case type1(T1) 881 | case type2(T2) 882 | case type3(T3) 883 | case type4(T4) 884 | case type5(T5) 885 | case type6(T6) 886 | case type7(T7) 887 | case type8(T8) 888 | case type9(T9) 889 | 890 | public var asType0: T0? { 891 | guard case .type0(let value) = self else { 892 | return nil 893 | } 894 | return value 895 | } 896 | public var asType1: T1? { 897 | guard case .type1(let value) = self else { 898 | return nil 899 | } 900 | return value 901 | } 902 | public var asType2: T2? { 903 | guard case .type2(let value) = self else { 904 | return nil 905 | } 906 | return value 907 | } 908 | public var asType3: T3? { 909 | guard case .type3(let value) = self else { 910 | return nil 911 | } 912 | return value 913 | } 914 | public var asType4: T4? { 915 | guard case .type4(let value) = self else { 916 | return nil 917 | } 918 | return value 919 | } 920 | public var asType5: T5? { 921 | guard case .type5(let value) = self else { 922 | return nil 923 | } 924 | return value 925 | } 926 | public var asType6: T6? { 927 | guard case .type6(let value) = self else { 928 | return nil 929 | } 930 | return value 931 | } 932 | public var asType7: T7? { 933 | guard case .type7(let value) = self else { 934 | return nil 935 | } 936 | return value 937 | } 938 | public var asType8: T8? { 939 | guard case .type8(let value) = self else { 940 | return nil 941 | } 942 | return value 943 | } 944 | public var asType9: T9? { 945 | guard case .type9(let value) = self else { 946 | return nil 947 | } 948 | return value 949 | } 950 | 951 | } 952 | 953 | extension Union10: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable { 954 | public func encode(to encoder: Encoder) throws { 955 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 956 | 957 | switch self { 958 | case .type0(let value): 959 | try typeContainer.encode(T0.typeValue, forKey: .type) 960 | try value.encode(to: encoder) 961 | case .type1(let value): 962 | try typeContainer.encode(T1.typeValue, forKey: .type) 963 | try value.encode(to: encoder) 964 | case .type2(let value): 965 | try typeContainer.encode(T2.typeValue, forKey: .type) 966 | try value.encode(to: encoder) 967 | case .type3(let value): 968 | try typeContainer.encode(T3.typeValue, forKey: .type) 969 | try value.encode(to: encoder) 970 | case .type4(let value): 971 | try typeContainer.encode(T4.typeValue, forKey: .type) 972 | try value.encode(to: encoder) 973 | case .type5(let value): 974 | try typeContainer.encode(T5.typeValue, forKey: .type) 975 | try value.encode(to: encoder) 976 | case .type6(let value): 977 | try typeContainer.encode(T6.typeValue, forKey: .type) 978 | try value.encode(to: encoder) 979 | case .type7(let value): 980 | try typeContainer.encode(T7.typeValue, forKey: .type) 981 | try value.encode(to: encoder) 982 | case .type8(let value): 983 | try typeContainer.encode(T8.typeValue, forKey: .type) 984 | try value.encode(to: encoder) 985 | case .type9(let value): 986 | try typeContainer.encode(T9.typeValue, forKey: .type) 987 | try value.encode(to: encoder) 988 | } 989 | } 990 | } 991 | 992 | extension Union10: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable { 993 | public init(from decoder: Decoder) throws { 994 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 995 | 996 | let typeValue = try container.decode(String.self, forKey: .type) 997 | let defID = try LexiconDefinitionID(string: typeValue) 998 | switch defID { 999 | case T0.typeValue: 1000 | self = .type0(try T0(from: decoder)) 1001 | case T1.typeValue: 1002 | self = .type1(try T1(from: decoder)) 1003 | case T2.typeValue: 1004 | self = .type2(try T2(from: decoder)) 1005 | case T3.typeValue: 1006 | self = .type3(try T3(from: decoder)) 1007 | case T4.typeValue: 1008 | self = .type4(try T4(from: decoder)) 1009 | case T5.typeValue: 1010 | self = .type5(try T5(from: decoder)) 1011 | case T6.typeValue: 1012 | self = .type6(try T6(from: decoder)) 1013 | case T7.typeValue: 1014 | self = .type7(try T7(from: decoder)) 1015 | case T8.typeValue: 1016 | self = .type8(try T8(from: decoder)) 1017 | case T9.typeValue: 1018 | self = .type9(try T9(from: decoder)) 1019 | default: 1020 | throw DecodingError.dataCorrupted( 1021 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 1022 | ) 1023 | } 1024 | } 1025 | } 1026 | 1027 | extension Union10: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable {} 1028 | extension Union10: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable {} 1029 | 1030 | 1031 | // Union11 1032 | 1033 | public enum Union11 { 1034 | 1035 | case type0(T0) 1036 | case type1(T1) 1037 | case type2(T2) 1038 | case type3(T3) 1039 | case type4(T4) 1040 | case type5(T5) 1041 | case type6(T6) 1042 | case type7(T7) 1043 | case type8(T8) 1044 | case type9(T9) 1045 | case type10(T10) 1046 | 1047 | public var asType0: T0? { 1048 | guard case .type0(let value) = self else { 1049 | return nil 1050 | } 1051 | return value 1052 | } 1053 | public var asType1: T1? { 1054 | guard case .type1(let value) = self else { 1055 | return nil 1056 | } 1057 | return value 1058 | } 1059 | public var asType2: T2? { 1060 | guard case .type2(let value) = self else { 1061 | return nil 1062 | } 1063 | return value 1064 | } 1065 | public var asType3: T3? { 1066 | guard case .type3(let value) = self else { 1067 | return nil 1068 | } 1069 | return value 1070 | } 1071 | public var asType4: T4? { 1072 | guard case .type4(let value) = self else { 1073 | return nil 1074 | } 1075 | return value 1076 | } 1077 | public var asType5: T5? { 1078 | guard case .type5(let value) = self else { 1079 | return nil 1080 | } 1081 | return value 1082 | } 1083 | public var asType6: T6? { 1084 | guard case .type6(let value) = self else { 1085 | return nil 1086 | } 1087 | return value 1088 | } 1089 | public var asType7: T7? { 1090 | guard case .type7(let value) = self else { 1091 | return nil 1092 | } 1093 | return value 1094 | } 1095 | public var asType8: T8? { 1096 | guard case .type8(let value) = self else { 1097 | return nil 1098 | } 1099 | return value 1100 | } 1101 | public var asType9: T9? { 1102 | guard case .type9(let value) = self else { 1103 | return nil 1104 | } 1105 | return value 1106 | } 1107 | public var asType10: T10? { 1108 | guard case .type10(let value) = self else { 1109 | return nil 1110 | } 1111 | return value 1112 | } 1113 | 1114 | } 1115 | 1116 | extension Union11: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable { 1117 | public func encode(to encoder: Encoder) throws { 1118 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 1119 | 1120 | switch self { 1121 | case .type0(let value): 1122 | try typeContainer.encode(T0.typeValue, forKey: .type) 1123 | try value.encode(to: encoder) 1124 | case .type1(let value): 1125 | try typeContainer.encode(T1.typeValue, forKey: .type) 1126 | try value.encode(to: encoder) 1127 | case .type2(let value): 1128 | try typeContainer.encode(T2.typeValue, forKey: .type) 1129 | try value.encode(to: encoder) 1130 | case .type3(let value): 1131 | try typeContainer.encode(T3.typeValue, forKey: .type) 1132 | try value.encode(to: encoder) 1133 | case .type4(let value): 1134 | try typeContainer.encode(T4.typeValue, forKey: .type) 1135 | try value.encode(to: encoder) 1136 | case .type5(let value): 1137 | try typeContainer.encode(T5.typeValue, forKey: .type) 1138 | try value.encode(to: encoder) 1139 | case .type6(let value): 1140 | try typeContainer.encode(T6.typeValue, forKey: .type) 1141 | try value.encode(to: encoder) 1142 | case .type7(let value): 1143 | try typeContainer.encode(T7.typeValue, forKey: .type) 1144 | try value.encode(to: encoder) 1145 | case .type8(let value): 1146 | try typeContainer.encode(T8.typeValue, forKey: .type) 1147 | try value.encode(to: encoder) 1148 | case .type9(let value): 1149 | try typeContainer.encode(T9.typeValue, forKey: .type) 1150 | try value.encode(to: encoder) 1151 | case .type10(let value): 1152 | try typeContainer.encode(T10.typeValue, forKey: .type) 1153 | try value.encode(to: encoder) 1154 | } 1155 | } 1156 | } 1157 | 1158 | extension Union11: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable { 1159 | public init(from decoder: Decoder) throws { 1160 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 1161 | 1162 | let typeValue = try container.decode(String.self, forKey: .type) 1163 | let defID = try LexiconDefinitionID(string: typeValue) 1164 | switch defID { 1165 | case T0.typeValue: 1166 | self = .type0(try T0(from: decoder)) 1167 | case T1.typeValue: 1168 | self = .type1(try T1(from: decoder)) 1169 | case T2.typeValue: 1170 | self = .type2(try T2(from: decoder)) 1171 | case T3.typeValue: 1172 | self = .type3(try T3(from: decoder)) 1173 | case T4.typeValue: 1174 | self = .type4(try T4(from: decoder)) 1175 | case T5.typeValue: 1176 | self = .type5(try T5(from: decoder)) 1177 | case T6.typeValue: 1178 | self = .type6(try T6(from: decoder)) 1179 | case T7.typeValue: 1180 | self = .type7(try T7(from: decoder)) 1181 | case T8.typeValue: 1182 | self = .type8(try T8(from: decoder)) 1183 | case T9.typeValue: 1184 | self = .type9(try T9(from: decoder)) 1185 | case T10.typeValue: 1186 | self = .type10(try T10(from: decoder)) 1187 | default: 1188 | throw DecodingError.dataCorrupted( 1189 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 1190 | ) 1191 | } 1192 | } 1193 | } 1194 | 1195 | extension Union11: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable {} 1196 | extension Union11: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable {} 1197 | 1198 | 1199 | // Union12 1200 | 1201 | public enum Union12 { 1202 | 1203 | case type0(T0) 1204 | case type1(T1) 1205 | case type2(T2) 1206 | case type3(T3) 1207 | case type4(T4) 1208 | case type5(T5) 1209 | case type6(T6) 1210 | case type7(T7) 1211 | case type8(T8) 1212 | case type9(T9) 1213 | case type10(T10) 1214 | case type11(T11) 1215 | 1216 | public var asType0: T0? { 1217 | guard case .type0(let value) = self else { 1218 | return nil 1219 | } 1220 | return value 1221 | } 1222 | public var asType1: T1? { 1223 | guard case .type1(let value) = self else { 1224 | return nil 1225 | } 1226 | return value 1227 | } 1228 | public var asType2: T2? { 1229 | guard case .type2(let value) = self else { 1230 | return nil 1231 | } 1232 | return value 1233 | } 1234 | public var asType3: T3? { 1235 | guard case .type3(let value) = self else { 1236 | return nil 1237 | } 1238 | return value 1239 | } 1240 | public var asType4: T4? { 1241 | guard case .type4(let value) = self else { 1242 | return nil 1243 | } 1244 | return value 1245 | } 1246 | public var asType5: T5? { 1247 | guard case .type5(let value) = self else { 1248 | return nil 1249 | } 1250 | return value 1251 | } 1252 | public var asType6: T6? { 1253 | guard case .type6(let value) = self else { 1254 | return nil 1255 | } 1256 | return value 1257 | } 1258 | public var asType7: T7? { 1259 | guard case .type7(let value) = self else { 1260 | return nil 1261 | } 1262 | return value 1263 | } 1264 | public var asType8: T8? { 1265 | guard case .type8(let value) = self else { 1266 | return nil 1267 | } 1268 | return value 1269 | } 1270 | public var asType9: T9? { 1271 | guard case .type9(let value) = self else { 1272 | return nil 1273 | } 1274 | return value 1275 | } 1276 | public var asType10: T10? { 1277 | guard case .type10(let value) = self else { 1278 | return nil 1279 | } 1280 | return value 1281 | } 1282 | public var asType11: T11? { 1283 | guard case .type11(let value) = self else { 1284 | return nil 1285 | } 1286 | return value 1287 | } 1288 | 1289 | } 1290 | 1291 | extension Union12: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable { 1292 | public func encode(to encoder: Encoder) throws { 1293 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 1294 | 1295 | switch self { 1296 | case .type0(let value): 1297 | try typeContainer.encode(T0.typeValue, forKey: .type) 1298 | try value.encode(to: encoder) 1299 | case .type1(let value): 1300 | try typeContainer.encode(T1.typeValue, forKey: .type) 1301 | try value.encode(to: encoder) 1302 | case .type2(let value): 1303 | try typeContainer.encode(T2.typeValue, forKey: .type) 1304 | try value.encode(to: encoder) 1305 | case .type3(let value): 1306 | try typeContainer.encode(T3.typeValue, forKey: .type) 1307 | try value.encode(to: encoder) 1308 | case .type4(let value): 1309 | try typeContainer.encode(T4.typeValue, forKey: .type) 1310 | try value.encode(to: encoder) 1311 | case .type5(let value): 1312 | try typeContainer.encode(T5.typeValue, forKey: .type) 1313 | try value.encode(to: encoder) 1314 | case .type6(let value): 1315 | try typeContainer.encode(T6.typeValue, forKey: .type) 1316 | try value.encode(to: encoder) 1317 | case .type7(let value): 1318 | try typeContainer.encode(T7.typeValue, forKey: .type) 1319 | try value.encode(to: encoder) 1320 | case .type8(let value): 1321 | try typeContainer.encode(T8.typeValue, forKey: .type) 1322 | try value.encode(to: encoder) 1323 | case .type9(let value): 1324 | try typeContainer.encode(T9.typeValue, forKey: .type) 1325 | try value.encode(to: encoder) 1326 | case .type10(let value): 1327 | try typeContainer.encode(T10.typeValue, forKey: .type) 1328 | try value.encode(to: encoder) 1329 | case .type11(let value): 1330 | try typeContainer.encode(T11.typeValue, forKey: .type) 1331 | try value.encode(to: encoder) 1332 | } 1333 | } 1334 | } 1335 | 1336 | extension Union12: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable { 1337 | public init(from decoder: Decoder) throws { 1338 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 1339 | 1340 | let typeValue = try container.decode(String.self, forKey: .type) 1341 | let defID = try LexiconDefinitionID(string: typeValue) 1342 | switch defID { 1343 | case T0.typeValue: 1344 | self = .type0(try T0(from: decoder)) 1345 | case T1.typeValue: 1346 | self = .type1(try T1(from: decoder)) 1347 | case T2.typeValue: 1348 | self = .type2(try T2(from: decoder)) 1349 | case T3.typeValue: 1350 | self = .type3(try T3(from: decoder)) 1351 | case T4.typeValue: 1352 | self = .type4(try T4(from: decoder)) 1353 | case T5.typeValue: 1354 | self = .type5(try T5(from: decoder)) 1355 | case T6.typeValue: 1356 | self = .type6(try T6(from: decoder)) 1357 | case T7.typeValue: 1358 | self = .type7(try T7(from: decoder)) 1359 | case T8.typeValue: 1360 | self = .type8(try T8(from: decoder)) 1361 | case T9.typeValue: 1362 | self = .type9(try T9(from: decoder)) 1363 | case T10.typeValue: 1364 | self = .type10(try T10(from: decoder)) 1365 | case T11.typeValue: 1366 | self = .type11(try T11(from: decoder)) 1367 | default: 1368 | throw DecodingError.dataCorrupted( 1369 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 1370 | ) 1371 | } 1372 | } 1373 | } 1374 | 1375 | extension Union12: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable {} 1376 | extension Union12: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable {} 1377 | 1378 | 1379 | // Union13 1380 | 1381 | public enum Union13 { 1382 | 1383 | case type0(T0) 1384 | case type1(T1) 1385 | case type2(T2) 1386 | case type3(T3) 1387 | case type4(T4) 1388 | case type5(T5) 1389 | case type6(T6) 1390 | case type7(T7) 1391 | case type8(T8) 1392 | case type9(T9) 1393 | case type10(T10) 1394 | case type11(T11) 1395 | case type12(T12) 1396 | 1397 | public var asType0: T0? { 1398 | guard case .type0(let value) = self else { 1399 | return nil 1400 | } 1401 | return value 1402 | } 1403 | public var asType1: T1? { 1404 | guard case .type1(let value) = self else { 1405 | return nil 1406 | } 1407 | return value 1408 | } 1409 | public var asType2: T2? { 1410 | guard case .type2(let value) = self else { 1411 | return nil 1412 | } 1413 | return value 1414 | } 1415 | public var asType3: T3? { 1416 | guard case .type3(let value) = self else { 1417 | return nil 1418 | } 1419 | return value 1420 | } 1421 | public var asType4: T4? { 1422 | guard case .type4(let value) = self else { 1423 | return nil 1424 | } 1425 | return value 1426 | } 1427 | public var asType5: T5? { 1428 | guard case .type5(let value) = self else { 1429 | return nil 1430 | } 1431 | return value 1432 | } 1433 | public var asType6: T6? { 1434 | guard case .type6(let value) = self else { 1435 | return nil 1436 | } 1437 | return value 1438 | } 1439 | public var asType7: T7? { 1440 | guard case .type7(let value) = self else { 1441 | return nil 1442 | } 1443 | return value 1444 | } 1445 | public var asType8: T8? { 1446 | guard case .type8(let value) = self else { 1447 | return nil 1448 | } 1449 | return value 1450 | } 1451 | public var asType9: T9? { 1452 | guard case .type9(let value) = self else { 1453 | return nil 1454 | } 1455 | return value 1456 | } 1457 | public var asType10: T10? { 1458 | guard case .type10(let value) = self else { 1459 | return nil 1460 | } 1461 | return value 1462 | } 1463 | public var asType11: T11? { 1464 | guard case .type11(let value) = self else { 1465 | return nil 1466 | } 1467 | return value 1468 | } 1469 | public var asType12: T12? { 1470 | guard case .type12(let value) = self else { 1471 | return nil 1472 | } 1473 | return value 1474 | } 1475 | 1476 | } 1477 | 1478 | extension Union13: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable { 1479 | public func encode(to encoder: Encoder) throws { 1480 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 1481 | 1482 | switch self { 1483 | case .type0(let value): 1484 | try typeContainer.encode(T0.typeValue, forKey: .type) 1485 | try value.encode(to: encoder) 1486 | case .type1(let value): 1487 | try typeContainer.encode(T1.typeValue, forKey: .type) 1488 | try value.encode(to: encoder) 1489 | case .type2(let value): 1490 | try typeContainer.encode(T2.typeValue, forKey: .type) 1491 | try value.encode(to: encoder) 1492 | case .type3(let value): 1493 | try typeContainer.encode(T3.typeValue, forKey: .type) 1494 | try value.encode(to: encoder) 1495 | case .type4(let value): 1496 | try typeContainer.encode(T4.typeValue, forKey: .type) 1497 | try value.encode(to: encoder) 1498 | case .type5(let value): 1499 | try typeContainer.encode(T5.typeValue, forKey: .type) 1500 | try value.encode(to: encoder) 1501 | case .type6(let value): 1502 | try typeContainer.encode(T6.typeValue, forKey: .type) 1503 | try value.encode(to: encoder) 1504 | case .type7(let value): 1505 | try typeContainer.encode(T7.typeValue, forKey: .type) 1506 | try value.encode(to: encoder) 1507 | case .type8(let value): 1508 | try typeContainer.encode(T8.typeValue, forKey: .type) 1509 | try value.encode(to: encoder) 1510 | case .type9(let value): 1511 | try typeContainer.encode(T9.typeValue, forKey: .type) 1512 | try value.encode(to: encoder) 1513 | case .type10(let value): 1514 | try typeContainer.encode(T10.typeValue, forKey: .type) 1515 | try value.encode(to: encoder) 1516 | case .type11(let value): 1517 | try typeContainer.encode(T11.typeValue, forKey: .type) 1518 | try value.encode(to: encoder) 1519 | case .type12(let value): 1520 | try typeContainer.encode(T12.typeValue, forKey: .type) 1521 | try value.encode(to: encoder) 1522 | } 1523 | } 1524 | } 1525 | 1526 | extension Union13: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable { 1527 | public init(from decoder: Decoder) throws { 1528 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 1529 | 1530 | let typeValue = try container.decode(String.self, forKey: .type) 1531 | let defID = try LexiconDefinitionID(string: typeValue) 1532 | switch defID { 1533 | case T0.typeValue: 1534 | self = .type0(try T0(from: decoder)) 1535 | case T1.typeValue: 1536 | self = .type1(try T1(from: decoder)) 1537 | case T2.typeValue: 1538 | self = .type2(try T2(from: decoder)) 1539 | case T3.typeValue: 1540 | self = .type3(try T3(from: decoder)) 1541 | case T4.typeValue: 1542 | self = .type4(try T4(from: decoder)) 1543 | case T5.typeValue: 1544 | self = .type5(try T5(from: decoder)) 1545 | case T6.typeValue: 1546 | self = .type6(try T6(from: decoder)) 1547 | case T7.typeValue: 1548 | self = .type7(try T7(from: decoder)) 1549 | case T8.typeValue: 1550 | self = .type8(try T8(from: decoder)) 1551 | case T9.typeValue: 1552 | self = .type9(try T9(from: decoder)) 1553 | case T10.typeValue: 1554 | self = .type10(try T10(from: decoder)) 1555 | case T11.typeValue: 1556 | self = .type11(try T11(from: decoder)) 1557 | case T12.typeValue: 1558 | self = .type12(try T12(from: decoder)) 1559 | default: 1560 | throw DecodingError.dataCorrupted( 1561 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 1562 | ) 1563 | } 1564 | } 1565 | } 1566 | 1567 | extension Union13: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable {} 1568 | extension Union13: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable {} 1569 | 1570 | 1571 | // Union14 1572 | 1573 | public enum Union14 { 1574 | 1575 | case type0(T0) 1576 | case type1(T1) 1577 | case type2(T2) 1578 | case type3(T3) 1579 | case type4(T4) 1580 | case type5(T5) 1581 | case type6(T6) 1582 | case type7(T7) 1583 | case type8(T8) 1584 | case type9(T9) 1585 | case type10(T10) 1586 | case type11(T11) 1587 | case type12(T12) 1588 | case type13(T13) 1589 | 1590 | public var asType0: T0? { 1591 | guard case .type0(let value) = self else { 1592 | return nil 1593 | } 1594 | return value 1595 | } 1596 | public var asType1: T1? { 1597 | guard case .type1(let value) = self else { 1598 | return nil 1599 | } 1600 | return value 1601 | } 1602 | public var asType2: T2? { 1603 | guard case .type2(let value) = self else { 1604 | return nil 1605 | } 1606 | return value 1607 | } 1608 | public var asType3: T3? { 1609 | guard case .type3(let value) = self else { 1610 | return nil 1611 | } 1612 | return value 1613 | } 1614 | public var asType4: T4? { 1615 | guard case .type4(let value) = self else { 1616 | return nil 1617 | } 1618 | return value 1619 | } 1620 | public var asType5: T5? { 1621 | guard case .type5(let value) = self else { 1622 | return nil 1623 | } 1624 | return value 1625 | } 1626 | public var asType6: T6? { 1627 | guard case .type6(let value) = self else { 1628 | return nil 1629 | } 1630 | return value 1631 | } 1632 | public var asType7: T7? { 1633 | guard case .type7(let value) = self else { 1634 | return nil 1635 | } 1636 | return value 1637 | } 1638 | public var asType8: T8? { 1639 | guard case .type8(let value) = self else { 1640 | return nil 1641 | } 1642 | return value 1643 | } 1644 | public var asType9: T9? { 1645 | guard case .type9(let value) = self else { 1646 | return nil 1647 | } 1648 | return value 1649 | } 1650 | public var asType10: T10? { 1651 | guard case .type10(let value) = self else { 1652 | return nil 1653 | } 1654 | return value 1655 | } 1656 | public var asType11: T11? { 1657 | guard case .type11(let value) = self else { 1658 | return nil 1659 | } 1660 | return value 1661 | } 1662 | public var asType12: T12? { 1663 | guard case .type12(let value) = self else { 1664 | return nil 1665 | } 1666 | return value 1667 | } 1668 | public var asType13: T13? { 1669 | guard case .type13(let value) = self else { 1670 | return nil 1671 | } 1672 | return value 1673 | } 1674 | 1675 | } 1676 | 1677 | extension Union14: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable, T13: UnionEncodable { 1678 | public func encode(to encoder: Encoder) throws { 1679 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 1680 | 1681 | switch self { 1682 | case .type0(let value): 1683 | try typeContainer.encode(T0.typeValue, forKey: .type) 1684 | try value.encode(to: encoder) 1685 | case .type1(let value): 1686 | try typeContainer.encode(T1.typeValue, forKey: .type) 1687 | try value.encode(to: encoder) 1688 | case .type2(let value): 1689 | try typeContainer.encode(T2.typeValue, forKey: .type) 1690 | try value.encode(to: encoder) 1691 | case .type3(let value): 1692 | try typeContainer.encode(T3.typeValue, forKey: .type) 1693 | try value.encode(to: encoder) 1694 | case .type4(let value): 1695 | try typeContainer.encode(T4.typeValue, forKey: .type) 1696 | try value.encode(to: encoder) 1697 | case .type5(let value): 1698 | try typeContainer.encode(T5.typeValue, forKey: .type) 1699 | try value.encode(to: encoder) 1700 | case .type6(let value): 1701 | try typeContainer.encode(T6.typeValue, forKey: .type) 1702 | try value.encode(to: encoder) 1703 | case .type7(let value): 1704 | try typeContainer.encode(T7.typeValue, forKey: .type) 1705 | try value.encode(to: encoder) 1706 | case .type8(let value): 1707 | try typeContainer.encode(T8.typeValue, forKey: .type) 1708 | try value.encode(to: encoder) 1709 | case .type9(let value): 1710 | try typeContainer.encode(T9.typeValue, forKey: .type) 1711 | try value.encode(to: encoder) 1712 | case .type10(let value): 1713 | try typeContainer.encode(T10.typeValue, forKey: .type) 1714 | try value.encode(to: encoder) 1715 | case .type11(let value): 1716 | try typeContainer.encode(T11.typeValue, forKey: .type) 1717 | try value.encode(to: encoder) 1718 | case .type12(let value): 1719 | try typeContainer.encode(T12.typeValue, forKey: .type) 1720 | try value.encode(to: encoder) 1721 | case .type13(let value): 1722 | try typeContainer.encode(T13.typeValue, forKey: .type) 1723 | try value.encode(to: encoder) 1724 | } 1725 | } 1726 | } 1727 | 1728 | extension Union14: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable, T13: UnionDecodable { 1729 | public init(from decoder: Decoder) throws { 1730 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 1731 | 1732 | let typeValue = try container.decode(String.self, forKey: .type) 1733 | let defID = try LexiconDefinitionID(string: typeValue) 1734 | switch defID { 1735 | case T0.typeValue: 1736 | self = .type0(try T0(from: decoder)) 1737 | case T1.typeValue: 1738 | self = .type1(try T1(from: decoder)) 1739 | case T2.typeValue: 1740 | self = .type2(try T2(from: decoder)) 1741 | case T3.typeValue: 1742 | self = .type3(try T3(from: decoder)) 1743 | case T4.typeValue: 1744 | self = .type4(try T4(from: decoder)) 1745 | case T5.typeValue: 1746 | self = .type5(try T5(from: decoder)) 1747 | case T6.typeValue: 1748 | self = .type6(try T6(from: decoder)) 1749 | case T7.typeValue: 1750 | self = .type7(try T7(from: decoder)) 1751 | case T8.typeValue: 1752 | self = .type8(try T8(from: decoder)) 1753 | case T9.typeValue: 1754 | self = .type9(try T9(from: decoder)) 1755 | case T10.typeValue: 1756 | self = .type10(try T10(from: decoder)) 1757 | case T11.typeValue: 1758 | self = .type11(try T11(from: decoder)) 1759 | case T12.typeValue: 1760 | self = .type12(try T12(from: decoder)) 1761 | case T13.typeValue: 1762 | self = .type13(try T13(from: decoder)) 1763 | default: 1764 | throw DecodingError.dataCorrupted( 1765 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 1766 | ) 1767 | } 1768 | } 1769 | } 1770 | 1771 | extension Union14: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable, T13: Equatable {} 1772 | extension Union14: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable, T13: Hashable {} 1773 | 1774 | 1775 | // Union15 1776 | 1777 | public enum Union15 { 1778 | 1779 | case type0(T0) 1780 | case type1(T1) 1781 | case type2(T2) 1782 | case type3(T3) 1783 | case type4(T4) 1784 | case type5(T5) 1785 | case type6(T6) 1786 | case type7(T7) 1787 | case type8(T8) 1788 | case type9(T9) 1789 | case type10(T10) 1790 | case type11(T11) 1791 | case type12(T12) 1792 | case type13(T13) 1793 | case type14(T14) 1794 | 1795 | public var asType0: T0? { 1796 | guard case .type0(let value) = self else { 1797 | return nil 1798 | } 1799 | return value 1800 | } 1801 | public var asType1: T1? { 1802 | guard case .type1(let value) = self else { 1803 | return nil 1804 | } 1805 | return value 1806 | } 1807 | public var asType2: T2? { 1808 | guard case .type2(let value) = self else { 1809 | return nil 1810 | } 1811 | return value 1812 | } 1813 | public var asType3: T3? { 1814 | guard case .type3(let value) = self else { 1815 | return nil 1816 | } 1817 | return value 1818 | } 1819 | public var asType4: T4? { 1820 | guard case .type4(let value) = self else { 1821 | return nil 1822 | } 1823 | return value 1824 | } 1825 | public var asType5: T5? { 1826 | guard case .type5(let value) = self else { 1827 | return nil 1828 | } 1829 | return value 1830 | } 1831 | public var asType6: T6? { 1832 | guard case .type6(let value) = self else { 1833 | return nil 1834 | } 1835 | return value 1836 | } 1837 | public var asType7: T7? { 1838 | guard case .type7(let value) = self else { 1839 | return nil 1840 | } 1841 | return value 1842 | } 1843 | public var asType8: T8? { 1844 | guard case .type8(let value) = self else { 1845 | return nil 1846 | } 1847 | return value 1848 | } 1849 | public var asType9: T9? { 1850 | guard case .type9(let value) = self else { 1851 | return nil 1852 | } 1853 | return value 1854 | } 1855 | public var asType10: T10? { 1856 | guard case .type10(let value) = self else { 1857 | return nil 1858 | } 1859 | return value 1860 | } 1861 | public var asType11: T11? { 1862 | guard case .type11(let value) = self else { 1863 | return nil 1864 | } 1865 | return value 1866 | } 1867 | public var asType12: T12? { 1868 | guard case .type12(let value) = self else { 1869 | return nil 1870 | } 1871 | return value 1872 | } 1873 | public var asType13: T13? { 1874 | guard case .type13(let value) = self else { 1875 | return nil 1876 | } 1877 | return value 1878 | } 1879 | public var asType14: T14? { 1880 | guard case .type14(let value) = self else { 1881 | return nil 1882 | } 1883 | return value 1884 | } 1885 | 1886 | } 1887 | 1888 | extension Union15: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable, T13: UnionEncodable, T14: UnionEncodable { 1889 | public func encode(to encoder: Encoder) throws { 1890 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 1891 | 1892 | switch self { 1893 | case .type0(let value): 1894 | try typeContainer.encode(T0.typeValue, forKey: .type) 1895 | try value.encode(to: encoder) 1896 | case .type1(let value): 1897 | try typeContainer.encode(T1.typeValue, forKey: .type) 1898 | try value.encode(to: encoder) 1899 | case .type2(let value): 1900 | try typeContainer.encode(T2.typeValue, forKey: .type) 1901 | try value.encode(to: encoder) 1902 | case .type3(let value): 1903 | try typeContainer.encode(T3.typeValue, forKey: .type) 1904 | try value.encode(to: encoder) 1905 | case .type4(let value): 1906 | try typeContainer.encode(T4.typeValue, forKey: .type) 1907 | try value.encode(to: encoder) 1908 | case .type5(let value): 1909 | try typeContainer.encode(T5.typeValue, forKey: .type) 1910 | try value.encode(to: encoder) 1911 | case .type6(let value): 1912 | try typeContainer.encode(T6.typeValue, forKey: .type) 1913 | try value.encode(to: encoder) 1914 | case .type7(let value): 1915 | try typeContainer.encode(T7.typeValue, forKey: .type) 1916 | try value.encode(to: encoder) 1917 | case .type8(let value): 1918 | try typeContainer.encode(T8.typeValue, forKey: .type) 1919 | try value.encode(to: encoder) 1920 | case .type9(let value): 1921 | try typeContainer.encode(T9.typeValue, forKey: .type) 1922 | try value.encode(to: encoder) 1923 | case .type10(let value): 1924 | try typeContainer.encode(T10.typeValue, forKey: .type) 1925 | try value.encode(to: encoder) 1926 | case .type11(let value): 1927 | try typeContainer.encode(T11.typeValue, forKey: .type) 1928 | try value.encode(to: encoder) 1929 | case .type12(let value): 1930 | try typeContainer.encode(T12.typeValue, forKey: .type) 1931 | try value.encode(to: encoder) 1932 | case .type13(let value): 1933 | try typeContainer.encode(T13.typeValue, forKey: .type) 1934 | try value.encode(to: encoder) 1935 | case .type14(let value): 1936 | try typeContainer.encode(T14.typeValue, forKey: .type) 1937 | try value.encode(to: encoder) 1938 | } 1939 | } 1940 | } 1941 | 1942 | extension Union15: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable, T13: UnionDecodable, T14: UnionDecodable { 1943 | public init(from decoder: Decoder) throws { 1944 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 1945 | 1946 | let typeValue = try container.decode(String.self, forKey: .type) 1947 | let defID = try LexiconDefinitionID(string: typeValue) 1948 | switch defID { 1949 | case T0.typeValue: 1950 | self = .type0(try T0(from: decoder)) 1951 | case T1.typeValue: 1952 | self = .type1(try T1(from: decoder)) 1953 | case T2.typeValue: 1954 | self = .type2(try T2(from: decoder)) 1955 | case T3.typeValue: 1956 | self = .type3(try T3(from: decoder)) 1957 | case T4.typeValue: 1958 | self = .type4(try T4(from: decoder)) 1959 | case T5.typeValue: 1960 | self = .type5(try T5(from: decoder)) 1961 | case T6.typeValue: 1962 | self = .type6(try T6(from: decoder)) 1963 | case T7.typeValue: 1964 | self = .type7(try T7(from: decoder)) 1965 | case T8.typeValue: 1966 | self = .type8(try T8(from: decoder)) 1967 | case T9.typeValue: 1968 | self = .type9(try T9(from: decoder)) 1969 | case T10.typeValue: 1970 | self = .type10(try T10(from: decoder)) 1971 | case T11.typeValue: 1972 | self = .type11(try T11(from: decoder)) 1973 | case T12.typeValue: 1974 | self = .type12(try T12(from: decoder)) 1975 | case T13.typeValue: 1976 | self = .type13(try T13(from: decoder)) 1977 | case T14.typeValue: 1978 | self = .type14(try T14(from: decoder)) 1979 | default: 1980 | throw DecodingError.dataCorrupted( 1981 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 1982 | ) 1983 | } 1984 | } 1985 | } 1986 | 1987 | extension Union15: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable, T13: Equatable, T14: Equatable {} 1988 | extension Union15: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable, T13: Hashable, T14: Hashable {} 1989 | 1990 | 1991 | // Union16 1992 | 1993 | public enum Union16 { 1994 | 1995 | case type0(T0) 1996 | case type1(T1) 1997 | case type2(T2) 1998 | case type3(T3) 1999 | case type4(T4) 2000 | case type5(T5) 2001 | case type6(T6) 2002 | case type7(T7) 2003 | case type8(T8) 2004 | case type9(T9) 2005 | case type10(T10) 2006 | case type11(T11) 2007 | case type12(T12) 2008 | case type13(T13) 2009 | case type14(T14) 2010 | case type15(T15) 2011 | 2012 | public var asType0: T0? { 2013 | guard case .type0(let value) = self else { 2014 | return nil 2015 | } 2016 | return value 2017 | } 2018 | public var asType1: T1? { 2019 | guard case .type1(let value) = self else { 2020 | return nil 2021 | } 2022 | return value 2023 | } 2024 | public var asType2: T2? { 2025 | guard case .type2(let value) = self else { 2026 | return nil 2027 | } 2028 | return value 2029 | } 2030 | public var asType3: T3? { 2031 | guard case .type3(let value) = self else { 2032 | return nil 2033 | } 2034 | return value 2035 | } 2036 | public var asType4: T4? { 2037 | guard case .type4(let value) = self else { 2038 | return nil 2039 | } 2040 | return value 2041 | } 2042 | public var asType5: T5? { 2043 | guard case .type5(let value) = self else { 2044 | return nil 2045 | } 2046 | return value 2047 | } 2048 | public var asType6: T6? { 2049 | guard case .type6(let value) = self else { 2050 | return nil 2051 | } 2052 | return value 2053 | } 2054 | public var asType7: T7? { 2055 | guard case .type7(let value) = self else { 2056 | return nil 2057 | } 2058 | return value 2059 | } 2060 | public var asType8: T8? { 2061 | guard case .type8(let value) = self else { 2062 | return nil 2063 | } 2064 | return value 2065 | } 2066 | public var asType9: T9? { 2067 | guard case .type9(let value) = self else { 2068 | return nil 2069 | } 2070 | return value 2071 | } 2072 | public var asType10: T10? { 2073 | guard case .type10(let value) = self else { 2074 | return nil 2075 | } 2076 | return value 2077 | } 2078 | public var asType11: T11? { 2079 | guard case .type11(let value) = self else { 2080 | return nil 2081 | } 2082 | return value 2083 | } 2084 | public var asType12: T12? { 2085 | guard case .type12(let value) = self else { 2086 | return nil 2087 | } 2088 | return value 2089 | } 2090 | public var asType13: T13? { 2091 | guard case .type13(let value) = self else { 2092 | return nil 2093 | } 2094 | return value 2095 | } 2096 | public var asType14: T14? { 2097 | guard case .type14(let value) = self else { 2098 | return nil 2099 | } 2100 | return value 2101 | } 2102 | public var asType15: T15? { 2103 | guard case .type15(let value) = self else { 2104 | return nil 2105 | } 2106 | return value 2107 | } 2108 | 2109 | } 2110 | 2111 | extension Union16: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable, T13: UnionEncodable, T14: UnionEncodable, T15: UnionEncodable { 2112 | public func encode(to encoder: Encoder) throws { 2113 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 2114 | 2115 | switch self { 2116 | case .type0(let value): 2117 | try typeContainer.encode(T0.typeValue, forKey: .type) 2118 | try value.encode(to: encoder) 2119 | case .type1(let value): 2120 | try typeContainer.encode(T1.typeValue, forKey: .type) 2121 | try value.encode(to: encoder) 2122 | case .type2(let value): 2123 | try typeContainer.encode(T2.typeValue, forKey: .type) 2124 | try value.encode(to: encoder) 2125 | case .type3(let value): 2126 | try typeContainer.encode(T3.typeValue, forKey: .type) 2127 | try value.encode(to: encoder) 2128 | case .type4(let value): 2129 | try typeContainer.encode(T4.typeValue, forKey: .type) 2130 | try value.encode(to: encoder) 2131 | case .type5(let value): 2132 | try typeContainer.encode(T5.typeValue, forKey: .type) 2133 | try value.encode(to: encoder) 2134 | case .type6(let value): 2135 | try typeContainer.encode(T6.typeValue, forKey: .type) 2136 | try value.encode(to: encoder) 2137 | case .type7(let value): 2138 | try typeContainer.encode(T7.typeValue, forKey: .type) 2139 | try value.encode(to: encoder) 2140 | case .type8(let value): 2141 | try typeContainer.encode(T8.typeValue, forKey: .type) 2142 | try value.encode(to: encoder) 2143 | case .type9(let value): 2144 | try typeContainer.encode(T9.typeValue, forKey: .type) 2145 | try value.encode(to: encoder) 2146 | case .type10(let value): 2147 | try typeContainer.encode(T10.typeValue, forKey: .type) 2148 | try value.encode(to: encoder) 2149 | case .type11(let value): 2150 | try typeContainer.encode(T11.typeValue, forKey: .type) 2151 | try value.encode(to: encoder) 2152 | case .type12(let value): 2153 | try typeContainer.encode(T12.typeValue, forKey: .type) 2154 | try value.encode(to: encoder) 2155 | case .type13(let value): 2156 | try typeContainer.encode(T13.typeValue, forKey: .type) 2157 | try value.encode(to: encoder) 2158 | case .type14(let value): 2159 | try typeContainer.encode(T14.typeValue, forKey: .type) 2160 | try value.encode(to: encoder) 2161 | case .type15(let value): 2162 | try typeContainer.encode(T15.typeValue, forKey: .type) 2163 | try value.encode(to: encoder) 2164 | } 2165 | } 2166 | } 2167 | 2168 | extension Union16: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable, T13: UnionDecodable, T14: UnionDecodable, T15: UnionDecodable { 2169 | public init(from decoder: Decoder) throws { 2170 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 2171 | 2172 | let typeValue = try container.decode(String.self, forKey: .type) 2173 | let defID = try LexiconDefinitionID(string: typeValue) 2174 | switch defID { 2175 | case T0.typeValue: 2176 | self = .type0(try T0(from: decoder)) 2177 | case T1.typeValue: 2178 | self = .type1(try T1(from: decoder)) 2179 | case T2.typeValue: 2180 | self = .type2(try T2(from: decoder)) 2181 | case T3.typeValue: 2182 | self = .type3(try T3(from: decoder)) 2183 | case T4.typeValue: 2184 | self = .type4(try T4(from: decoder)) 2185 | case T5.typeValue: 2186 | self = .type5(try T5(from: decoder)) 2187 | case T6.typeValue: 2188 | self = .type6(try T6(from: decoder)) 2189 | case T7.typeValue: 2190 | self = .type7(try T7(from: decoder)) 2191 | case T8.typeValue: 2192 | self = .type8(try T8(from: decoder)) 2193 | case T9.typeValue: 2194 | self = .type9(try T9(from: decoder)) 2195 | case T10.typeValue: 2196 | self = .type10(try T10(from: decoder)) 2197 | case T11.typeValue: 2198 | self = .type11(try T11(from: decoder)) 2199 | case T12.typeValue: 2200 | self = .type12(try T12(from: decoder)) 2201 | case T13.typeValue: 2202 | self = .type13(try T13(from: decoder)) 2203 | case T14.typeValue: 2204 | self = .type14(try T14(from: decoder)) 2205 | case T15.typeValue: 2206 | self = .type15(try T15(from: decoder)) 2207 | default: 2208 | throw DecodingError.dataCorrupted( 2209 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 2210 | ) 2211 | } 2212 | } 2213 | } 2214 | 2215 | extension Union16: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable, T13: Equatable, T14: Equatable, T15: Equatable {} 2216 | extension Union16: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable, T13: Hashable, T14: Hashable, T15: Hashable {} 2217 | 2218 | 2219 | // Union17 2220 | 2221 | public enum Union17 { 2222 | 2223 | case type0(T0) 2224 | case type1(T1) 2225 | case type2(T2) 2226 | case type3(T3) 2227 | case type4(T4) 2228 | case type5(T5) 2229 | case type6(T6) 2230 | case type7(T7) 2231 | case type8(T8) 2232 | case type9(T9) 2233 | case type10(T10) 2234 | case type11(T11) 2235 | case type12(T12) 2236 | case type13(T13) 2237 | case type14(T14) 2238 | case type15(T15) 2239 | case type16(T16) 2240 | 2241 | public var asType0: T0? { 2242 | guard case .type0(let value) = self else { 2243 | return nil 2244 | } 2245 | return value 2246 | } 2247 | public var asType1: T1? { 2248 | guard case .type1(let value) = self else { 2249 | return nil 2250 | } 2251 | return value 2252 | } 2253 | public var asType2: T2? { 2254 | guard case .type2(let value) = self else { 2255 | return nil 2256 | } 2257 | return value 2258 | } 2259 | public var asType3: T3? { 2260 | guard case .type3(let value) = self else { 2261 | return nil 2262 | } 2263 | return value 2264 | } 2265 | public var asType4: T4? { 2266 | guard case .type4(let value) = self else { 2267 | return nil 2268 | } 2269 | return value 2270 | } 2271 | public var asType5: T5? { 2272 | guard case .type5(let value) = self else { 2273 | return nil 2274 | } 2275 | return value 2276 | } 2277 | public var asType6: T6? { 2278 | guard case .type6(let value) = self else { 2279 | return nil 2280 | } 2281 | return value 2282 | } 2283 | public var asType7: T7? { 2284 | guard case .type7(let value) = self else { 2285 | return nil 2286 | } 2287 | return value 2288 | } 2289 | public var asType8: T8? { 2290 | guard case .type8(let value) = self else { 2291 | return nil 2292 | } 2293 | return value 2294 | } 2295 | public var asType9: T9? { 2296 | guard case .type9(let value) = self else { 2297 | return nil 2298 | } 2299 | return value 2300 | } 2301 | public var asType10: T10? { 2302 | guard case .type10(let value) = self else { 2303 | return nil 2304 | } 2305 | return value 2306 | } 2307 | public var asType11: T11? { 2308 | guard case .type11(let value) = self else { 2309 | return nil 2310 | } 2311 | return value 2312 | } 2313 | public var asType12: T12? { 2314 | guard case .type12(let value) = self else { 2315 | return nil 2316 | } 2317 | return value 2318 | } 2319 | public var asType13: T13? { 2320 | guard case .type13(let value) = self else { 2321 | return nil 2322 | } 2323 | return value 2324 | } 2325 | public var asType14: T14? { 2326 | guard case .type14(let value) = self else { 2327 | return nil 2328 | } 2329 | return value 2330 | } 2331 | public var asType15: T15? { 2332 | guard case .type15(let value) = self else { 2333 | return nil 2334 | } 2335 | return value 2336 | } 2337 | public var asType16: T16? { 2338 | guard case .type16(let value) = self else { 2339 | return nil 2340 | } 2341 | return value 2342 | } 2343 | 2344 | } 2345 | 2346 | extension Union17: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable, T13: UnionEncodable, T14: UnionEncodable, T15: UnionEncodable, T16: UnionEncodable { 2347 | public func encode(to encoder: Encoder) throws { 2348 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 2349 | 2350 | switch self { 2351 | case .type0(let value): 2352 | try typeContainer.encode(T0.typeValue, forKey: .type) 2353 | try value.encode(to: encoder) 2354 | case .type1(let value): 2355 | try typeContainer.encode(T1.typeValue, forKey: .type) 2356 | try value.encode(to: encoder) 2357 | case .type2(let value): 2358 | try typeContainer.encode(T2.typeValue, forKey: .type) 2359 | try value.encode(to: encoder) 2360 | case .type3(let value): 2361 | try typeContainer.encode(T3.typeValue, forKey: .type) 2362 | try value.encode(to: encoder) 2363 | case .type4(let value): 2364 | try typeContainer.encode(T4.typeValue, forKey: .type) 2365 | try value.encode(to: encoder) 2366 | case .type5(let value): 2367 | try typeContainer.encode(T5.typeValue, forKey: .type) 2368 | try value.encode(to: encoder) 2369 | case .type6(let value): 2370 | try typeContainer.encode(T6.typeValue, forKey: .type) 2371 | try value.encode(to: encoder) 2372 | case .type7(let value): 2373 | try typeContainer.encode(T7.typeValue, forKey: .type) 2374 | try value.encode(to: encoder) 2375 | case .type8(let value): 2376 | try typeContainer.encode(T8.typeValue, forKey: .type) 2377 | try value.encode(to: encoder) 2378 | case .type9(let value): 2379 | try typeContainer.encode(T9.typeValue, forKey: .type) 2380 | try value.encode(to: encoder) 2381 | case .type10(let value): 2382 | try typeContainer.encode(T10.typeValue, forKey: .type) 2383 | try value.encode(to: encoder) 2384 | case .type11(let value): 2385 | try typeContainer.encode(T11.typeValue, forKey: .type) 2386 | try value.encode(to: encoder) 2387 | case .type12(let value): 2388 | try typeContainer.encode(T12.typeValue, forKey: .type) 2389 | try value.encode(to: encoder) 2390 | case .type13(let value): 2391 | try typeContainer.encode(T13.typeValue, forKey: .type) 2392 | try value.encode(to: encoder) 2393 | case .type14(let value): 2394 | try typeContainer.encode(T14.typeValue, forKey: .type) 2395 | try value.encode(to: encoder) 2396 | case .type15(let value): 2397 | try typeContainer.encode(T15.typeValue, forKey: .type) 2398 | try value.encode(to: encoder) 2399 | case .type16(let value): 2400 | try typeContainer.encode(T16.typeValue, forKey: .type) 2401 | try value.encode(to: encoder) 2402 | } 2403 | } 2404 | } 2405 | 2406 | extension Union17: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable, T13: UnionDecodable, T14: UnionDecodable, T15: UnionDecodable, T16: UnionDecodable { 2407 | public init(from decoder: Decoder) throws { 2408 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 2409 | 2410 | let typeValue = try container.decode(String.self, forKey: .type) 2411 | let defID = try LexiconDefinitionID(string: typeValue) 2412 | switch defID { 2413 | case T0.typeValue: 2414 | self = .type0(try T0(from: decoder)) 2415 | case T1.typeValue: 2416 | self = .type1(try T1(from: decoder)) 2417 | case T2.typeValue: 2418 | self = .type2(try T2(from: decoder)) 2419 | case T3.typeValue: 2420 | self = .type3(try T3(from: decoder)) 2421 | case T4.typeValue: 2422 | self = .type4(try T4(from: decoder)) 2423 | case T5.typeValue: 2424 | self = .type5(try T5(from: decoder)) 2425 | case T6.typeValue: 2426 | self = .type6(try T6(from: decoder)) 2427 | case T7.typeValue: 2428 | self = .type7(try T7(from: decoder)) 2429 | case T8.typeValue: 2430 | self = .type8(try T8(from: decoder)) 2431 | case T9.typeValue: 2432 | self = .type9(try T9(from: decoder)) 2433 | case T10.typeValue: 2434 | self = .type10(try T10(from: decoder)) 2435 | case T11.typeValue: 2436 | self = .type11(try T11(from: decoder)) 2437 | case T12.typeValue: 2438 | self = .type12(try T12(from: decoder)) 2439 | case T13.typeValue: 2440 | self = .type13(try T13(from: decoder)) 2441 | case T14.typeValue: 2442 | self = .type14(try T14(from: decoder)) 2443 | case T15.typeValue: 2444 | self = .type15(try T15(from: decoder)) 2445 | case T16.typeValue: 2446 | self = .type16(try T16(from: decoder)) 2447 | default: 2448 | throw DecodingError.dataCorrupted( 2449 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 2450 | ) 2451 | } 2452 | } 2453 | } 2454 | 2455 | extension Union17: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable, T13: Equatable, T14: Equatable, T15: Equatable, T16: Equatable {} 2456 | extension Union17: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable, T13: Hashable, T14: Hashable, T15: Hashable, T16: Hashable {} 2457 | 2458 | 2459 | // Union18 2460 | 2461 | public enum Union18 { 2462 | 2463 | case type0(T0) 2464 | case type1(T1) 2465 | case type2(T2) 2466 | case type3(T3) 2467 | case type4(T4) 2468 | case type5(T5) 2469 | case type6(T6) 2470 | case type7(T7) 2471 | case type8(T8) 2472 | case type9(T9) 2473 | case type10(T10) 2474 | case type11(T11) 2475 | case type12(T12) 2476 | case type13(T13) 2477 | case type14(T14) 2478 | case type15(T15) 2479 | case type16(T16) 2480 | case type17(T17) 2481 | 2482 | public var asType0: T0? { 2483 | guard case .type0(let value) = self else { 2484 | return nil 2485 | } 2486 | return value 2487 | } 2488 | public var asType1: T1? { 2489 | guard case .type1(let value) = self else { 2490 | return nil 2491 | } 2492 | return value 2493 | } 2494 | public var asType2: T2? { 2495 | guard case .type2(let value) = self else { 2496 | return nil 2497 | } 2498 | return value 2499 | } 2500 | public var asType3: T3? { 2501 | guard case .type3(let value) = self else { 2502 | return nil 2503 | } 2504 | return value 2505 | } 2506 | public var asType4: T4? { 2507 | guard case .type4(let value) = self else { 2508 | return nil 2509 | } 2510 | return value 2511 | } 2512 | public var asType5: T5? { 2513 | guard case .type5(let value) = self else { 2514 | return nil 2515 | } 2516 | return value 2517 | } 2518 | public var asType6: T6? { 2519 | guard case .type6(let value) = self else { 2520 | return nil 2521 | } 2522 | return value 2523 | } 2524 | public var asType7: T7? { 2525 | guard case .type7(let value) = self else { 2526 | return nil 2527 | } 2528 | return value 2529 | } 2530 | public var asType8: T8? { 2531 | guard case .type8(let value) = self else { 2532 | return nil 2533 | } 2534 | return value 2535 | } 2536 | public var asType9: T9? { 2537 | guard case .type9(let value) = self else { 2538 | return nil 2539 | } 2540 | return value 2541 | } 2542 | public var asType10: T10? { 2543 | guard case .type10(let value) = self else { 2544 | return nil 2545 | } 2546 | return value 2547 | } 2548 | public var asType11: T11? { 2549 | guard case .type11(let value) = self else { 2550 | return nil 2551 | } 2552 | return value 2553 | } 2554 | public var asType12: T12? { 2555 | guard case .type12(let value) = self else { 2556 | return nil 2557 | } 2558 | return value 2559 | } 2560 | public var asType13: T13? { 2561 | guard case .type13(let value) = self else { 2562 | return nil 2563 | } 2564 | return value 2565 | } 2566 | public var asType14: T14? { 2567 | guard case .type14(let value) = self else { 2568 | return nil 2569 | } 2570 | return value 2571 | } 2572 | public var asType15: T15? { 2573 | guard case .type15(let value) = self else { 2574 | return nil 2575 | } 2576 | return value 2577 | } 2578 | public var asType16: T16? { 2579 | guard case .type16(let value) = self else { 2580 | return nil 2581 | } 2582 | return value 2583 | } 2584 | public var asType17: T17? { 2585 | guard case .type17(let value) = self else { 2586 | return nil 2587 | } 2588 | return value 2589 | } 2590 | 2591 | } 2592 | 2593 | extension Union18: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable, T13: UnionEncodable, T14: UnionEncodable, T15: UnionEncodable, T16: UnionEncodable, T17: UnionEncodable { 2594 | public func encode(to encoder: Encoder) throws { 2595 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 2596 | 2597 | switch self { 2598 | case .type0(let value): 2599 | try typeContainer.encode(T0.typeValue, forKey: .type) 2600 | try value.encode(to: encoder) 2601 | case .type1(let value): 2602 | try typeContainer.encode(T1.typeValue, forKey: .type) 2603 | try value.encode(to: encoder) 2604 | case .type2(let value): 2605 | try typeContainer.encode(T2.typeValue, forKey: .type) 2606 | try value.encode(to: encoder) 2607 | case .type3(let value): 2608 | try typeContainer.encode(T3.typeValue, forKey: .type) 2609 | try value.encode(to: encoder) 2610 | case .type4(let value): 2611 | try typeContainer.encode(T4.typeValue, forKey: .type) 2612 | try value.encode(to: encoder) 2613 | case .type5(let value): 2614 | try typeContainer.encode(T5.typeValue, forKey: .type) 2615 | try value.encode(to: encoder) 2616 | case .type6(let value): 2617 | try typeContainer.encode(T6.typeValue, forKey: .type) 2618 | try value.encode(to: encoder) 2619 | case .type7(let value): 2620 | try typeContainer.encode(T7.typeValue, forKey: .type) 2621 | try value.encode(to: encoder) 2622 | case .type8(let value): 2623 | try typeContainer.encode(T8.typeValue, forKey: .type) 2624 | try value.encode(to: encoder) 2625 | case .type9(let value): 2626 | try typeContainer.encode(T9.typeValue, forKey: .type) 2627 | try value.encode(to: encoder) 2628 | case .type10(let value): 2629 | try typeContainer.encode(T10.typeValue, forKey: .type) 2630 | try value.encode(to: encoder) 2631 | case .type11(let value): 2632 | try typeContainer.encode(T11.typeValue, forKey: .type) 2633 | try value.encode(to: encoder) 2634 | case .type12(let value): 2635 | try typeContainer.encode(T12.typeValue, forKey: .type) 2636 | try value.encode(to: encoder) 2637 | case .type13(let value): 2638 | try typeContainer.encode(T13.typeValue, forKey: .type) 2639 | try value.encode(to: encoder) 2640 | case .type14(let value): 2641 | try typeContainer.encode(T14.typeValue, forKey: .type) 2642 | try value.encode(to: encoder) 2643 | case .type15(let value): 2644 | try typeContainer.encode(T15.typeValue, forKey: .type) 2645 | try value.encode(to: encoder) 2646 | case .type16(let value): 2647 | try typeContainer.encode(T16.typeValue, forKey: .type) 2648 | try value.encode(to: encoder) 2649 | case .type17(let value): 2650 | try typeContainer.encode(T17.typeValue, forKey: .type) 2651 | try value.encode(to: encoder) 2652 | } 2653 | } 2654 | } 2655 | 2656 | extension Union18: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable, T13: UnionDecodable, T14: UnionDecodable, T15: UnionDecodable, T16: UnionDecodable, T17: UnionDecodable { 2657 | public init(from decoder: Decoder) throws { 2658 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 2659 | 2660 | let typeValue = try container.decode(String.self, forKey: .type) 2661 | let defID = try LexiconDefinitionID(string: typeValue) 2662 | switch defID { 2663 | case T0.typeValue: 2664 | self = .type0(try T0(from: decoder)) 2665 | case T1.typeValue: 2666 | self = .type1(try T1(from: decoder)) 2667 | case T2.typeValue: 2668 | self = .type2(try T2(from: decoder)) 2669 | case T3.typeValue: 2670 | self = .type3(try T3(from: decoder)) 2671 | case T4.typeValue: 2672 | self = .type4(try T4(from: decoder)) 2673 | case T5.typeValue: 2674 | self = .type5(try T5(from: decoder)) 2675 | case T6.typeValue: 2676 | self = .type6(try T6(from: decoder)) 2677 | case T7.typeValue: 2678 | self = .type7(try T7(from: decoder)) 2679 | case T8.typeValue: 2680 | self = .type8(try T8(from: decoder)) 2681 | case T9.typeValue: 2682 | self = .type9(try T9(from: decoder)) 2683 | case T10.typeValue: 2684 | self = .type10(try T10(from: decoder)) 2685 | case T11.typeValue: 2686 | self = .type11(try T11(from: decoder)) 2687 | case T12.typeValue: 2688 | self = .type12(try T12(from: decoder)) 2689 | case T13.typeValue: 2690 | self = .type13(try T13(from: decoder)) 2691 | case T14.typeValue: 2692 | self = .type14(try T14(from: decoder)) 2693 | case T15.typeValue: 2694 | self = .type15(try T15(from: decoder)) 2695 | case T16.typeValue: 2696 | self = .type16(try T16(from: decoder)) 2697 | case T17.typeValue: 2698 | self = .type17(try T17(from: decoder)) 2699 | default: 2700 | throw DecodingError.dataCorrupted( 2701 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 2702 | ) 2703 | } 2704 | } 2705 | } 2706 | 2707 | extension Union18: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable, T13: Equatable, T14: Equatable, T15: Equatable, T16: Equatable, T17: Equatable {} 2708 | extension Union18: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable, T13: Hashable, T14: Hashable, T15: Hashable, T16: Hashable, T17: Hashable {} 2709 | 2710 | 2711 | // Union19 2712 | 2713 | public enum Union19 { 2714 | 2715 | case type0(T0) 2716 | case type1(T1) 2717 | case type2(T2) 2718 | case type3(T3) 2719 | case type4(T4) 2720 | case type5(T5) 2721 | case type6(T6) 2722 | case type7(T7) 2723 | case type8(T8) 2724 | case type9(T9) 2725 | case type10(T10) 2726 | case type11(T11) 2727 | case type12(T12) 2728 | case type13(T13) 2729 | case type14(T14) 2730 | case type15(T15) 2731 | case type16(T16) 2732 | case type17(T17) 2733 | case type18(T18) 2734 | 2735 | public var asType0: T0? { 2736 | guard case .type0(let value) = self else { 2737 | return nil 2738 | } 2739 | return value 2740 | } 2741 | public var asType1: T1? { 2742 | guard case .type1(let value) = self else { 2743 | return nil 2744 | } 2745 | return value 2746 | } 2747 | public var asType2: T2? { 2748 | guard case .type2(let value) = self else { 2749 | return nil 2750 | } 2751 | return value 2752 | } 2753 | public var asType3: T3? { 2754 | guard case .type3(let value) = self else { 2755 | return nil 2756 | } 2757 | return value 2758 | } 2759 | public var asType4: T4? { 2760 | guard case .type4(let value) = self else { 2761 | return nil 2762 | } 2763 | return value 2764 | } 2765 | public var asType5: T5? { 2766 | guard case .type5(let value) = self else { 2767 | return nil 2768 | } 2769 | return value 2770 | } 2771 | public var asType6: T6? { 2772 | guard case .type6(let value) = self else { 2773 | return nil 2774 | } 2775 | return value 2776 | } 2777 | public var asType7: T7? { 2778 | guard case .type7(let value) = self else { 2779 | return nil 2780 | } 2781 | return value 2782 | } 2783 | public var asType8: T8? { 2784 | guard case .type8(let value) = self else { 2785 | return nil 2786 | } 2787 | return value 2788 | } 2789 | public var asType9: T9? { 2790 | guard case .type9(let value) = self else { 2791 | return nil 2792 | } 2793 | return value 2794 | } 2795 | public var asType10: T10? { 2796 | guard case .type10(let value) = self else { 2797 | return nil 2798 | } 2799 | return value 2800 | } 2801 | public var asType11: T11? { 2802 | guard case .type11(let value) = self else { 2803 | return nil 2804 | } 2805 | return value 2806 | } 2807 | public var asType12: T12? { 2808 | guard case .type12(let value) = self else { 2809 | return nil 2810 | } 2811 | return value 2812 | } 2813 | public var asType13: T13? { 2814 | guard case .type13(let value) = self else { 2815 | return nil 2816 | } 2817 | return value 2818 | } 2819 | public var asType14: T14? { 2820 | guard case .type14(let value) = self else { 2821 | return nil 2822 | } 2823 | return value 2824 | } 2825 | public var asType15: T15? { 2826 | guard case .type15(let value) = self else { 2827 | return nil 2828 | } 2829 | return value 2830 | } 2831 | public var asType16: T16? { 2832 | guard case .type16(let value) = self else { 2833 | return nil 2834 | } 2835 | return value 2836 | } 2837 | public var asType17: T17? { 2838 | guard case .type17(let value) = self else { 2839 | return nil 2840 | } 2841 | return value 2842 | } 2843 | public var asType18: T18? { 2844 | guard case .type18(let value) = self else { 2845 | return nil 2846 | } 2847 | return value 2848 | } 2849 | 2850 | } 2851 | 2852 | extension Union19: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable, T13: UnionEncodable, T14: UnionEncodable, T15: UnionEncodable, T16: UnionEncodable, T17: UnionEncodable, T18: UnionEncodable { 2853 | public func encode(to encoder: Encoder) throws { 2854 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 2855 | 2856 | switch self { 2857 | case .type0(let value): 2858 | try typeContainer.encode(T0.typeValue, forKey: .type) 2859 | try value.encode(to: encoder) 2860 | case .type1(let value): 2861 | try typeContainer.encode(T1.typeValue, forKey: .type) 2862 | try value.encode(to: encoder) 2863 | case .type2(let value): 2864 | try typeContainer.encode(T2.typeValue, forKey: .type) 2865 | try value.encode(to: encoder) 2866 | case .type3(let value): 2867 | try typeContainer.encode(T3.typeValue, forKey: .type) 2868 | try value.encode(to: encoder) 2869 | case .type4(let value): 2870 | try typeContainer.encode(T4.typeValue, forKey: .type) 2871 | try value.encode(to: encoder) 2872 | case .type5(let value): 2873 | try typeContainer.encode(T5.typeValue, forKey: .type) 2874 | try value.encode(to: encoder) 2875 | case .type6(let value): 2876 | try typeContainer.encode(T6.typeValue, forKey: .type) 2877 | try value.encode(to: encoder) 2878 | case .type7(let value): 2879 | try typeContainer.encode(T7.typeValue, forKey: .type) 2880 | try value.encode(to: encoder) 2881 | case .type8(let value): 2882 | try typeContainer.encode(T8.typeValue, forKey: .type) 2883 | try value.encode(to: encoder) 2884 | case .type9(let value): 2885 | try typeContainer.encode(T9.typeValue, forKey: .type) 2886 | try value.encode(to: encoder) 2887 | case .type10(let value): 2888 | try typeContainer.encode(T10.typeValue, forKey: .type) 2889 | try value.encode(to: encoder) 2890 | case .type11(let value): 2891 | try typeContainer.encode(T11.typeValue, forKey: .type) 2892 | try value.encode(to: encoder) 2893 | case .type12(let value): 2894 | try typeContainer.encode(T12.typeValue, forKey: .type) 2895 | try value.encode(to: encoder) 2896 | case .type13(let value): 2897 | try typeContainer.encode(T13.typeValue, forKey: .type) 2898 | try value.encode(to: encoder) 2899 | case .type14(let value): 2900 | try typeContainer.encode(T14.typeValue, forKey: .type) 2901 | try value.encode(to: encoder) 2902 | case .type15(let value): 2903 | try typeContainer.encode(T15.typeValue, forKey: .type) 2904 | try value.encode(to: encoder) 2905 | case .type16(let value): 2906 | try typeContainer.encode(T16.typeValue, forKey: .type) 2907 | try value.encode(to: encoder) 2908 | case .type17(let value): 2909 | try typeContainer.encode(T17.typeValue, forKey: .type) 2910 | try value.encode(to: encoder) 2911 | case .type18(let value): 2912 | try typeContainer.encode(T18.typeValue, forKey: .type) 2913 | try value.encode(to: encoder) 2914 | } 2915 | } 2916 | } 2917 | 2918 | extension Union19: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable, T13: UnionDecodable, T14: UnionDecodable, T15: UnionDecodable, T16: UnionDecodable, T17: UnionDecodable, T18: UnionDecodable { 2919 | public init(from decoder: Decoder) throws { 2920 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 2921 | 2922 | let typeValue = try container.decode(String.self, forKey: .type) 2923 | let defID = try LexiconDefinitionID(string: typeValue) 2924 | switch defID { 2925 | case T0.typeValue: 2926 | self = .type0(try T0(from: decoder)) 2927 | case T1.typeValue: 2928 | self = .type1(try T1(from: decoder)) 2929 | case T2.typeValue: 2930 | self = .type2(try T2(from: decoder)) 2931 | case T3.typeValue: 2932 | self = .type3(try T3(from: decoder)) 2933 | case T4.typeValue: 2934 | self = .type4(try T4(from: decoder)) 2935 | case T5.typeValue: 2936 | self = .type5(try T5(from: decoder)) 2937 | case T6.typeValue: 2938 | self = .type6(try T6(from: decoder)) 2939 | case T7.typeValue: 2940 | self = .type7(try T7(from: decoder)) 2941 | case T8.typeValue: 2942 | self = .type8(try T8(from: decoder)) 2943 | case T9.typeValue: 2944 | self = .type9(try T9(from: decoder)) 2945 | case T10.typeValue: 2946 | self = .type10(try T10(from: decoder)) 2947 | case T11.typeValue: 2948 | self = .type11(try T11(from: decoder)) 2949 | case T12.typeValue: 2950 | self = .type12(try T12(from: decoder)) 2951 | case T13.typeValue: 2952 | self = .type13(try T13(from: decoder)) 2953 | case T14.typeValue: 2954 | self = .type14(try T14(from: decoder)) 2955 | case T15.typeValue: 2956 | self = .type15(try T15(from: decoder)) 2957 | case T16.typeValue: 2958 | self = .type16(try T16(from: decoder)) 2959 | case T17.typeValue: 2960 | self = .type17(try T17(from: decoder)) 2961 | case T18.typeValue: 2962 | self = .type18(try T18(from: decoder)) 2963 | default: 2964 | throw DecodingError.dataCorrupted( 2965 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 2966 | ) 2967 | } 2968 | } 2969 | } 2970 | 2971 | extension Union19: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable, T13: Equatable, T14: Equatable, T15: Equatable, T16: Equatable, T17: Equatable, T18: Equatable {} 2972 | extension Union19: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable, T13: Hashable, T14: Hashable, T15: Hashable, T16: Hashable, T17: Hashable, T18: Hashable {} 2973 | 2974 | 2975 | // Union20 2976 | 2977 | public enum Union20 { 2978 | 2979 | case type0(T0) 2980 | case type1(T1) 2981 | case type2(T2) 2982 | case type3(T3) 2983 | case type4(T4) 2984 | case type5(T5) 2985 | case type6(T6) 2986 | case type7(T7) 2987 | case type8(T8) 2988 | case type9(T9) 2989 | case type10(T10) 2990 | case type11(T11) 2991 | case type12(T12) 2992 | case type13(T13) 2993 | case type14(T14) 2994 | case type15(T15) 2995 | case type16(T16) 2996 | case type17(T17) 2997 | case type18(T18) 2998 | case type19(T19) 2999 | 3000 | public var asType0: T0? { 3001 | guard case .type0(let value) = self else { 3002 | return nil 3003 | } 3004 | return value 3005 | } 3006 | public var asType1: T1? { 3007 | guard case .type1(let value) = self else { 3008 | return nil 3009 | } 3010 | return value 3011 | } 3012 | public var asType2: T2? { 3013 | guard case .type2(let value) = self else { 3014 | return nil 3015 | } 3016 | return value 3017 | } 3018 | public var asType3: T3? { 3019 | guard case .type3(let value) = self else { 3020 | return nil 3021 | } 3022 | return value 3023 | } 3024 | public var asType4: T4? { 3025 | guard case .type4(let value) = self else { 3026 | return nil 3027 | } 3028 | return value 3029 | } 3030 | public var asType5: T5? { 3031 | guard case .type5(let value) = self else { 3032 | return nil 3033 | } 3034 | return value 3035 | } 3036 | public var asType6: T6? { 3037 | guard case .type6(let value) = self else { 3038 | return nil 3039 | } 3040 | return value 3041 | } 3042 | public var asType7: T7? { 3043 | guard case .type7(let value) = self else { 3044 | return nil 3045 | } 3046 | return value 3047 | } 3048 | public var asType8: T8? { 3049 | guard case .type8(let value) = self else { 3050 | return nil 3051 | } 3052 | return value 3053 | } 3054 | public var asType9: T9? { 3055 | guard case .type9(let value) = self else { 3056 | return nil 3057 | } 3058 | return value 3059 | } 3060 | public var asType10: T10? { 3061 | guard case .type10(let value) = self else { 3062 | return nil 3063 | } 3064 | return value 3065 | } 3066 | public var asType11: T11? { 3067 | guard case .type11(let value) = self else { 3068 | return nil 3069 | } 3070 | return value 3071 | } 3072 | public var asType12: T12? { 3073 | guard case .type12(let value) = self else { 3074 | return nil 3075 | } 3076 | return value 3077 | } 3078 | public var asType13: T13? { 3079 | guard case .type13(let value) = self else { 3080 | return nil 3081 | } 3082 | return value 3083 | } 3084 | public var asType14: T14? { 3085 | guard case .type14(let value) = self else { 3086 | return nil 3087 | } 3088 | return value 3089 | } 3090 | public var asType15: T15? { 3091 | guard case .type15(let value) = self else { 3092 | return nil 3093 | } 3094 | return value 3095 | } 3096 | public var asType16: T16? { 3097 | guard case .type16(let value) = self else { 3098 | return nil 3099 | } 3100 | return value 3101 | } 3102 | public var asType17: T17? { 3103 | guard case .type17(let value) = self else { 3104 | return nil 3105 | } 3106 | return value 3107 | } 3108 | public var asType18: T18? { 3109 | guard case .type18(let value) = self else { 3110 | return nil 3111 | } 3112 | return value 3113 | } 3114 | public var asType19: T19? { 3115 | guard case .type19(let value) = self else { 3116 | return nil 3117 | } 3118 | return value 3119 | } 3120 | 3121 | } 3122 | 3123 | extension Union20: Encodable where T0: UnionEncodable, T1: UnionEncodable, T2: UnionEncodable, T3: UnionEncodable, T4: UnionEncodable, T5: UnionEncodable, T6: UnionEncodable, T7: UnionEncodable, T8: UnionEncodable, T9: UnionEncodable, T10: UnionEncodable, T11: UnionEncodable, T12: UnionEncodable, T13: UnionEncodable, T14: UnionEncodable, T15: UnionEncodable, T16: UnionEncodable, T17: UnionEncodable, T18: UnionEncodable, T19: UnionEncodable { 3124 | public func encode(to encoder: Encoder) throws { 3125 | var typeContainer = encoder.container(keyedBy: UnionTypeCodingKeys.self) 3126 | 3127 | switch self { 3128 | case .type0(let value): 3129 | try typeContainer.encode(T0.typeValue, forKey: .type) 3130 | try value.encode(to: encoder) 3131 | case .type1(let value): 3132 | try typeContainer.encode(T1.typeValue, forKey: .type) 3133 | try value.encode(to: encoder) 3134 | case .type2(let value): 3135 | try typeContainer.encode(T2.typeValue, forKey: .type) 3136 | try value.encode(to: encoder) 3137 | case .type3(let value): 3138 | try typeContainer.encode(T3.typeValue, forKey: .type) 3139 | try value.encode(to: encoder) 3140 | case .type4(let value): 3141 | try typeContainer.encode(T4.typeValue, forKey: .type) 3142 | try value.encode(to: encoder) 3143 | case .type5(let value): 3144 | try typeContainer.encode(T5.typeValue, forKey: .type) 3145 | try value.encode(to: encoder) 3146 | case .type6(let value): 3147 | try typeContainer.encode(T6.typeValue, forKey: .type) 3148 | try value.encode(to: encoder) 3149 | case .type7(let value): 3150 | try typeContainer.encode(T7.typeValue, forKey: .type) 3151 | try value.encode(to: encoder) 3152 | case .type8(let value): 3153 | try typeContainer.encode(T8.typeValue, forKey: .type) 3154 | try value.encode(to: encoder) 3155 | case .type9(let value): 3156 | try typeContainer.encode(T9.typeValue, forKey: .type) 3157 | try value.encode(to: encoder) 3158 | case .type10(let value): 3159 | try typeContainer.encode(T10.typeValue, forKey: .type) 3160 | try value.encode(to: encoder) 3161 | case .type11(let value): 3162 | try typeContainer.encode(T11.typeValue, forKey: .type) 3163 | try value.encode(to: encoder) 3164 | case .type12(let value): 3165 | try typeContainer.encode(T12.typeValue, forKey: .type) 3166 | try value.encode(to: encoder) 3167 | case .type13(let value): 3168 | try typeContainer.encode(T13.typeValue, forKey: .type) 3169 | try value.encode(to: encoder) 3170 | case .type14(let value): 3171 | try typeContainer.encode(T14.typeValue, forKey: .type) 3172 | try value.encode(to: encoder) 3173 | case .type15(let value): 3174 | try typeContainer.encode(T15.typeValue, forKey: .type) 3175 | try value.encode(to: encoder) 3176 | case .type16(let value): 3177 | try typeContainer.encode(T16.typeValue, forKey: .type) 3178 | try value.encode(to: encoder) 3179 | case .type17(let value): 3180 | try typeContainer.encode(T17.typeValue, forKey: .type) 3181 | try value.encode(to: encoder) 3182 | case .type18(let value): 3183 | try typeContainer.encode(T18.typeValue, forKey: .type) 3184 | try value.encode(to: encoder) 3185 | case .type19(let value): 3186 | try typeContainer.encode(T19.typeValue, forKey: .type) 3187 | try value.encode(to: encoder) 3188 | } 3189 | } 3190 | } 3191 | 3192 | extension Union20: Decodable where T0: UnionDecodable, T1: UnionDecodable, T2: UnionDecodable, T3: UnionDecodable, T4: UnionDecodable, T5: UnionDecodable, T6: UnionDecodable, T7: UnionDecodable, T8: UnionDecodable, T9: UnionDecodable, T10: UnionDecodable, T11: UnionDecodable, T12: UnionDecodable, T13: UnionDecodable, T14: UnionDecodable, T15: UnionDecodable, T16: UnionDecodable, T17: UnionDecodable, T18: UnionDecodable, T19: UnionDecodable { 3193 | public init(from decoder: Decoder) throws { 3194 | let container = try decoder.container(keyedBy: UnionTypeCodingKeys.self) 3195 | 3196 | let typeValue = try container.decode(String.self, forKey: .type) 3197 | let defID = try LexiconDefinitionID(string: typeValue) 3198 | switch defID { 3199 | case T0.typeValue: 3200 | self = .type0(try T0(from: decoder)) 3201 | case T1.typeValue: 3202 | self = .type1(try T1(from: decoder)) 3203 | case T2.typeValue: 3204 | self = .type2(try T2(from: decoder)) 3205 | case T3.typeValue: 3206 | self = .type3(try T3(from: decoder)) 3207 | case T4.typeValue: 3208 | self = .type4(try T4(from: decoder)) 3209 | case T5.typeValue: 3210 | self = .type5(try T5(from: decoder)) 3211 | case T6.typeValue: 3212 | self = .type6(try T6(from: decoder)) 3213 | case T7.typeValue: 3214 | self = .type7(try T7(from: decoder)) 3215 | case T8.typeValue: 3216 | self = .type8(try T8(from: decoder)) 3217 | case T9.typeValue: 3218 | self = .type9(try T9(from: decoder)) 3219 | case T10.typeValue: 3220 | self = .type10(try T10(from: decoder)) 3221 | case T11.typeValue: 3222 | self = .type11(try T11(from: decoder)) 3223 | case T12.typeValue: 3224 | self = .type12(try T12(from: decoder)) 3225 | case T13.typeValue: 3226 | self = .type13(try T13(from: decoder)) 3227 | case T14.typeValue: 3228 | self = .type14(try T14(from: decoder)) 3229 | case T15.typeValue: 3230 | self = .type15(try T15(from: decoder)) 3231 | case T16.typeValue: 3232 | self = .type16(try T16(from: decoder)) 3233 | case T17.typeValue: 3234 | self = .type17(try T17(from: decoder)) 3235 | case T18.typeValue: 3236 | self = .type18(try T18(from: decoder)) 3237 | case T19.typeValue: 3238 | self = .type19(try T19(from: decoder)) 3239 | default: 3240 | throw DecodingError.dataCorrupted( 3241 | .init(codingPath: decoder.codingPath, debugDescription: "unexpected $type value: \(typeValue)") 3242 | ) 3243 | } 3244 | } 3245 | } 3246 | 3247 | extension Union20: Equatable where T0: Equatable, T1: Equatable, T2: Equatable, T3: Equatable, T4: Equatable, T5: Equatable, T6: Equatable, T7: Equatable, T8: Equatable, T9: Equatable, T10: Equatable, T11: Equatable, T12: Equatable, T13: Equatable, T14: Equatable, T15: Equatable, T16: Equatable, T17: Equatable, T18: Equatable, T19: Equatable {} 3248 | extension Union20: Hashable where T0: Hashable, T1: Hashable, T2: Hashable, T3: Hashable, T4: Hashable, T5: Hashable, T6: Hashable, T7: Hashable, T8: Hashable, T9: Hashable, T10: Hashable, T11: Hashable, T12: Hashable, T13: Hashable, T14: Hashable, T15: Hashable, T16: Hashable, T17: Hashable, T18: Hashable, T19: Hashable {} 3249 | 3250 | --------------------------------------------------------------------------------