diff --git a/IntegrationTest/Package.swift b/IntegrationTest/Package.swift index 32604b28..f906870b 100644 --- a/IntegrationTest/Package.swift +++ b/IntegrationTest/Package.swift @@ -32,8 +32,8 @@ let package = Package( ) ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), ], targets: [ .target( diff --git a/Package.swift b/Package.swift index 5e6f07e0..9747692d 100644 --- a/Package.swift +++ b/Package.swift @@ -80,7 +80,7 @@ let package = Package( // Tests-only: Runtime library linked by generated code, and also // helps keep the runtime library new enough to work with the generated // code. - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.11")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), // Build and preview docs .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), @@ -147,18 +147,6 @@ let package = Package( swiftSettings: swiftSettings ), - // PetstoreConsumerTestsFFMultipleContentTypes - // Builds and tests the reference code from GeneratorReferenceTests - // to ensure it actually works correctly at runtime. - // Enabled feature flag: multipleContentTypes - .testTarget( - name: "PetstoreConsumerTestsFFMultipleContentTypes", - dependencies: [ - "PetstoreConsumerTestCore" - ], - swiftSettings: swiftSettings - ), - // Generator CLI .executableTarget( name: "swift-openapi-generator", diff --git a/Sources/_OpenAPIGeneratorCore/FeatureFlags.swift b/Sources/_OpenAPIGeneratorCore/FeatureFlags.swift index c4195f7c..9f233ffb 100644 --- a/Sources/_OpenAPIGeneratorCore/FeatureFlags.swift +++ b/Sources/_OpenAPIGeneratorCore/FeatureFlags.swift @@ -27,29 +27,9 @@ /// 1.0 is released.) public enum FeatureFlag: String, Hashable, Codable, CaseIterable { - /// Multiple request and response body content types. - /// - /// Tracking issues: - /// - https://github.com/apple/swift-openapi-generator/issues/6 - /// - https://github.com/apple/swift-openapi-generator/issues/7 - case multipleContentTypes - - /// SOAR-0001 Improved OpenAPI -> Swift name mapping - /// - /// Tracking issues: - /// - https://github.com/apple/swift-openapi-generator/pull/95 - case proposal0001 - - /// Stricted input OpenAPI document validation. - /// - /// Check for structural issues and detect cycles proactively. - case strictOpenAPIValidation - - /// Removed the generation of an undocumented case in enums/oneOfs. - /// - /// Tracking issue: - /// - https://github.com/apple/swift-openapi-generator/issues/204 - case closedEnumsAndOneOfs + /// Has to be here until we add more feature flags, otherwise the enum + /// doesn't compile. + case empty } /// A set of enabled feature flags. diff --git a/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift b/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift index 645b7afe..589f6ef0 100644 --- a/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift +++ b/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift @@ -18,9 +18,6 @@ /// - config: The generator config. /// - Throws: An error if a fatal issue is found. func validateDoc(_ doc: ParsedOpenAPIRepresentation, config: Config) throws -> [Diagnostic] { - guard config.featureFlags.contains(.strictOpenAPIValidation) else { - return [] - } // Run OpenAPIKit's built-in validation. // Pass `false` to `strict`, however, because we don't // want to turn schema loading warnings into errors. diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/SwiftSafeNames.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/SwiftSafeNames.swift index 22769cb9..13f67532 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/SwiftSafeNames.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/SwiftSafeNames.swift @@ -19,57 +19,12 @@ extension FileTranslator { /// /// - Parameter string: The string to convert to be safe for Swift. func swiftSafeName(for string: String) -> String { - guard config.featureFlags.contains(.proposal0001) else { - return string.safeForSwiftCode - } - return string.proposedSafeForSwiftCode + string.safeForSwiftCode } } fileprivate extension String { - /// Returns a string sanitized to be usable as a Swift identifier. - /// - /// For example, the string `$nake` would be returned as `_nake`, because - /// the dollar sign is not a valid character in a Swift identifier. - /// - /// In addition to replacing illegal characters with an underscores, also - /// ensures that the identifier starts with a letter and not a number. - var safeForSwiftCode: String { - guard !isEmpty else { - return "_empty" - } - - // Only allow [a-zA-Z][a-zA-Z0-9_]* - // This is bad, is there something like percent encoding functionality but for general "allowed chars only"? - - let firstCharSet: CharacterSet = .letters - let numbers: CharacterSet = .decimalDigits - let otherCharSet: CharacterSet = .alphanumerics.union(.init(charactersIn: "_")) - - var sanitizedScalars: [Unicode.Scalar] = [] - for (index, scalar) in unicodeScalars.enumerated() { - let allowedSet = index == 0 ? firstCharSet : otherCharSet - let outScalar: Unicode.Scalar - if allowedSet.contains(scalar) { - outScalar = scalar - } else if index == 0 && numbers.contains(scalar) { - sanitizedScalars.append("_") - outScalar = scalar - } else { - outScalar = "_" - } - sanitizedScalars.append(outScalar) - } - - let validString = String(UnicodeScalarView(sanitizedScalars)) - - guard Self.keywords.contains(validString) else { - return validString - } - return "_\(validString)" - } - /// Returns a string sanitized to be usable as a Swift identifier. /// /// See the proposal SOAR-0001 for details. @@ -81,7 +36,7 @@ fileprivate extension String { /// /// In addition to replacing illegal characters, it also /// ensures that the identifier starts with a letter and not a number. - var proposedSafeForSwiftCode: String { + var safeForSwiftCode: String { guard !isEmpty else { return "_empty" } diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateAllAnyOneOf.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateAllAnyOneOf.swift index 972d1e0f..92d1eb4d 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateAllAnyOneOf.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateAllAnyOneOf.swift @@ -207,11 +207,9 @@ extension FileTranslator { let caseNames = cases.map(\.0) - let undocumentedType: TypeName let codingKeysDecls: [Declaration] let decoder: Declaration if let discriminator { - undocumentedType = .objectContainer let originalName = discriminator.propertyName let swiftName = swiftSafeName(for: originalName) codingKeysDecls = [ @@ -232,33 +230,12 @@ extension FileTranslator { cases: cases.map { ($0.0, $0.1!) } ) } else { - undocumentedType = .valueContainer codingKeysDecls = [] decoder = translateOneOfWithoutDiscriminatorDecoder( caseNames: caseNames ) } - let generateUndocumentedCase = shouldGenerateUndocumentedCaseForEnumsAndOneOfs - - let otherCases: [Declaration] - if generateUndocumentedCase { - let undocumentedCase: Declaration = .commentable( - .doc("Parsed a case that was not defined in the OpenAPI document."), - .enumCase( - name: Constants.OneOf.undocumentedCaseName, - kind: .nameWithAssociatedValues([ - .init(type: undocumentedType.fullyQualifiedSwiftName) - ]) - ) - ) - otherCases = [ - undocumentedCase - ] - } else { - otherCases = [] - } - let encoder = translateOneOfEncoder(caseNames: caseNames) let comment: Comment? = @@ -269,7 +246,7 @@ extension FileTranslator { accessModifier: config.access, name: typeName.shortSwiftName, conformances: Constants.ObjectStruct.conformances, - members: caseDecls + otherCases + codingKeysDecls + [ + members: caseDecls + codingKeysDecls + [ decoder, encoder, ] diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateCodable.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateCodable.swift index 0e4ddaf2..b69237e2 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateCodable.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateCodable.swift @@ -339,61 +339,11 @@ extension FileTranslator { ) } - let generateUndocumentedCase = shouldGenerateUndocumentedCaseForEnumsAndOneOfs - let otherExprs: [CodeBlock] - if generateUndocumentedCase { - otherExprs = [ - .declaration( - .variable( - kind: .let, - left: "container", - right: .try( - .identifier("decoder") - .dot("singleValueContainer") - .call([]) - ) - ) - ), - .declaration( - .variable( - kind: .let, - left: "value", - right: .try( - .identifier("container") - .dot("decode") - .call([ - .init( - label: nil, - expression: - .identifier( - TypeName - .valueContainer - .fullyQualifiedSwiftName - ) - .dot("self") - ) - ]) - ) - ) - ), - .expression( - .assignment( - left: .identifier("self"), - right: .dot(Constants.OneOf.undocumentedCaseName) - .call([ - .init(label: nil, expression: .identifier("value")) - ]) - ) - ), - ] - } else { - otherExprs = [ - .expression( - translateOneOfDecoderThrowOnUnknownExpr() - ) - ] - } - + let otherExprs: [CodeBlock] = [ + .expression( + translateOneOfDecoderThrowOnUnknownExpr() + ) + ] return decoderInitializer( body: (assignExprs).map { .expression($0) } + otherExprs ) @@ -447,60 +397,11 @@ extension FileTranslator { ] ) } - let generateUndocumentedCase = shouldGenerateUndocumentedCaseForEnumsAndOneOfs - let otherExprs: [CodeBlock] - if generateUndocumentedCase { - otherExprs = [ - .declaration( - .variable( - kind: .let, - left: "container", - right: .try( - .identifier("decoder") - .dot("singleValueContainer") - .call([]) - ) - ) - ), - .declaration( - .variable( - kind: .let, - left: "value", - right: .try( - .identifier("container") - .dot("decode") - .call([ - .init( - label: nil, - expression: - .identifier( - TypeName - .objectContainer - .fullyQualifiedSwiftName - ) - .dot("self") - ) - ]) - ) - ) - ), - .expression( - .assignment( - left: .identifier("self"), - right: .dot(Constants.OneOf.undocumentedCaseName) - .call([ - .init(label: nil, expression: .identifier("value")) - ]) - ) - ), - ] - } else { - otherExprs = [ - .expression( - translateOneOfDecoderThrowOnUnknownExpr() - ) - ] - } + let otherExprs: [CodeBlock] = [ + .expression( + translateOneOfDecoderThrowOnUnknownExpr() + ) + ] let body: [CodeBlock] = [ .declaration(.decoderContainerOfKeysVar()), .declaration( @@ -546,27 +447,19 @@ extension FileTranslator { func translateOneOfEncoder( caseNames: [String] ) -> Declaration { - let generateUndocumentedCase = shouldGenerateUndocumentedCaseForEnumsAndOneOfs - let otherCaseNames: [String] - if generateUndocumentedCase { - otherCaseNames = [Constants.OneOf.undocumentedCaseName] - } else { - otherCaseNames = [] - } let switchExpr: Expression = .switch( switchedExpression: .identifier("self"), - cases: (caseNames + otherCaseNames) - .map { caseName in - .init( - kind: .case(.dot(caseName), ["value"]), - body: [ - .expression( - .identifier("value") - .encodeExpr() - ) - ] - ) - } + cases: caseNames.map { caseName in + .init( + kind: .case(.dot(caseName), ["value"]), + body: [ + .expression( + .identifier("value") + .encodeExpr() + ) + ] + ) + } ) return encoderFunction(body: [.expression(switchExpr)]) } diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStringEnum.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStringEnum.swift index 71cd23fa..dcd33313 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStringEnum.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStringEnum.swift @@ -45,19 +45,14 @@ extension FileTranslator { let caseName = swiftSafeName(for: rawValue) return (caseName, rawValue) } - let generateUnknownCases = shouldGenerateUndocumentedCaseForEnumsAndOneOfs - let baseConformance = - generateUnknownCases ? Constants.StringEnum.baseConformanceOpen : Constants.StringEnum.baseConformanceClosed - let conformances = - generateUnknownCases ? Constants.StringEnum.conformancesOpen : Constants.StringEnum.conformancesClosed - let unknownCaseName = generateUnknownCases ? Constants.StringEnum.undocumentedCaseName : nil + let conformances = [Constants.StringEnum.baseConformance] + Constants.StringEnum.conformances return try translateRawRepresentableEnum( typeName: typeName, - conformances: [baseConformance] + conformances, + conformances: conformances, userDescription: userDescription, cases: cases, - unknownCaseName: unknownCaseName, - unknownCaseDescription: "Parsed a raw value that was not defined in the OpenAPI document." + unknownCaseName: nil, + unknownCaseDescription: nil ) } } diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift index 9ecc281a..acd5fc7e 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift @@ -141,25 +141,11 @@ enum Constants { /// Constants related to all generated string-based enums. enum StringEnum { - /// The name of the undocumented enum case. - static let undocumentedCaseName = "undocumented" - - /// The name of the base conformance when enums are open. - static let baseConformanceOpen: String = "RawRepresentable" - - /// The name of the base conformance when enums are closed. - static let baseConformanceClosed: String = "String" - - /// The types that every enum conforms to. - static let conformancesOpen: [String] = [ - "Codable", - "Hashable", - "Sendable", - "CaseIterable", - ] + /// The name of the base conformance. + static let baseConformance: String = "String" /// The types that every enum conforms to. - static let conformancesClosed: [String] = [ + static let conformances: [String] = [ "Codable", "Hashable", "Sendable", @@ -168,9 +154,6 @@ enum Constants { /// Constants related to generated oneOf enums. enum OneOf { - /// The name of the undocumented enum case. - static let undocumentedCaseName = "undocumented" - /// The name of the discriminator variable. static let discriminatorName = "discriminator" } diff --git a/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentInspector.swift b/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentInspector.swift index 497360fc..0e869268 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentInspector.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentInspector.swift @@ -113,14 +113,6 @@ extension FileTranslator { guard !contents.isEmpty else { return [] } - guard config.featureFlags.contains(.multipleContentTypes) else { - return bestSingleContent( - contents, - excludeBinary: excludeBinary, - foundIn: foundIn - ) - .flatMap { [$0] } ?? [] - } return contents .compactMap { key, value in diff --git a/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentSwiftName.swift b/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentSwiftName.swift index 637946b1..1d5db86f 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentSwiftName.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/Content/ContentSwiftName.swift @@ -20,48 +20,37 @@ extension FileTranslator { /// /// - Parameter contentType: The content type for which to compute the name. func contentSwiftName(_ contentType: ContentType) -> String { - if config.featureFlags.contains(.multipleContentTypes) { - switch contentType.lowercasedTypeAndSubtype { - case "application/json": - return "json" - case "application/x-www-form-urlencoded": - return "urlEncodedForm" - case "multipart/form-data": - return "multipartForm" - case "text/plain": - return "plainText" - case "*/*": - return "any" - case "application/xml": - return "xml" - case "application/octet-stream": - return "binary" - case "text/html": - return "html" - case "application/yaml": - return "yaml" - case "text/csv": - return "csv" - case "image/png": - return "png" - case "application/pdf": - return "pdf" - case "image/jpeg": - return "jpeg" - default: - let safedType = swiftSafeName(for: contentType.originallyCasedType) - let safedSubtype = swiftSafeName(for: contentType.originallyCasedSubtype) - return "\(safedType)_\(safedSubtype)" - } - } else { - switch contentType.category { - case .json: - return "json" - case .text: - return "text" - case .binary: - return "binary" - } + switch contentType.lowercasedTypeAndSubtype { + case "application/json": + return "json" + case "application/x-www-form-urlencoded": + return "urlEncodedForm" + case "multipart/form-data": + return "multipartForm" + case "text/plain": + return "plainText" + case "*/*": + return "any" + case "application/xml": + return "xml" + case "application/octet-stream": + return "binary" + case "text/html": + return "html" + case "application/yaml": + return "yaml" + case "text/csv": + return "csv" + case "image/png": + return "png" + case "application/pdf": + return "pdf" + case "image/jpeg": + return "jpeg" + default: + let safedType = swiftSafeName(for: contentType.originallyCasedType) + let safedSubtype = swiftSafeName(for: contentType.originallyCasedSubtype) + return "\(safedType)_\(safedSubtype)" } } } diff --git a/Sources/_OpenAPIGeneratorCore/Translator/FileTranslator+FeatureFlags.swift b/Sources/_OpenAPIGeneratorCore/Translator/FileTranslator+FeatureFlags.swift index 7b2a587c..4527bbe9 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/FileTranslator+FeatureFlags.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/FileTranslator+FeatureFlags.swift @@ -14,14 +14,5 @@ import OpenAPIKit extension FileTranslator { - - /// Returns a Boolean value indicating whether an undocumented case should - /// be generated for enums and oneOfs. - var shouldGenerateUndocumentedCaseForEnumsAndOneOfs: Bool { - if config.featureFlags.contains(.closedEnumsAndOneOfs) { - return false - } - // The 0.1.x default. - return true - } + // Add helpers for reading feature flags below. } diff --git a/Sources/swift-openapi-generator/Documentation.docc/Articles/Supported-OpenAPI-features.md b/Sources/swift-openapi-generator/Documentation.docc/Articles/Supported-OpenAPI-features.md index 880228f1..4da0316d 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Articles/Supported-OpenAPI-features.md +++ b/Sources/swift-openapi-generator/Documentation.docc/Articles/Supported-OpenAPI-features.md @@ -204,7 +204,7 @@ Supported features are always provided on _both_ client and server. - [x] schema - [ ] example - [ ] examples -- [x] content (chooses one from the map) +- [x] content #### Style Values diff --git a/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0003.md b/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0003.md index dad9c4d8..da775f40 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0003.md +++ b/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0003.md @@ -38,9 +38,9 @@ To summarize, the client needs to _provide_ Accept header information, and the s #### Existing behavior -Today, the generated client includes in the Accept header all the content types that appear in any response for the invoked operation in the OpenAPI document, essentially allowing the server to pick any content type. For an operation that uses JSON and plain text, the header would be: `accept: application/json, text/plain`. However, there is no way for the client to narrow down the choices or customize the quality value, meaning the only workaround is to build a [`ClientMiddleware`](https://swiftpackageindex.com/apple/swift-openapi-runtime/0.1.8/documentation/openapiruntime/clientmiddleware) that modifies the raw HTTP request before it's executed by the transport. +Today, the generated client includes in the Accept header all the content types that appear in any response for the invoked operation in the OpenAPI document, essentially allowing the server to pick any content type. For an operation that uses JSON and plain text, the header would be: `accept: application/json, text/plain`. However, there is no way for the client to narrow down the choices or customize the quality value, meaning the only workaround is to build a [`ClientMiddleware`](https://swiftpackageindex.com/apple/swift-openapi-runtime/documentation/openapiruntime/clientmiddleware) that modifies the raw HTTP request before it's executed by the transport. -On the server side, adopters have had to resort to workarounds, such as extracting the Accept header in a custom [`ServerMiddleware`](https://swiftpackageindex.com/apple/swift-openapi-runtime/0.1.8/documentation/openapiruntime/servermiddleware) and saving the parsed value into a task local value. +On the server side, adopters have had to resort to workarounds, such as extracting the Accept header in a custom [`ServerMiddleware`](https://swiftpackageindex.com/apple/swift-openapi-runtime/documentation/openapiruntime/servermiddleware) and saving the parsed value into a task local value. #### Why now? diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.2.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.2.swift index 27a565ca..9162a6ea 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.2.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.2.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/apple/swift-openapi-urlsession", .upToNextMinor(from: "0.1.0")), ], targets: [ diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.3.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.3.swift index ba0a72e5..d5c2ea5d 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.3.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.3.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/apple/swift-openapi-urlsession", .upToNextMinor(from: "0.1.0")), ], targets: [ diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.4.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.4.swift index 8590e352..3dd6f29e 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.4.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.4.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/apple/swift-openapi-urlsession", .upToNextMinor(from: "0.1.0")), ], targets: [ diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.5.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.5.swift index 8590e352..3dd6f29e 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.5.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/client.Package.5.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/apple/swift-openapi-urlsession", .upToNextMinor(from: "0.1.0")), ], targets: [ diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.2.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.2.swift index 862ff334..8ed5e11e 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.2.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.2.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15) ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/swift-server/swift-openapi-vapor", .upToNextMinor(from: "0.1.0")), .package(url: "https://github.com/vapor/vapor", from: "4.76.0"), ], diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.3.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.3.swift index 20c7d280..8b60e97b 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.3.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.3.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15) ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/swift-server/swift-openapi-vapor", .upToNextMinor(from: "0.1.0")), .package(url: "https://github.com/vapor/vapor", from: "4.76.0"), ], diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.4.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.4.swift index 6c5153bc..03702ce5 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.4.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.4.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15) ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/swift-server/swift-openapi-vapor", .upToNextMinor(from: "0.1.0")), .package(url: "https://github.com/vapor/vapor", from: "4.76.0"), ], diff --git a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.5.swift b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.5.swift index 6c5153bc..03702ce5 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.5.swift +++ b/Sources/swift-openapi-generator/Documentation.docc/Tutorials/_Resources/server.Package.5.swift @@ -7,8 +7,8 @@ let package = Package( .macOS(.v10_15) ], dependencies: [ - .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.1.0")), - .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.1.0")), + .package(url: "https://github.com/apple/swift-openapi-generator", .upToNextMinor(from: "0.2.0")), + .package(url: "https://github.com/apple/swift-openapi-runtime", .upToNextMinor(from: "0.2.0")), .package(url: "https://github.com/swift-server/swift-openapi-vapor", .upToNextMinor(from: "0.1.0")), .package(url: "https://github.com/vapor/vapor", from: "4.76.0"), ], diff --git a/Tests/OpenAPIGeneratorCoreTests/Extensions/Test_String.swift b/Tests/OpenAPIGeneratorCoreTests/Extensions/Test_String.swift index f5bd98d5..ac985481 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Extensions/Test_String.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Extensions/Test_String.swift @@ -17,30 +17,6 @@ import XCTest final class Test_String: Test_Core { func testAsSwiftSafeName() { - let cases: [(String, String)] = [ - // Simple - ("foo", "foo"), - - // Starts with a number - ("3foo", "_3foo"), - - // Keyword - ("default", "_default"), - - // Reserved name - ("Type", "_Type"), - - // Empty string - ("", "_empty"), - ] - let translator = makeTranslator(featureFlags: []) - let asSwiftSafeName: (String) -> String = translator.swiftSafeName - for (input, sanitized) in cases { - XCTAssertEqual(asSwiftSafeName(input), sanitized) - } - } - - func testAsProposedSwiftName() { let cases: [(String, String)] = [ // Simple ("foo", "foo"), @@ -88,7 +64,7 @@ final class Test_String: Test_Core { ("application", "application"), ("vendor1+json", "vendor1_plus_json"), ] - let translator = makeTranslator(featureFlags: [.proposal0001]) + let translator = makeTranslator() let asSwiftSafeName: (String) -> String = translator.swiftSafeName for (input, sanitized) in cases { XCTAssertEqual(asSwiftSafeName(input), sanitized) diff --git a/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift b/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift index adefedae..c8074235 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift @@ -35,12 +35,7 @@ final class Test_validateDoc: Test_Core { ) let diagnostics = try validateDoc( doc, - config: .init( - mode: .types, - featureFlags: [ - .strictOpenAPIValidation - ] - ) + config: .init(mode: .types) ) XCTAssertEqual(diagnostics.count, 1) } @@ -66,12 +61,7 @@ final class Test_validateDoc: Test_Core { XCTAssertThrowsError( try validateDoc( doc, - config: .init( - mode: .types, - featureFlags: [ - .strictOpenAPIValidation - ] - ) + config: .init(mode: .types) ) ) } diff --git a/Tests/OpenAPIGeneratorCoreTests/Translator/CommonTranslations/Test_translateStringEnum.swift b/Tests/OpenAPIGeneratorCoreTests/Translator/CommonTranslations/Test_translateStringEnum.swift index abc7040f..e6dd0258 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Translator/CommonTranslations/Test_translateStringEnum.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Translator/CommonTranslations/Test_translateStringEnum.swift @@ -24,7 +24,7 @@ final class Test_translateStringEnum: Test_Core { "" ) ) - XCTAssertEqual(names, ["a", "_empty", "undocumented"]) + XCTAssertEqual(names, ["a", "_empty"]) } func testCaseValuesForNullableSchema() throws { @@ -35,7 +35,7 @@ final class Test_translateStringEnum: Test_Core { nil ) ) - XCTAssertEqual(names, ["a", "_empty", "undocumented"]) + XCTAssertEqual(names, ["a", "_empty"]) } func _caseValues(_ schema: JSONSchema) throws -> [String] { diff --git a/Tests/OpenAPIGeneratorCoreTests/Translator/Content/Test_ContentSwiftName.swift b/Tests/OpenAPIGeneratorCoreTests/Translator/Content/Test_ContentSwiftName.swift index b2a0e32f..a0bd0d04 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Translator/Content/Test_ContentSwiftName.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Translator/Content/Test_ContentSwiftName.swift @@ -17,28 +17,8 @@ import OpenAPIKit final class Test_ContentSwiftName: Test_Core { - func testExisting() throws { - let nameMaker = makeTranslator(featureFlags: []).contentSwiftName - let cases: [(String, String)] = [ - ("application/json", "json"), - ("application/x-www-form-urlencoded", "binary"), - ("multipart/form-data", "binary"), - ("text/plain", "text"), - ("*/*", "binary"), - ("application/xml", "binary"), - ("application/octet-stream", "binary"), - ("application/myformat+json", "json"), - ("foo/bar", "binary"), - ] - try _testIdentifiers(cases: cases, nameMaker: nameMaker) - } - - func testProposed_multipleContentTypes() throws { - let nameMaker = makeTranslator(featureFlags: [ - .proposal0001, - .multipleContentTypes, - ]) - .contentSwiftName + func test() throws { + let nameMaker = makeTranslator().contentSwiftName let cases: [(String, String)] = [ // Short names. @@ -60,10 +40,6 @@ final class Test_ContentSwiftName: Test_Core { ("application/myformat+json", "application_myformat_plus_json"), ("foo/bar", "foo_bar"), ] - try _testIdentifiers(cases: cases, nameMaker: nameMaker) - } - - func _testIdentifiers(cases: [(String, String)], nameMaker: (ContentType) -> String) throws { for item in cases { let contentType = try XCTUnwrap(ContentType(item.0)) XCTAssertEqual(nameMaker(contentType), item.1, "Case \(item.0) failed") diff --git a/Tests/OpenAPIGeneratorCoreTests/Translator/TypeAssignment/Test_TypeAssigner.swift b/Tests/OpenAPIGeneratorCoreTests/Translator/TypeAssignment/Test_TypeAssigner.swift index a9a8092b..90418ea8 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Translator/TypeAssignment/Test_TypeAssigner.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Translator/TypeAssignment/Test_TypeAssigner.swift @@ -70,8 +70,8 @@ class Test_TypeAssigner: Test_Core { "__custom__type": "__custom__type", // sanitization "1customtype": "_1customtype", - "custom.type": "custom_type", - ".custom$type": "_custom_type", + "custom.type": "custom_period_type", + ".custom$type": "_period_custom_dollar_type", // keywords "enum": "_enum", ] diff --git a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift index 15041edf..5c2aa8ec 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift @@ -46,25 +46,7 @@ class FileBasedReferenceTests: XCTestCase { func testPetstore() throws { try _test( - referenceProject: .init(name: .petstore), - ignoredDiagnosticMessages: [ - #"Feature "Multiple content types" is not supported, skipping"# - ] - ) - } - - func testPetstoreFFMultipleContentTypes() throws { - try _test( - referenceProject: .init( - name: .petstore, - customDirectoryName: "Petstore_FF_MultipleContentTypes" - ), - featureFlags: [ - .multipleContentTypes, - .proposal0001, - .strictOpenAPIValidation, - .closedEnumsAndOneOfs, - ] + referenceProject: .init(name: .petstore) ) } diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift index a485ed8e..b5a599c5 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift @@ -71,7 +71,7 @@ public struct Client: APIProtocol { try converter.setHeaderFieldAsURI( in: &request.headerFields, name: "My-Request-UUID", - value: input.headers.My_Request_UUID + value: input.headers.My_hyphen_Request_hyphen_UUID ) try converter.setQueryItemAsURI( in: &request, @@ -87,12 +87,12 @@ public struct Client: APIProtocol { switch response.statusCode { case 200: let headers: Operations.listPets.Output.Ok.Headers = .init( - My_Response_UUID: try converter.getRequiredHeaderFieldAsURI( + My_hyphen_Response_hyphen_UUID: try converter.getRequiredHeaderFieldAsURI( in: response.headerFields, name: "My-Response-UUID", as: Swift.String.self ), - My_Tracing_Header: try converter.getOptionalHeaderFieldAsURI( + My_hyphen_Tracing_hyphen_Header: try converter.getOptionalHeaderFieldAsURI( in: response.headerFields, name: "My-Tracing-Header", as: Components.Headers.TracingHeader.self @@ -146,7 +146,7 @@ public struct Client: APIProtocol { try converter.setHeaderFieldAsJSON( in: &request.headerFields, name: "X-Extra-Arguments", - value: input.headers.X_Extra_Arguments + value: input.headers.X_hyphen_Extra_hyphen_Arguments ) converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) switch input.body { @@ -163,7 +163,7 @@ public struct Client: APIProtocol { switch response.statusCode { case 201: let headers: Operations.createPet.Output.Created.Headers = .init( - X_Extra_Arguments: try converter.getOptionalHeaderFieldAsJSON( + X_hyphen_Extra_hyphen_Arguments: try converter.getOptionalHeaderFieldAsJSON( in: response.headerFields, name: "X-Extra-Arguments", as: Components.Schemas.CodeError.self @@ -185,7 +185,7 @@ public struct Client: APIProtocol { return .created(.init(headers: headers, body: body)) case 400...499: let headers: Components.Responses.ErrorBadRequest.Headers = .init( - X_Reason: try converter.getOptionalHeaderFieldAsURI( + X_hyphen_Reason: try converter.getOptionalHeaderFieldAsURI( in: response.headerFields, name: "X-Reason", as: Swift.String.self @@ -236,6 +236,21 @@ public struct Client: APIProtocol { from: response.body, transforming: { value in .json(value) } ) + } else if try converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") { + body = try converter.getResponseBodyAsString( + Swift.String.self, + from: response.body, + transforming: { value in .plainText(value) } + ) + } else if try converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/octet-stream" + ) { + body = try converter.getResponseBodyAsBinary( + Foundation.Data.self, + from: response.body, + transforming: { value in .binary(value) } + ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } @@ -261,6 +276,18 @@ public struct Client: APIProtocol { headerFields: &request.headerFields, contentType: "application/json; charset=utf-8" ) + case let .plainText(value): + request.body = try converter.setRequiredRequestBodyAsString( + value, + headerFields: &request.headerFields, + contentType: "text/plain" + ) + case let .binary(value): + request.body = try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) } return request }, @@ -418,7 +445,7 @@ public struct Client: APIProtocol { body = try converter.getResponseBodyAsString( Swift.String.self, from: response.body, - transforming: { value in .text(value) } + transforming: { value in .plainText(value) } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift index c60a7a9f..ff42f68a 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift @@ -111,11 +111,11 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { style: .form, explode: true, name: "since", - as: Components.Parameters.query_born_since.self + as: Components.Parameters.query_period_born_hyphen_since.self ) ) let headers: Operations.listPets.Input.Headers = .init( - My_Request_UUID: try converter.getOptionalHeaderFieldAsURI( + My_hyphen_Request_hyphen_UUID: try converter.getOptionalHeaderFieldAsURI( in: request.headerFields, name: "My-Request-UUID", as: Swift.String.self @@ -140,12 +140,12 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { try converter.setHeaderFieldAsURI( in: &response.headerFields, name: "My-Response-UUID", - value: value.headers.My_Response_UUID + value: value.headers.My_hyphen_Response_hyphen_UUID ) try converter.setHeaderFieldAsURI( in: &response.headerFields, name: "My-Tracing-Header", - value: value.headers.My_Tracing_Header + value: value.headers.My_hyphen_Tracing_hyphen_Header ) switch value.body { case let .json(value): @@ -188,7 +188,7 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { deserializer: { request, metadata in let path: Operations.createPet.Input.Path = .init() let query: Operations.createPet.Input.Query = .init() let headers: Operations.createPet.Input.Headers = .init( - X_Extra_Arguments: try converter.getOptionalHeaderFieldAsJSON( + X_hyphen_Extra_hyphen_Arguments: try converter.getOptionalHeaderFieldAsJSON( in: request.headerFields, name: "X-Extra-Arguments", as: Components.Schemas.CodeError.self @@ -226,7 +226,7 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { try converter.setHeaderFieldAsJSON( in: &response.headerFields, name: "X-Extra-Arguments", - value: value.headers.X_Extra_Arguments + value: value.headers.X_hyphen_Extra_hyphen_Arguments ) switch value.body { case let .json(value): @@ -245,7 +245,7 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { try converter.setHeaderFieldAsURI( in: &response.headerFields, name: "X-Reason", - value: value.headers.X_Reason + value: value.headers.X_hyphen_Reason ) switch value.body { case let .json(value): @@ -298,6 +298,20 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { headerFields: &response.headerFields, contentType: "application/json; charset=utf-8" ) + case let .plainText(value): + try converter.validateAcceptIfPresent("text/plain", in: request.headerFields) + response.body = try converter.setResponseBodyAsString( + value, + headerFields: &response.headerFields, + contentType: "text/plain" + ) + case let .binary(value): + try converter.validateAcceptIfPresent("application/octet-stream", in: request.headerFields) + response.body = try converter.setResponseBodyAsBinary( + value, + headerFields: &response.headerFields, + contentType: "application/octet-stream" + ) } return response case let .undocumented(statusCode, _): return .init(statusCode: statusCode) @@ -327,6 +341,21 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { from: request.body, transforming: { value in .json(value) } ) + } else if try converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") { + body = try converter.getRequiredRequestBodyAsString( + Swift.String.self, + from: request.body, + transforming: { value in .plainText(value) } + ) + } else if try converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/octet-stream" + ) { + body = try converter.getRequiredRequestBodyAsBinary( + Foundation.Data.self, + from: request.body, + transforming: { value in .binary(value) } + ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } @@ -461,7 +490,7 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { petId: try converter.getPathParameterAsURI( in: metadata.pathParameters, name: "petId", - as: Components.Parameters.path_petId.self + as: Components.Parameters.path_period_petId.self ) ) let query: Operations.uploadAvatarForPet.Input.Query = .init() @@ -525,7 +554,7 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { var response = Response(statusCode: 500) suppressMutabilityWarning(&response) switch value.body { - case let .text(value): + case let .plainText(value): try converter.validateAcceptIfPresent("text/plain", in: request.headerFields) response.body = try converter.setResponseBodyAsString( value, diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift index 78c889aa..3f65c92d 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift @@ -95,38 +95,13 @@ public enum Components { /// Kind of pet /// /// - Remark: Generated from `#/components/schemas/PetKind`. - @frozen public enum PetKind: RawRepresentable, Codable, Hashable, Sendable, CaseIterable { - case cat - case dog - case ELEPHANT - case BIG_ELEPHANT_1 - case _nake - case _public - /// Parsed a raw value that was not defined in the OpenAPI document. - case undocumented(String) - public init?(rawValue: String) { - switch rawValue { - case "cat": self = .cat - case "dog": self = .dog - case "ELEPHANT": self = .ELEPHANT - case "BIG_ELEPHANT_1": self = .BIG_ELEPHANT_1 - case "$nake": self = ._nake - case "public": self = ._public - default: self = .undocumented(rawValue) - } - } - public var rawValue: String { - switch self { - case let .undocumented(string): return string - case .cat: return "cat" - case .dog: return "dog" - case .ELEPHANT: return "ELEPHANT" - case .BIG_ELEPHANT_1: return "BIG_ELEPHANT_1" - case ._nake: return "$nake" - case ._public: return "public" - } - } - public static var allCases: [Self] { [.cat, .dog, .ELEPHANT, .BIG_ELEPHANT_1, ._nake, ._public] } + @frozen public enum PetKind: String, Codable, Hashable, Sendable { + case cat = "cat" + case dog = "dog" + case ELEPHANT = "ELEPHANT" + case BIG_ELEPHANT_1 = "BIG_ELEPHANT_1" + case _dollar_nake = "$nake" + case _public = "public" } /// - Remark: Generated from `#/components/schemas/CreatePetRequest`. public struct CreatePetRequest: Codable, Hashable, Sendable { @@ -160,7 +135,7 @@ public enum Components { /// - Remark: Generated from `#/components/schemas/Error/code`. public var code: Swift.Int32 /// - Remark: Generated from `#/components/schemas/Error/me$sage`. - public var me_sage: Swift.String + public var me_dollar_sage: Swift.String /// Extra information about the error. /// /// - Remark: Generated from `#/components/schemas/Error/extraInfo`. @@ -173,23 +148,23 @@ public enum Components { /// /// - Parameters: /// - code: - /// - me_sage: + /// - me_dollar_sage: /// - extraInfo: Extra information about the error. /// - userData: Custom user-provided key-value pairs. public init( code: Swift.Int32, - me_sage: Swift.String, + me_dollar_sage: Swift.String, extraInfo: Components.Schemas.ExtraInfo? = nil, userData: OpenAPIRuntime.OpenAPIObjectContainer? = nil ) { self.code = code - self.me_sage = me_sage + self.me_dollar_sage = me_dollar_sage self.extraInfo = extraInfo self.userData = userData } public enum CodingKeys: String, CodingKey { case code - case me_sage = "me$sage" + case me_dollar_sage = "me$sage" case extraInfo case userData } @@ -197,29 +172,10 @@ public enum Components { /// - Remark: Generated from `#/components/schemas/PetFeeding`. public struct PetFeeding: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/PetFeeding/schedule`. - @frozen public enum schedulePayload: RawRepresentable, Codable, Hashable, Sendable, CaseIterable { - case hourly - case daily - case weekly - /// Parsed a raw value that was not defined in the OpenAPI document. - case undocumented(String) - public init?(rawValue: String) { - switch rawValue { - case "hourly": self = .hourly - case "daily": self = .daily - case "weekly": self = .weekly - default: self = .undocumented(rawValue) - } - } - public var rawValue: String { - switch self { - case let .undocumented(string): return string - case .hourly: return "hourly" - case .daily: return "daily" - case .weekly: return "weekly" - } - } - public static var allCases: [Self] { [.hourly, .daily, .weekly] } + @frozen public enum schedulePayload: String, Codable, Hashable, Sendable { + case hourly = "hourly" + case daily = "daily" + case weekly = "weekly" } /// - Remark: Generated from `#/components/schemas/PetFeeding/schedule`. public var schedule: Components.Schemas.PetFeeding.schedulePayload? @@ -415,8 +371,6 @@ public enum Components { } /// - Remark: Generated from `#/components/schemas/OneOfAny/case4`. case case4(Components.Schemas.OneOfAny.Case4Payload) - /// Parsed a case that was not defined in the OpenAPI document. - case undocumented(OpenAPIRuntime.OpenAPIValueContainer) public init(from decoder: any Decoder) throws { do { self = .case1(try .init(from: decoder)) @@ -434,9 +388,7 @@ public enum Components { self = .case4(try .init(from: decoder)) return } catch {} - let container = try decoder.singleValueContainer() - let value = try container.decode(OpenAPIRuntime.OpenAPIValueContainer.self) - self = .undocumented(value) + throw DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) } public func encode(to encoder: any Encoder) throws { switch self { @@ -444,7 +396,6 @@ public enum Components { case let .case2(value): try value.encode(to: encoder) case let .CodeError(value): try value.encode(to: encoder) case let .case4(value): try value.encode(to: encoder) - case let .undocumented(value): try value.encode(to: encoder) } } } @@ -523,8 +474,6 @@ public enum Components { case Walk(Components.Schemas.Walk) /// - Remark: Generated from `#/components/schemas/OneOfObjectsWithDiscriminator/MessagedExercise`. case MessagedExercise(Components.Schemas.MessagedExercise) - /// Parsed a case that was not defined in the OpenAPI document. - case undocumented(OpenAPIRuntime.OpenAPIObjectContainer) public enum CodingKeys: String, CodingKey { case kind } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -533,17 +482,13 @@ public enum Components { case "Walk", "#/components/schemas/Walk": self = .Walk(try .init(from: decoder)) case "MessagedExercise", "#/components/schemas/MessagedExercise": self = .MessagedExercise(try .init(from: decoder)) - default: - let container = try decoder.singleValueContainer() - let value = try container.decode(OpenAPIRuntime.OpenAPIObjectContainer.self) - self = .undocumented(value) + default: throw DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) } } public func encode(to encoder: any Encoder) throws { switch self { case let .Walk(value): try value.encode(to: encoder) case let .MessagedExercise(value): try value.encode(to: encoder) - case let .undocumented(value): try value.encode(to: encoder) } } } @@ -581,15 +526,15 @@ public enum Components { /// Supply this parameter to filter pets born since the provided date. /// /// - Remark: Generated from `#/components/parameters/query.born-since`. - public typealias query_born_since = Components.Schemas.DOB + public typealias query_period_born_hyphen_since = Components.Schemas.DOB /// The id of the pet to retrieve /// /// - Remark: Generated from `#/components/parameters/path.petId`. - public typealias path_petId = Swift.Int64 + public typealias path_period_petId = Swift.Int64 /// A deprecated header parameter /// /// - Remark: Generated from `#/components/parameters/header.deprecatedHeader`. - public typealias header_deprecatedHeader = Swift.String + public typealias header_period_deprecatedHeader = Swift.String } /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. public enum RequestBodies { @@ -638,12 +583,12 @@ public enum Components { /// A description here. /// /// - Remark: Generated from `#/components/responses/ErrorBadRequest/headers/X-Reason`. - public var X_Reason: Swift.String? + public var X_hyphen_Reason: Swift.String? /// Creates a new `Headers`. /// /// - Parameters: - /// - X_Reason: A description here. - public init(X_Reason: Swift.String? = nil) { self.X_Reason = X_Reason } + /// - X_hyphen_Reason: A description here. + public init(X_hyphen_Reason: Swift.String? = nil) { self.X_hyphen_Reason = X_hyphen_Reason } } /// Received HTTP response headers public var headers: Components.Responses.ErrorBadRequest.Headers @@ -712,59 +657,19 @@ public enum Operations { /// - Remark: Generated from `#/paths/pets/GET/query/limit`. public var limit: Swift.Int32? /// - Remark: Generated from `#/paths/pets/GET/query/habitat`. - @frozen public enum habitatPayload: RawRepresentable, Codable, Hashable, Sendable, CaseIterable { - case water - case land - case air - case _empty - /// Parsed a raw value that was not defined in the OpenAPI document. - case undocumented(String) - public init?(rawValue: String) { - switch rawValue { - case "water": self = .water - case "land": self = .land - case "air": self = .air - case "": self = ._empty - default: self = .undocumented(rawValue) - } - } - public var rawValue: String { - switch self { - case let .undocumented(string): return string - case .water: return "water" - case .land: return "land" - case .air: return "air" - case ._empty: return "" - } - } - public static var allCases: [Self] { [.water, .land, .air, ._empty] } + @frozen public enum habitatPayload: String, Codable, Hashable, Sendable { + case water = "water" + case land = "land" + case air = "air" + case _empty = "" } /// - Remark: Generated from `#/paths/pets/GET/query/habitat`. public var habitat: Operations.listPets.Input.Query.habitatPayload? /// - Remark: Generated from `#/paths/pets/GET/query/feedsPayload`. - @frozen public enum feedsPayloadPayload: RawRepresentable, Codable, Hashable, Sendable, CaseIterable { - case omnivore - case carnivore - case herbivore - /// Parsed a raw value that was not defined in the OpenAPI document. - case undocumented(String) - public init?(rawValue: String) { - switch rawValue { - case "omnivore": self = .omnivore - case "carnivore": self = .carnivore - case "herbivore": self = .herbivore - default: self = .undocumented(rawValue) - } - } - public var rawValue: String { - switch self { - case let .undocumented(string): return string - case .omnivore: return "omnivore" - case .carnivore: return "carnivore" - case .herbivore: return "herbivore" - } - } - public static var allCases: [Self] { [.omnivore, .carnivore, .herbivore] } + @frozen public enum feedsPayloadPayload: String, Codable, Hashable, Sendable { + case omnivore = "omnivore" + case carnivore = "carnivore" + case herbivore = "herbivore" } /// - Remark: Generated from `#/paths/pets/GET/query/feeds`. public typealias feedsPayload = [Operations.listPets.Input.Query.feedsPayloadPayload] @@ -773,7 +678,7 @@ public enum Operations { /// Supply this parameter to filter pets born since the provided date. /// /// - Remark: Generated from `#/paths/pets/GET/query/since`. - public var since: Components.Parameters.query_born_since? + public var since: Components.Parameters.query_period_born_hyphen_since? /// Creates a new `Query`. /// /// - Parameters: @@ -785,7 +690,7 @@ public enum Operations { limit: Swift.Int32? = nil, habitat: Operations.listPets.Input.Query.habitatPayload? = nil, feeds: Operations.listPets.Input.Query.feedsPayload? = nil, - since: Components.Parameters.query_born_since? = nil + since: Components.Parameters.query_period_born_hyphen_since? = nil ) { self.limit = limit self.habitat = habitat @@ -799,19 +704,19 @@ public enum Operations { /// Request identifier /// /// - Remark: Generated from `#/paths/pets/GET/header/My-Request-UUID`. - public var My_Request_UUID: Swift.String? + public var My_hyphen_Request_hyphen_UUID: Swift.String? public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: - /// - My_Request_UUID: Request identifier + /// - My_hyphen_Request_hyphen_UUID: Request identifier /// - accept: public init( - My_Request_UUID: Swift.String? = nil, + My_hyphen_Request_hyphen_UUID: Swift.String? = nil, accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() ) { - self.My_Request_UUID = My_Request_UUID + self.My_hyphen_Request_hyphen_UUID = My_hyphen_Request_hyphen_UUID self.accept = accept } } @@ -854,22 +759,22 @@ public enum Operations { /// Response identifier /// /// - Remark: Generated from `#/paths/pets/GET/responses/200/headers/My-Response-UUID`. - public var My_Response_UUID: Swift.String + public var My_hyphen_Response_hyphen_UUID: Swift.String /// A description here. /// /// - Remark: Generated from `#/paths/pets/GET/responses/200/headers/My-Tracing-Header`. - public var My_Tracing_Header: Components.Headers.TracingHeader? + public var My_hyphen_Tracing_hyphen_Header: Components.Headers.TracingHeader? /// Creates a new `Headers`. /// /// - Parameters: - /// - My_Response_UUID: Response identifier - /// - My_Tracing_Header: A description here. + /// - My_hyphen_Response_hyphen_UUID: Response identifier + /// - My_hyphen_Tracing_hyphen_Header: A description here. public init( - My_Response_UUID: Swift.String, - My_Tracing_Header: Components.Headers.TracingHeader? = nil + My_hyphen_Response_hyphen_UUID: Swift.String, + My_hyphen_Tracing_hyphen_Header: Components.Headers.TracingHeader? = nil ) { - self.My_Response_UUID = My_Response_UUID - self.My_Tracing_Header = My_Tracing_Header + self.My_hyphen_Response_hyphen_UUID = My_hyphen_Response_hyphen_UUID + self.My_hyphen_Tracing_hyphen_Header = My_hyphen_Tracing_hyphen_Header } } /// Received HTTP response headers @@ -974,19 +879,19 @@ public enum Operations { /// A description here. /// /// - Remark: Generated from `#/paths/pets/POST/header/X-Extra-Arguments`. - public var X_Extra_Arguments: Components.Schemas.CodeError? + public var X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: - /// - X_Extra_Arguments: A description here. + /// - X_hyphen_Extra_hyphen_Arguments: A description here. /// - accept: public init( - X_Extra_Arguments: Components.Schemas.CodeError? = nil, + X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? = nil, accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() ) { - self.X_Extra_Arguments = X_Extra_Arguments + self.X_hyphen_Extra_hyphen_Arguments = X_hyphen_Extra_hyphen_Arguments self.accept = accept } } @@ -1032,13 +937,13 @@ public enum Operations { /// A description here. /// /// - Remark: Generated from `#/paths/pets/POST/responses/201/headers/X-Extra-Arguments`. - public var X_Extra_Arguments: Components.Schemas.CodeError? + public var X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? /// Creates a new `Headers`. /// /// - Parameters: - /// - X_Extra_Arguments: A description here. - public init(X_Extra_Arguments: Components.Schemas.CodeError? = nil) { - self.X_Extra_Arguments = X_Extra_Arguments + /// - X_hyphen_Extra_hyphen_Arguments: A description here. + public init(X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? = nil) { + self.X_hyphen_Extra_hyphen_Arguments = X_hyphen_Extra_hyphen_Arguments } } /// Received HTTP response headers @@ -1172,6 +1077,10 @@ public enum Operations { @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/content/application\/json`. case json(Components.Schemas.PetStats) + /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/content/text\/plain`. + case plainText(Swift.String) + /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/content/application\/octet-stream`. + case binary(Foundation.Data) } /// Received HTTP response body public var body: Operations.getStats.Output.Ok.Body @@ -1201,10 +1110,14 @@ public enum Operations { } @frozen public enum AcceptableContentType: AcceptableProtocol { case json + case plainText + case binary case other(String) public init?(rawValue: String) { switch rawValue.lowercased() { case "application/json": self = .json + case "text/plain": self = .plainText + case "application/octet-stream": self = .binary default: self = .other(rawValue) } } @@ -1212,9 +1125,11 @@ public enum Operations { switch self { case let .other(string): return string case .json: return "application/json" + case .plainText: return "text/plain" + case .binary: return "application/octet-stream" } } - public static var allCases: [Self] { [.json] } + public static var allCases: [Self] { [.json, .plainText, .binary] } } } /// - Remark: HTTP `POST /pets/stats`. @@ -1250,6 +1165,10 @@ public enum Operations { @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/pets/stats/POST/requestBody/content/application\/json`. case json(Components.Schemas.PetStats) + /// - Remark: Generated from `#/paths/pets/stats/POST/requestBody/content/text\/plain`. + case plainText(Swift.String) + /// - Remark: Generated from `#/paths/pets/stats/POST/requestBody/content/application\/octet-stream`. + case binary(Foundation.Data) } public var body: Operations.postStats.Input.Body /// Creates a new `Input`. @@ -1584,12 +1503,12 @@ public enum Operations { /// The id of the pet to retrieve /// /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/path/petId`. - public var petId: Components.Parameters.path_petId + public var petId: Components.Parameters.path_period_petId /// Creates a new `Path`. /// /// - Parameters: /// - petId: The id of the pet to retrieve - public init(petId: Components.Parameters.path_petId) { self.petId = petId } + public init(petId: Components.Parameters.path_period_petId) { self.petId = petId } } public var path: Operations.uploadAvatarForPet.Input.Path /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/query`. @@ -1727,7 +1646,7 @@ public enum Operations { /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/500/content`. @frozen public enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/500/content/text\/plain`. - case text(Swift.String) + case plainText(Swift.String) } /// Received HTTP response body public var body: Operations.uploadAvatarForPet.Output.InternalServerError.Body @@ -1758,13 +1677,13 @@ public enum Operations { @frozen public enum AcceptableContentType: AcceptableProtocol { case binary case json - case text + case plainText case other(String) public init?(rawValue: String) { switch rawValue.lowercased() { case "application/octet-stream": self = .binary case "application/json": self = .json - case "text/plain": self = .text + case "text/plain": self = .plainText default: self = .other(rawValue) } } @@ -1773,10 +1692,10 @@ public enum Operations { case let .other(string): return string case .binary: return "application/octet-stream" case .json: return "application/json" - case .text: return "text/plain" + case .plainText: return "text/plain" } } - public static var allCases: [Self] { [.binary, .json, .text] } + public static var allCases: [Self] { [.binary, .json, .plainText] } } } } diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Client.swift deleted file mode 100644 index b5a599c5..00000000 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Client.swift +++ /dev/null @@ -1,459 +0,0 @@ -// Generated by swift-openapi-generator, do not modify. -@_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import Foundation -#else -import Foundation -#endif -/// Service for managing pet metadata. -/// -/// Because why not. -public struct Client: APIProtocol { - /// The underlying HTTP client. - private let client: UniversalClient - /// Creates a new client. - /// - Parameters: - /// - serverURL: The server URL that the client connects to. Any server - /// URLs defined in the OpenAPI document are available as static methods - /// on the ``Servers`` type. - /// - configuration: A set of configuration values for the client. - /// - transport: A transport that performs HTTP operations. - /// - middlewares: A list of middlewares to call before the transport. - public init( - serverURL: URL, - configuration: Configuration = .init(), - transport: any ClientTransport, - middlewares: [any ClientMiddleware] = [] - ) { - self.client = .init( - serverURL: serverURL, - configuration: configuration, - transport: transport, - middlewares: middlewares - ) - } - private var converter: Converter { client.converter } - /// List all pets - /// - /// You can fetch - /// all the pets here - /// - /// - Remark: HTTP `GET /pets`. - /// - Remark: Generated from `#/paths//pets/get(listPets)`. - public func listPets(_ input: Operations.listPets.Input) async throws -> Operations.listPets.Output { - try await client.send( - input: input, - forOperation: Operations.listPets.id, - serializer: { input in let path = try converter.renderedPath(template: "/pets", parameters: []) - var request: OpenAPIRuntime.Request = .init(path: path, method: .get) - suppressMutabilityWarning(&request) - try converter.setQueryItemAsURI( - in: &request, - style: .form, - explode: true, - name: "limit", - value: input.query.limit - ) - try converter.setQueryItemAsURI( - in: &request, - style: .form, - explode: true, - name: "habitat", - value: input.query.habitat - ) - try converter.setQueryItemAsURI( - in: &request, - style: .form, - explode: true, - name: "feeds", - value: input.query.feeds - ) - try converter.setHeaderFieldAsURI( - in: &request.headerFields, - name: "My-Request-UUID", - value: input.headers.My_hyphen_Request_hyphen_UUID - ) - try converter.setQueryItemAsURI( - in: &request, - style: .form, - explode: true, - name: "since", - value: input.query.since - ) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) - return request - }, - deserializer: { response in - switch response.statusCode { - case 200: - let headers: Operations.listPets.Output.Ok.Headers = .init( - My_hyphen_Response_hyphen_UUID: try converter.getRequiredHeaderFieldAsURI( - in: response.headerFields, - name: "My-Response-UUID", - as: Swift.String.self - ), - My_hyphen_Tracing_hyphen_Header: try converter.getOptionalHeaderFieldAsURI( - in: response.headerFields, - name: "My-Tracing-Header", - as: Components.Headers.TracingHeader.self - ) - ) - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.listPets.Output.Ok.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getResponseBodyAsJSON( - Components.Schemas.Pets.self, - from: response.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .ok(.init(headers: headers, body: body)) - default: - let headers: Operations.listPets.Output.Default.Headers = .init() - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.listPets.Output.Default.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getResponseBodyAsJSON( - Components.Schemas._Error.self, - from: response.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .`default`(statusCode: response.statusCode, .init(headers: headers, body: body)) - } - } - ) - } - /// Create a pet - /// - /// - Remark: HTTP `POST /pets`. - /// - Remark: Generated from `#/paths//pets/post(createPet)`. - public func createPet(_ input: Operations.createPet.Input) async throws -> Operations.createPet.Output { - try await client.send( - input: input, - forOperation: Operations.createPet.id, - serializer: { input in let path = try converter.renderedPath(template: "/pets", parameters: []) - var request: OpenAPIRuntime.Request = .init(path: path, method: .post) - suppressMutabilityWarning(&request) - try converter.setHeaderFieldAsJSON( - in: &request.headerFields, - name: "X-Extra-Arguments", - value: input.headers.X_hyphen_Extra_hyphen_Arguments - ) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) - switch input.body { - case let .json(value): - request.body = try converter.setRequiredRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return request - }, - deserializer: { response in - switch response.statusCode { - case 201: - let headers: Operations.createPet.Output.Created.Headers = .init( - X_hyphen_Extra_hyphen_Arguments: try converter.getOptionalHeaderFieldAsJSON( - in: response.headerFields, - name: "X-Extra-Arguments", - as: Components.Schemas.CodeError.self - ) - ) - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.createPet.Output.Created.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getResponseBodyAsJSON( - Components.Schemas.Pet.self, - from: response.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .created(.init(headers: headers, body: body)) - case 400...499: - let headers: Components.Responses.ErrorBadRequest.Headers = .init( - X_hyphen_Reason: try converter.getOptionalHeaderFieldAsURI( - in: response.headerFields, - name: "X-Reason", - as: Swift.String.self - ) - ) - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Components.Responses.ErrorBadRequest.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getResponseBodyAsJSON( - Components.Responses.ErrorBadRequest.Body.jsonPayload.self, - from: response.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .clientError(statusCode: response.statusCode, .init(headers: headers, body: body)) - default: return .undocumented(statusCode: response.statusCode, .init()) - } - } - ) - } - /// - Remark: HTTP `GET /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/get(getStats)`. - public func getStats(_ input: Operations.getStats.Input) async throws -> Operations.getStats.Output { - try await client.send( - input: input, - forOperation: Operations.getStats.id, - serializer: { input in let path = try converter.renderedPath(template: "/pets/stats", parameters: []) - var request: OpenAPIRuntime.Request = .init(path: path, method: .get) - suppressMutabilityWarning(&request) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) - return request - }, - deserializer: { response in - switch response.statusCode { - case 200: - let headers: Operations.getStats.Output.Ok.Headers = .init() - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.getStats.Output.Ok.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getResponseBodyAsJSON( - Components.Schemas.PetStats.self, - from: response.body, - transforming: { value in .json(value) } - ) - } else if try converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") { - body = try converter.getResponseBodyAsString( - Swift.String.self, - from: response.body, - transforming: { value in .plainText(value) } - ) - } else if try converter.isMatchingContentType( - received: contentType, - expectedRaw: "application/octet-stream" - ) { - body = try converter.getResponseBodyAsBinary( - Foundation.Data.self, - from: response.body, - transforming: { value in .binary(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .ok(.init(headers: headers, body: body)) - default: return .undocumented(statusCode: response.statusCode, .init()) - } - } - ) - } - /// - Remark: HTTP `POST /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/post(postStats)`. - public func postStats(_ input: Operations.postStats.Input) async throws -> Operations.postStats.Output { - try await client.send( - input: input, - forOperation: Operations.postStats.id, - serializer: { input in let path = try converter.renderedPath(template: "/pets/stats", parameters: []) - var request: OpenAPIRuntime.Request = .init(path: path, method: .post) - suppressMutabilityWarning(&request) - switch input.body { - case let .json(value): - request.body = try converter.setRequiredRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - case let .plainText(value): - request.body = try converter.setRequiredRequestBodyAsString( - value, - headerFields: &request.headerFields, - contentType: "text/plain" - ) - case let .binary(value): - request.body = try converter.setRequiredRequestBodyAsBinary( - value, - headerFields: &request.headerFields, - contentType: "application/octet-stream" - ) - } - return request - }, - deserializer: { response in - switch response.statusCode { - case 202: - let headers: Operations.postStats.Output.Accepted.Headers = .init() - return .accepted(.init(headers: headers, body: nil)) - default: return .undocumented(statusCode: response.statusCode, .init()) - } - } - ) - } - /// - Remark: HTTP `POST /probe/`. - /// - Remark: Generated from `#/paths//probe//post(probe)`. - @available(*, deprecated) public func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output - { - try await client.send( - input: input, - forOperation: Operations.probe.id, - serializer: { input in let path = try converter.renderedPath(template: "/probe/", parameters: []) - var request: OpenAPIRuntime.Request = .init(path: path, method: .post) - suppressMutabilityWarning(&request) - return request - }, - deserializer: { response in - switch response.statusCode { - case 204: - let headers: Operations.probe.Output.NoContent.Headers = .init() - return .noContent(.init(headers: headers, body: nil)) - default: return .undocumented(statusCode: response.statusCode, .init()) - } - } - ) - } - /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. - /// - /// - Remark: HTTP `PATCH /pets/{petId}`. - /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. - public func updatePet(_ input: Operations.updatePet.Input) async throws -> Operations.updatePet.Output { - try await client.send( - input: input, - forOperation: Operations.updatePet.id, - serializer: { input in - let path = try converter.renderedPath(template: "/pets/{}", parameters: [input.path.petId]) - var request: OpenAPIRuntime.Request = .init(path: path, method: .patch) - suppressMutabilityWarning(&request) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) - switch input.body { - case .none: request.body = nil - case let .json(value): - request.body = try converter.setOptionalRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return request - }, - deserializer: { response in - switch response.statusCode { - case 204: - let headers: Operations.updatePet.Output.NoContent.Headers = .init() - return .noContent(.init(headers: headers, body: nil)) - case 400: - let headers: Operations.updatePet.Output.BadRequest.Headers = .init() - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.updatePet.Output.BadRequest.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getResponseBodyAsJSON( - Operations.updatePet.Output.BadRequest.Body.jsonPayload.self, - from: response.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .badRequest(.init(headers: headers, body: body)) - default: return .undocumented(statusCode: response.statusCode, .init()) - } - } - ) - } - /// Upload an avatar - /// - /// - Remark: HTTP `PUT /pets/{petId}/avatar`. - /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. - public func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws - -> Operations.uploadAvatarForPet.Output - { - try await client.send( - input: input, - forOperation: Operations.uploadAvatarForPet.id, - serializer: { input in - let path = try converter.renderedPath(template: "/pets/{}/avatar", parameters: [input.path.petId]) - var request: OpenAPIRuntime.Request = .init(path: path, method: .put) - suppressMutabilityWarning(&request) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) - switch input.body { - case let .binary(value): - request.body = try converter.setRequiredRequestBodyAsBinary( - value, - headerFields: &request.headerFields, - contentType: "application/octet-stream" - ) - } - return request - }, - deserializer: { response in - switch response.statusCode { - case 200: - let headers: Operations.uploadAvatarForPet.Output.Ok.Headers = .init() - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.uploadAvatarForPet.Output.Ok.Body - if try contentType == nil - || converter.isMatchingContentType( - received: contentType, - expectedRaw: "application/octet-stream" - ) - { - body = try converter.getResponseBodyAsBinary( - Foundation.Data.self, - from: response.body, - transforming: { value in .binary(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .ok(.init(headers: headers, body: body)) - case 412: - let headers: Operations.uploadAvatarForPet.Output.PreconditionFailed.Headers = .init() - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.uploadAvatarForPet.Output.PreconditionFailed.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getResponseBodyAsJSON( - Swift.String.self, - from: response.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .preconditionFailed(.init(headers: headers, body: body)) - case 500: - let headers: Operations.uploadAvatarForPet.Output.InternalServerError.Headers = .init() - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.uploadAvatarForPet.Output.InternalServerError.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") - { - body = try converter.getResponseBodyAsString( - Swift.String.self, - from: response.body, - transforming: { value in .plainText(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return .internalServerError(.init(headers: headers, body: body)) - default: return .undocumented(statusCode: response.statusCode, .init()) - } - } - ) - } -} diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Server.swift deleted file mode 100644 index ff42f68a..00000000 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Server.swift +++ /dev/null @@ -1,571 +0,0 @@ -// Generated by swift-openapi-generator, do not modify. -@_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import Foundation -#else -import Foundation -#endif -extension APIProtocol { - /// Registers each operation handler with the provided transport. - /// - Parameters: - /// - transport: A transport to which to register the operation handlers. - /// - serverURL: A URL used to determine the path prefix for registered - /// request handlers. - /// - configuration: A set of configuration values for the server. - /// - middlewares: A list of middlewares to call before the handler. - public func registerHandlers( - on transport: any ServerTransport, - serverURL: URL = .defaultOpenAPIServerURL, - configuration: Configuration = .init(), - middlewares: [any ServerMiddleware] = [] - ) throws { - let server = UniversalServer( - serverURL: serverURL, - handler: self, - configuration: configuration, - middlewares: middlewares - ) - try transport.register( - { try await server.listPets(request: $0, metadata: $1) }, - method: .get, - path: server.apiPathComponentsWithServerPrefix(["pets"]), - queryItemNames: ["limit", "habitat", "feeds", "since"] - ) - try transport.register( - { try await server.createPet(request: $0, metadata: $1) }, - method: .post, - path: server.apiPathComponentsWithServerPrefix(["pets"]), - queryItemNames: [] - ) - try transport.register( - { try await server.getStats(request: $0, metadata: $1) }, - method: .get, - path: server.apiPathComponentsWithServerPrefix(["pets", "stats"]), - queryItemNames: [] - ) - try transport.register( - { try await server.postStats(request: $0, metadata: $1) }, - method: .post, - path: server.apiPathComponentsWithServerPrefix(["pets", "stats"]), - queryItemNames: [] - ) - try transport.register( - { try await server.probe(request: $0, metadata: $1) }, - method: .post, - path: server.apiPathComponentsWithServerPrefix(["probe"]), - queryItemNames: [] - ) - try transport.register( - { try await server.updatePet(request: $0, metadata: $1) }, - method: .patch, - path: server.apiPathComponentsWithServerPrefix(["pets", ":petId"]), - queryItemNames: [] - ) - try transport.register( - { try await server.uploadAvatarForPet(request: $0, metadata: $1) }, - method: .put, - path: server.apiPathComponentsWithServerPrefix(["pets", ":petId", "avatar"]), - queryItemNames: [] - ) - } -} -fileprivate extension UniversalServer where APIHandler: APIProtocol { - /// List all pets - /// - /// You can fetch - /// all the pets here - /// - /// - Remark: HTTP `GET /pets`. - /// - Remark: Generated from `#/paths//pets/get(listPets)`. - func listPets(request: Request, metadata: ServerRequestMetadata) async throws -> Response { - try await handle( - request: request, - with: metadata, - forOperation: Operations.listPets.id, - using: { APIHandler.listPets($0) }, - deserializer: { request, metadata in let path: Operations.listPets.Input.Path = .init() - let query: Operations.listPets.Input.Query = .init( - limit: try converter.getOptionalQueryItemAsURI( - in: request.query, - style: .form, - explode: true, - name: "limit", - as: Swift.Int32.self - ), - habitat: try converter.getOptionalQueryItemAsURI( - in: request.query, - style: .form, - explode: true, - name: "habitat", - as: Operations.listPets.Input.Query.habitatPayload.self - ), - feeds: try converter.getOptionalQueryItemAsURI( - in: request.query, - style: .form, - explode: true, - name: "feeds", - as: Operations.listPets.Input.Query.feedsPayload.self - ), - since: try converter.getOptionalQueryItemAsURI( - in: request.query, - style: .form, - explode: true, - name: "since", - as: Components.Parameters.query_period_born_hyphen_since.self - ) - ) - let headers: Operations.listPets.Input.Headers = .init( - My_hyphen_Request_hyphen_UUID: try converter.getOptionalHeaderFieldAsURI( - in: request.headerFields, - name: "My-Request-UUID", - as: Swift.String.self - ), - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) - let cookies: Operations.listPets.Input.Cookies = .init() - return Operations.listPets.Input( - path: path, - query: query, - headers: headers, - cookies: cookies, - body: nil - ) - }, - serializer: { output, request in - switch output { - case let .ok(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 200) - suppressMutabilityWarning(&response) - try converter.setHeaderFieldAsURI( - in: &response.headerFields, - name: "My-Response-UUID", - value: value.headers.My_hyphen_Response_hyphen_UUID - ) - try converter.setHeaderFieldAsURI( - in: &response.headerFields, - name: "My-Tracing-Header", - value: value.headers.My_hyphen_Tracing_hyphen_Header - ) - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) - response.body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return response - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = Response(statusCode: statusCode) - suppressMutabilityWarning(&response) - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) - response.body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return response - } - } - ) - } - /// Create a pet - /// - /// - Remark: HTTP `POST /pets`. - /// - Remark: Generated from `#/paths//pets/post(createPet)`. - func createPet(request: Request, metadata: ServerRequestMetadata) async throws -> Response { - try await handle( - request: request, - with: metadata, - forOperation: Operations.createPet.id, - using: { APIHandler.createPet($0) }, - deserializer: { request, metadata in let path: Operations.createPet.Input.Path = .init() - let query: Operations.createPet.Input.Query = .init() - let headers: Operations.createPet.Input.Headers = .init( - X_hyphen_Extra_hyphen_Arguments: try converter.getOptionalHeaderFieldAsJSON( - in: request.headerFields, - name: "X-Extra-Arguments", - as: Components.Schemas.CodeError.self - ), - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) - let cookies: Operations.createPet.Input.Cookies = .init() - let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) - let body: Operations.createPet.Input.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getRequiredRequestBodyAsJSON( - Components.Schemas.CreatePetRequest.self, - from: request.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return Operations.createPet.Input( - path: path, - query: query, - headers: headers, - cookies: cookies, - body: body - ) - }, - serializer: { output, request in - switch output { - case let .created(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 201) - suppressMutabilityWarning(&response) - try converter.setHeaderFieldAsJSON( - in: &response.headerFields, - name: "X-Extra-Arguments", - value: value.headers.X_hyphen_Extra_hyphen_Arguments - ) - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) - response.body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return response - case let .clientError(statusCode, value): - suppressUnusedWarning(value) - var response = Response(statusCode: statusCode) - suppressMutabilityWarning(&response) - try converter.setHeaderFieldAsURI( - in: &response.headerFields, - name: "X-Reason", - value: value.headers.X_hyphen_Reason - ) - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) - response.body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return response - case let .undocumented(statusCode, _): return .init(statusCode: statusCode) - } - } - ) - } - /// - Remark: HTTP `GET /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/get(getStats)`. - func getStats(request: Request, metadata: ServerRequestMetadata) async throws -> Response { - try await handle( - request: request, - with: metadata, - forOperation: Operations.getStats.id, - using: { APIHandler.getStats($0) }, - deserializer: { request, metadata in let path: Operations.getStats.Input.Path = .init() - let query: Operations.getStats.Input.Query = .init() - let headers: Operations.getStats.Input.Headers = .init( - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) - let cookies: Operations.getStats.Input.Cookies = .init() - return Operations.getStats.Input( - path: path, - query: query, - headers: headers, - cookies: cookies, - body: nil - ) - }, - serializer: { output, request in - switch output { - case let .ok(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 200) - suppressMutabilityWarning(&response) - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) - response.body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - case let .plainText(value): - try converter.validateAcceptIfPresent("text/plain", in: request.headerFields) - response.body = try converter.setResponseBodyAsString( - value, - headerFields: &response.headerFields, - contentType: "text/plain" - ) - case let .binary(value): - try converter.validateAcceptIfPresent("application/octet-stream", in: request.headerFields) - response.body = try converter.setResponseBodyAsBinary( - value, - headerFields: &response.headerFields, - contentType: "application/octet-stream" - ) - } - return response - case let .undocumented(statusCode, _): return .init(statusCode: statusCode) - } - } - ) - } - /// - Remark: HTTP `POST /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/post(postStats)`. - func postStats(request: Request, metadata: ServerRequestMetadata) async throws -> Response { - try await handle( - request: request, - with: metadata, - forOperation: Operations.postStats.id, - using: { APIHandler.postStats($0) }, - deserializer: { request, metadata in let path: Operations.postStats.Input.Path = .init() - let query: Operations.postStats.Input.Query = .init() - let headers: Operations.postStats.Input.Headers = .init() - let cookies: Operations.postStats.Input.Cookies = .init() - let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) - let body: Operations.postStats.Input.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getRequiredRequestBodyAsJSON( - Components.Schemas.PetStats.self, - from: request.body, - transforming: { value in .json(value) } - ) - } else if try converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") { - body = try converter.getRequiredRequestBodyAsString( - Swift.String.self, - from: request.body, - transforming: { value in .plainText(value) } - ) - } else if try converter.isMatchingContentType( - received: contentType, - expectedRaw: "application/octet-stream" - ) { - body = try converter.getRequiredRequestBodyAsBinary( - Foundation.Data.self, - from: request.body, - transforming: { value in .binary(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return Operations.postStats.Input( - path: path, - query: query, - headers: headers, - cookies: cookies, - body: body - ) - }, - serializer: { output, request in - switch output { - case let .accepted(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 202) - suppressMutabilityWarning(&response) - return response - case let .undocumented(statusCode, _): return .init(statusCode: statusCode) - } - } - ) - } - /// - Remark: HTTP `POST /probe/`. - /// - Remark: Generated from `#/paths//probe//post(probe)`. - @available(*, deprecated) func probe(request: Request, metadata: ServerRequestMetadata) async throws -> Response { - try await handle( - request: request, - with: metadata, - forOperation: Operations.probe.id, - using: { APIHandler.probe($0) }, - deserializer: { request, metadata in let path: Operations.probe.Input.Path = .init() - let query: Operations.probe.Input.Query = .init() - let headers: Operations.probe.Input.Headers = .init() - let cookies: Operations.probe.Input.Cookies = .init() - return Operations.probe.Input(path: path, query: query, headers: headers, cookies: cookies, body: nil) - }, - serializer: { output, request in - switch output { - case let .noContent(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 204) - suppressMutabilityWarning(&response) - return response - case let .undocumented(statusCode, _): return .init(statusCode: statusCode) - } - } - ) - } - /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. - /// - /// - Remark: HTTP `PATCH /pets/{petId}`. - /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. - func updatePet(request: Request, metadata: ServerRequestMetadata) async throws -> Response { - try await handle( - request: request, - with: metadata, - forOperation: Operations.updatePet.id, - using: { APIHandler.updatePet($0) }, - deserializer: { request, metadata in - let path: Operations.updatePet.Input.Path = .init( - petId: try converter.getPathParameterAsURI( - in: metadata.pathParameters, - name: "petId", - as: Swift.Int64.self - ) - ) - let query: Operations.updatePet.Input.Query = .init() - let headers: Operations.updatePet.Input.Headers = .init( - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) - let cookies: Operations.updatePet.Input.Cookies = .init() - let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) - let body: Components.RequestBodies.UpdatePetRequest? - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { - body = try converter.getOptionalRequestBodyAsJSON( - Components.RequestBodies.UpdatePetRequest.jsonPayload.self, - from: request.body, - transforming: { value in .json(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return Operations.updatePet.Input( - path: path, - query: query, - headers: headers, - cookies: cookies, - body: body - ) - }, - serializer: { output, request in - switch output { - case let .noContent(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 204) - suppressMutabilityWarning(&response) - return response - case let .badRequest(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 400) - suppressMutabilityWarning(&response) - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) - response.body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return response - case let .undocumented(statusCode, _): return .init(statusCode: statusCode) - } - } - ) - } - /// Upload an avatar - /// - /// - Remark: HTTP `PUT /pets/{petId}/avatar`. - /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. - func uploadAvatarForPet(request: Request, metadata: ServerRequestMetadata) async throws -> Response { - try await handle( - request: request, - with: metadata, - forOperation: Operations.uploadAvatarForPet.id, - using: { APIHandler.uploadAvatarForPet($0) }, - deserializer: { request, metadata in - let path: Operations.uploadAvatarForPet.Input.Path = .init( - petId: try converter.getPathParameterAsURI( - in: metadata.pathParameters, - name: "petId", - as: Components.Parameters.path_period_petId.self - ) - ) - let query: Operations.uploadAvatarForPet.Input.Query = .init() - let headers: Operations.uploadAvatarForPet.Input.Headers = .init( - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) - let cookies: Operations.uploadAvatarForPet.Input.Cookies = .init() - let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) - let body: Operations.uploadAvatarForPet.Input.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/octet-stream") - { - body = try converter.getRequiredRequestBodyAsBinary( - Foundation.Data.self, - from: request.body, - transforming: { value in .binary(value) } - ) - } else { - throw converter.makeUnexpectedContentTypeError(contentType: contentType) - } - return Operations.uploadAvatarForPet.Input( - path: path, - query: query, - headers: headers, - cookies: cookies, - body: body - ) - }, - serializer: { output, request in - switch output { - case let .ok(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 200) - suppressMutabilityWarning(&response) - switch value.body { - case let .binary(value): - try converter.validateAcceptIfPresent("application/octet-stream", in: request.headerFields) - response.body = try converter.setResponseBodyAsBinary( - value, - headerFields: &response.headerFields, - contentType: "application/octet-stream" - ) - } - return response - case let .preconditionFailed(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 412) - suppressMutabilityWarning(&response) - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) - response.body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return response - case let .internalServerError(value): - suppressUnusedWarning(value) - var response = Response(statusCode: 500) - suppressMutabilityWarning(&response) - switch value.body { - case let .plainText(value): - try converter.validateAcceptIfPresent("text/plain", in: request.headerFields) - response.body = try converter.setResponseBodyAsString( - value, - headerFields: &response.headerFields, - contentType: "text/plain" - ) - } - return response - case let .undocumented(statusCode, _): return .init(statusCode: statusCode) - } - } - ) - } -} diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Types.swift deleted file mode 100644 index 3f65c92d..00000000 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes/Types.swift +++ /dev/null @@ -1,1701 +0,0 @@ -// Generated by swift-openapi-generator, do not modify. -@_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import Foundation -#else -import Foundation -#endif -/// A type that performs HTTP operations defined by the OpenAPI document. -public protocol APIProtocol: Sendable { - /// List all pets - /// - /// You can fetch - /// all the pets here - /// - /// - Remark: HTTP `GET /pets`. - /// - Remark: Generated from `#/paths//pets/get(listPets)`. - func listPets(_ input: Operations.listPets.Input) async throws -> Operations.listPets.Output - /// Create a pet - /// - /// - Remark: HTTP `POST /pets`. - /// - Remark: Generated from `#/paths//pets/post(createPet)`. - func createPet(_ input: Operations.createPet.Input) async throws -> Operations.createPet.Output - /// - Remark: HTTP `GET /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/get(getStats)`. - func getStats(_ input: Operations.getStats.Input) async throws -> Operations.getStats.Output - /// - Remark: HTTP `POST /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/post(postStats)`. - func postStats(_ input: Operations.postStats.Input) async throws -> Operations.postStats.Output - /// - Remark: HTTP `POST /probe/`. - /// - Remark: Generated from `#/paths//probe//post(probe)`. - @available(*, deprecated) func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output - /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. - /// - /// - Remark: HTTP `PATCH /pets/{petId}`. - /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. - func updatePet(_ input: Operations.updatePet.Input) async throws -> Operations.updatePet.Output - /// Upload an avatar - /// - /// - Remark: HTTP `PUT /pets/{petId}/avatar`. - /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. - func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws - -> Operations.uploadAvatarForPet.Output -} -/// Server URLs defined in the OpenAPI document. -public enum Servers { - /// Example Petstore implementation service - public static func server1() throws -> URL { try URL(validatingOpenAPIServerURL: "https://example.com/api") } - public static func server2() throws -> URL { try URL(validatingOpenAPIServerURL: "/api") } -} -/// Types generated from the components section of the OpenAPI document. -public enum Components { - /// Types generated from the `#/components/schemas` section of the OpenAPI document. - public enum Schemas { - /// Pet metadata - /// - /// - Remark: Generated from `#/components/schemas/Pet`. - public struct Pet: Codable, Hashable, Sendable { - /// Pet id - /// - /// - Remark: Generated from `#/components/schemas/Pet/id`. - public var id: Swift.Int64 - /// Pet name - /// - /// - Remark: Generated from `#/components/schemas/Pet/name`. - public var name: Swift.String - /// - Remark: Generated from `#/components/schemas/Pet/tag`. - public var tag: Swift.String? - /// - Remark: Generated from `#/components/schemas/Pet/kind`. - public var kind: Components.Schemas.PetKind? - /// Creates a new `Pet`. - /// - /// - Parameters: - /// - id: Pet id - /// - name: Pet name - /// - tag: - /// - kind: - public init( - id: Swift.Int64, - name: Swift.String, - tag: Swift.String? = nil, - kind: Components.Schemas.PetKind? = nil - ) { - self.id = id - self.name = name - self.tag = tag - self.kind = kind - } - public enum CodingKeys: String, CodingKey { - case id - case name - case tag - case kind - } - } - /// Kind of pet - /// - /// - Remark: Generated from `#/components/schemas/PetKind`. - @frozen public enum PetKind: String, Codable, Hashable, Sendable { - case cat = "cat" - case dog = "dog" - case ELEPHANT = "ELEPHANT" - case BIG_ELEPHANT_1 = "BIG_ELEPHANT_1" - case _dollar_nake = "$nake" - case _public = "public" - } - /// - Remark: Generated from `#/components/schemas/CreatePetRequest`. - public struct CreatePetRequest: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/CreatePetRequest/name`. - public var name: Swift.String - /// - Remark: Generated from `#/components/schemas/CreatePetRequest/kind`. - public var kind: Components.Schemas.PetKind? - /// - Remark: Generated from `#/components/schemas/CreatePetRequest/tag`. - public var tag: Swift.String? - /// Creates a new `CreatePetRequest`. - /// - /// - Parameters: - /// - name: - /// - kind: - /// - tag: - public init(name: Swift.String, kind: Components.Schemas.PetKind? = nil, tag: Swift.String? = nil) { - self.name = name - self.kind = kind - self.tag = tag - } - public enum CodingKeys: String, CodingKey { - case name - case kind - case tag - } - } - /// - Remark: Generated from `#/components/schemas/Pets`. - public typealias Pets = [Components.Schemas.Pet] - /// - Remark: Generated from `#/components/schemas/Error`. - public struct _Error: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/Error/code`. - public var code: Swift.Int32 - /// - Remark: Generated from `#/components/schemas/Error/me$sage`. - public var me_dollar_sage: Swift.String - /// Extra information about the error. - /// - /// - Remark: Generated from `#/components/schemas/Error/extraInfo`. - public var extraInfo: Components.Schemas.ExtraInfo? - /// Custom user-provided key-value pairs. - /// - /// - Remark: Generated from `#/components/schemas/Error/userData`. - public var userData: OpenAPIRuntime.OpenAPIObjectContainer? - /// Creates a new `_Error`. - /// - /// - Parameters: - /// - code: - /// - me_dollar_sage: - /// - extraInfo: Extra information about the error. - /// - userData: Custom user-provided key-value pairs. - public init( - code: Swift.Int32, - me_dollar_sage: Swift.String, - extraInfo: Components.Schemas.ExtraInfo? = nil, - userData: OpenAPIRuntime.OpenAPIObjectContainer? = nil - ) { - self.code = code - self.me_dollar_sage = me_dollar_sage - self.extraInfo = extraInfo - self.userData = userData - } - public enum CodingKeys: String, CodingKey { - case code - case me_dollar_sage = "me$sage" - case extraInfo - case userData - } - } - /// - Remark: Generated from `#/components/schemas/PetFeeding`. - public struct PetFeeding: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/PetFeeding/schedule`. - @frozen public enum schedulePayload: String, Codable, Hashable, Sendable { - case hourly = "hourly" - case daily = "daily" - case weekly = "weekly" - } - /// - Remark: Generated from `#/components/schemas/PetFeeding/schedule`. - public var schedule: Components.Schemas.PetFeeding.schedulePayload? - /// Creates a new `PetFeeding`. - /// - /// - Parameters: - /// - schedule: - public init(schedule: Components.Schemas.PetFeeding.schedulePayload? = nil) { self.schedule = schedule } - public enum CodingKeys: String, CodingKey { case schedule } - } - /// - Remark: Generated from `#/components/schemas/DOB`. - public typealias DOB = Foundation.Date - /// - Remark: Generated from `#/components/schemas/ExtraInfo`. - public typealias ExtraInfo = Swift.String - /// - Remark: Generated from `#/components/schemas/NoAdditionalProperties`. - public struct NoAdditionalProperties: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/NoAdditionalProperties/foo`. - public var foo: Swift.String? - /// Creates a new `NoAdditionalProperties`. - /// - /// - Parameters: - /// - foo: - public init(foo: Swift.String? = nil) { self.foo = foo } - public enum CodingKeys: String, CodingKey { case foo } - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - foo = try container.decodeIfPresent(Swift.String.self, forKey: .foo) - try decoder.ensureNoAdditionalProperties(knownKeys: ["foo"]) - } - } - /// - Remark: Generated from `#/components/schemas/AnyAdditionalProperties`. - public struct AnyAdditionalProperties: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/AnyAdditionalProperties/foo`. - public var foo: Swift.String? - /// A container of undocumented properties. - public var additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer - /// Creates a new `AnyAdditionalProperties`. - /// - /// - Parameters: - /// - foo: - /// - additionalProperties: A container of undocumented properties. - public init(foo: Swift.String? = nil, additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer = .init()) - { - self.foo = foo - self.additionalProperties = additionalProperties - } - public enum CodingKeys: String, CodingKey { case foo } - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - foo = try container.decodeIfPresent(Swift.String.self, forKey: .foo) - additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: ["foo"]) - } - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encodeIfPresent(foo, forKey: .foo) - try encoder.encodeAdditionalProperties(additionalProperties) - } - } - /// - Remark: Generated from `#/components/schemas/TypedAdditionalProperties`. - public struct TypedAdditionalProperties: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/TypedAdditionalProperties/foo`. - public var foo: Swift.String? - /// A container of undocumented properties. - public var additionalProperties: [String: Swift.Int] - /// Creates a new `TypedAdditionalProperties`. - /// - /// - Parameters: - /// - foo: - /// - additionalProperties: A container of undocumented properties. - public init(foo: Swift.String? = nil, additionalProperties: [String: Swift.Int] = .init()) { - self.foo = foo - self.additionalProperties = additionalProperties - } - public enum CodingKeys: String, CodingKey { case foo } - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - foo = try container.decodeIfPresent(Swift.String.self, forKey: .foo) - additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: ["foo"]) - } - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encodeIfPresent(foo, forKey: .foo) - try encoder.encodeAdditionalProperties(additionalProperties) - } - } - /// - Remark: Generated from `#/components/schemas/CodeError`. - public struct CodeError: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/CodeError/code`. - public var code: Swift.Int - /// Creates a new `CodeError`. - /// - /// - Parameters: - /// - code: - public init(code: Swift.Int) { self.code = code } - public enum CodingKeys: String, CodingKey { case code } - } - /// - Remark: Generated from `#/components/schemas/AllOfObjects`. - public struct AllOfObjects: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/AllOfObjects/value1`. - public struct Value1Payload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/AllOfObjects/value1/message`. - public var message: Swift.String - /// Creates a new `Value1Payload`. - /// - /// - Parameters: - /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } - } - /// - Remark: Generated from `#/components/schemas/AllOfObjects/value1`. - public var value1: Components.Schemas.AllOfObjects.Value1Payload - /// - Remark: Generated from `#/components/schemas/AllOfObjects/value2`. - public var value2: Components.Schemas.CodeError - /// Creates a new `AllOfObjects`. - /// - /// - Parameters: - /// - value1: - /// - value2: - public init(value1: Components.Schemas.AllOfObjects.Value1Payload, value2: Components.Schemas.CodeError) { - self.value1 = value1 - self.value2 = value2 - } - public init(from decoder: any Decoder) throws { - value1 = try .init(from: decoder) - value2 = try .init(from: decoder) - } - public func encode(to encoder: any Encoder) throws { - try value1.encode(to: encoder) - try value2.encode(to: encoder) - } - } - /// - Remark: Generated from `#/components/schemas/AnyOfObjects`. - public struct AnyOfObjects: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/AnyOfObjects/value1`. - public struct Value1Payload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/AnyOfObjects/value1/message`. - public var message: Swift.String - /// Creates a new `Value1Payload`. - /// - /// - Parameters: - /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } - } - /// - Remark: Generated from `#/components/schemas/AnyOfObjects/value1`. - public var value1: Components.Schemas.AnyOfObjects.Value1Payload? - /// - Remark: Generated from `#/components/schemas/AnyOfObjects/value2`. - public var value2: Components.Schemas.CodeError? - /// Creates a new `AnyOfObjects`. - /// - /// - Parameters: - /// - value1: - /// - value2: - public init( - value1: Components.Schemas.AnyOfObjects.Value1Payload? = nil, - value2: Components.Schemas.CodeError? = nil - ) { - self.value1 = value1 - self.value2 = value2 - } - public init(from decoder: any Decoder) throws { - value1 = try? .init(from: decoder) - value2 = try? .init(from: decoder) - try DecodingError.verifyAtLeastOneSchemaIsNotNil( - [value1, value2], - type: Self.self, - codingPath: decoder.codingPath - ) - } - public func encode(to encoder: any Encoder) throws { - try value1?.encode(to: encoder) - try value2?.encode(to: encoder) - } - } - /// - Remark: Generated from `#/components/schemas/OneOfAny`. - @frozen public enum OneOfAny: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/OneOfAny/case1`. - case case1(Swift.String) - /// - Remark: Generated from `#/components/schemas/OneOfAny/case2`. - case case2(Swift.Int) - /// - Remark: Generated from `#/components/schemas/OneOfAny/case3`. - case CodeError(Components.Schemas.CodeError) - /// - Remark: Generated from `#/components/schemas/OneOfAny/case4`. - public struct Case4Payload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/OneOfAny/case4/message`. - public var message: Swift.String - /// Creates a new `Case4Payload`. - /// - /// - Parameters: - /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } - } - /// - Remark: Generated from `#/components/schemas/OneOfAny/case4`. - case case4(Components.Schemas.OneOfAny.Case4Payload) - public init(from decoder: any Decoder) throws { - do { - self = .case1(try .init(from: decoder)) - return - } catch {} - do { - self = .case2(try .init(from: decoder)) - return - } catch {} - do { - self = .CodeError(try .init(from: decoder)) - return - } catch {} - do { - self = .case4(try .init(from: decoder)) - return - } catch {} - throw DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) - } - public func encode(to encoder: any Encoder) throws { - switch self { - case let .case1(value): try value.encode(to: encoder) - case let .case2(value): try value.encode(to: encoder) - case let .CodeError(value): try value.encode(to: encoder) - case let .case4(value): try value.encode(to: encoder) - } - } - } - /// - Remark: Generated from `#/components/schemas/PetExercise`. - public struct PetExercise: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/PetExercise/kind`. - public var kind: Swift.String - /// Creates a new `PetExercise`. - /// - /// - Parameters: - /// - kind: - public init(kind: Swift.String) { self.kind = kind } - public enum CodingKeys: String, CodingKey { case kind } - } - /// - Remark: Generated from `#/components/schemas/Walk`. - public struct Walk: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/Walk/kind`. - public var kind: Swift.String - /// - Remark: Generated from `#/components/schemas/Walk/length`. - public var length: Swift.Int - /// Creates a new `Walk`. - /// - /// - Parameters: - /// - kind: - /// - length: - public init(kind: Swift.String, length: Swift.Int) { - self.kind = kind - self.length = length - } - public enum CodingKeys: String, CodingKey { - case kind - case length - } - } - /// - Remark: Generated from `#/components/schemas/MessagedExercise`. - public struct MessagedExercise: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/MessagedExercise/value1`. - public var value1: Components.Schemas.PetExercise - /// - Remark: Generated from `#/components/schemas/MessagedExercise/value2`. - public struct Value2Payload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/MessagedExercise/value2/message`. - public var message: Swift.String - /// Creates a new `Value2Payload`. - /// - /// - Parameters: - /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } - } - /// - Remark: Generated from `#/components/schemas/MessagedExercise/value2`. - public var value2: Components.Schemas.MessagedExercise.Value2Payload - /// Creates a new `MessagedExercise`. - /// - /// - Parameters: - /// - value1: - /// - value2: - public init( - value1: Components.Schemas.PetExercise, - value2: Components.Schemas.MessagedExercise.Value2Payload - ) { - self.value1 = value1 - self.value2 = value2 - } - public init(from decoder: any Decoder) throws { - value1 = try .init(from: decoder) - value2 = try .init(from: decoder) - } - public func encode(to encoder: any Encoder) throws { - try value1.encode(to: encoder) - try value2.encode(to: encoder) - } - } - /// - Remark: Generated from `#/components/schemas/OneOfObjectsWithDiscriminator`. - @frozen public enum OneOfObjectsWithDiscriminator: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/OneOfObjectsWithDiscriminator/Walk`. - case Walk(Components.Schemas.Walk) - /// - Remark: Generated from `#/components/schemas/OneOfObjectsWithDiscriminator/MessagedExercise`. - case MessagedExercise(Components.Schemas.MessagedExercise) - public enum CodingKeys: String, CodingKey { case kind } - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminator = try container.decode(String.self, forKey: .kind) - switch discriminator { - case "Walk", "#/components/schemas/Walk": self = .Walk(try .init(from: decoder)) - case "MessagedExercise", "#/components/schemas/MessagedExercise": - self = .MessagedExercise(try .init(from: decoder)) - default: throw DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) - } - } - public func encode(to encoder: any Encoder) throws { - switch self { - case let .Walk(value): try value.encode(to: encoder) - case let .MessagedExercise(value): try value.encode(to: encoder) - } - } - } - /// - Remark: Generated from `#/components/schemas/DeprecatedObject`. - @available(*, deprecated) public struct DeprecatedObject: Codable, Hashable, Sendable { - /// Creates a new `DeprecatedObject`. - public init() {} - public init(from decoder: any Decoder) throws { try decoder.ensureNoAdditionalProperties(knownKeys: []) } - } - /// - Remark: Generated from `#/components/schemas/ObjectWithDeprecatedProperty`. - public struct ObjectWithDeprecatedProperty: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/ObjectWithDeprecatedProperty/message`. - @available(*, deprecated) public var message: Swift.String? - /// Creates a new `ObjectWithDeprecatedProperty`. - /// - /// - Parameters: - /// - message: - public init(message: Swift.String? = nil) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } - } - /// - Remark: Generated from `#/components/schemas/PetStats`. - public struct PetStats: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/PetStats/count`. - public var count: Swift.Int - /// Creates a new `PetStats`. - /// - /// - Parameters: - /// - count: - public init(count: Swift.Int) { self.count = count } - public enum CodingKeys: String, CodingKey { case count } - } - } - /// Types generated from the `#/components/parameters` section of the OpenAPI document. - public enum Parameters { - /// Supply this parameter to filter pets born since the provided date. - /// - /// - Remark: Generated from `#/components/parameters/query.born-since`. - public typealias query_period_born_hyphen_since = Components.Schemas.DOB - /// The id of the pet to retrieve - /// - /// - Remark: Generated from `#/components/parameters/path.petId`. - public typealias path_period_petId = Swift.Int64 - /// A deprecated header parameter - /// - /// - Remark: Generated from `#/components/parameters/header.deprecatedHeader`. - public typealias header_period_deprecatedHeader = Swift.String - } - /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. - public enum RequestBodies { - /// - Remark: Generated from `#/components/requestBodies/UpdatePetRequest`. - @frozen public enum UpdatePetRequest: Sendable, Hashable { - /// - Remark: Generated from `#/components/requestBodies/UpdatePetRequest/json`. - public struct jsonPayload: Codable, Hashable, Sendable { - /// Pet name - /// - /// - Remark: Generated from `#/components/requestBodies/UpdatePetRequest/json/name`. - public var name: Swift.String? - /// - Remark: Generated from `#/components/requestBodies/UpdatePetRequest/json/kind`. - public var kind: Components.Schemas.PetKind? - /// - Remark: Generated from `#/components/requestBodies/UpdatePetRequest/json/tag`. - public var tag: Swift.String? - /// Creates a new `jsonPayload`. - /// - /// - Parameters: - /// - name: Pet name - /// - kind: - /// - tag: - public init( - name: Swift.String? = nil, - kind: Components.Schemas.PetKind? = nil, - tag: Swift.String? = nil - ) { - self.name = name - self.kind = kind - self.tag = tag - } - public enum CodingKeys: String, CodingKey { - case name - case kind - case tag - } - } - /// - Remark: Generated from `#/components/requestBodies/UpdatePetRequest/content/application\/json`. - case json(Components.RequestBodies.UpdatePetRequest.jsonPayload) - } - } - /// Types generated from the `#/components/responses` section of the OpenAPI document. - public enum Responses { - public struct ErrorBadRequest: Sendable, Hashable { - /// - Remark: Generated from `#/components/responses/ErrorBadRequest/headers`. - public struct Headers: Sendable, Hashable { - /// A description here. - /// - /// - Remark: Generated from `#/components/responses/ErrorBadRequest/headers/X-Reason`. - public var X_hyphen_Reason: Swift.String? - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - X_hyphen_Reason: A description here. - public init(X_hyphen_Reason: Swift.String? = nil) { self.X_hyphen_Reason = X_hyphen_Reason } - } - /// Received HTTP response headers - public var headers: Components.Responses.ErrorBadRequest.Headers - /// - Remark: Generated from `#/components/responses/ErrorBadRequest/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/components/responses/ErrorBadRequest/content/json`. - public struct jsonPayload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/responses/ErrorBadRequest/content/json/code`. - public var code: Swift.Int - /// Creates a new `jsonPayload`. - /// - /// - Parameters: - /// - code: - public init(code: Swift.Int) { self.code = code } - public enum CodingKeys: String, CodingKey { case code } - } - /// - Remark: Generated from `#/components/responses/ErrorBadRequest/content/application\/json`. - case json(Components.Responses.ErrorBadRequest.Body.jsonPayload) - } - /// Received HTTP response body - public var body: Components.Responses.ErrorBadRequest.Body - /// Creates a new `ErrorBadRequest`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Components.Responses.ErrorBadRequest.Headers = .init(), - body: Components.Responses.ErrorBadRequest.Body - ) { - self.headers = headers - self.body = body - } - } - } - /// Types generated from the `#/components/headers` section of the OpenAPI document. - public enum Headers { - /// A description here. - /// - /// - Remark: Generated from `#/components/headers/TracingHeader`. - public typealias TracingHeader = Swift.String - } -} -/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. -public enum Operations { - /// List all pets - /// - /// You can fetch - /// all the pets here - /// - /// - Remark: HTTP `GET /pets`. - /// - Remark: Generated from `#/paths//pets/get(listPets)`. - public enum listPets { - public static let id: String = "listPets" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/GET/path`. - public struct Path: Sendable, Hashable { - /// Creates a new `Path`. - public init() {} - } - public var path: Operations.listPets.Input.Path - /// - Remark: Generated from `#/paths/pets/GET/query`. - public struct Query: Sendable, Hashable { - /// How many items to return at one time (max 100) - /// - /// - Remark: Generated from `#/paths/pets/GET/query/limit`. - public var limit: Swift.Int32? - /// - Remark: Generated from `#/paths/pets/GET/query/habitat`. - @frozen public enum habitatPayload: String, Codable, Hashable, Sendable { - case water = "water" - case land = "land" - case air = "air" - case _empty = "" - } - /// - Remark: Generated from `#/paths/pets/GET/query/habitat`. - public var habitat: Operations.listPets.Input.Query.habitatPayload? - /// - Remark: Generated from `#/paths/pets/GET/query/feedsPayload`. - @frozen public enum feedsPayloadPayload: String, Codable, Hashable, Sendable { - case omnivore = "omnivore" - case carnivore = "carnivore" - case herbivore = "herbivore" - } - /// - Remark: Generated from `#/paths/pets/GET/query/feeds`. - public typealias feedsPayload = [Operations.listPets.Input.Query.feedsPayloadPayload] - /// - Remark: Generated from `#/paths/pets/GET/query/feeds`. - public var feeds: Operations.listPets.Input.Query.feedsPayload? - /// Supply this parameter to filter pets born since the provided date. - /// - /// - Remark: Generated from `#/paths/pets/GET/query/since`. - public var since: Components.Parameters.query_period_born_hyphen_since? - /// Creates a new `Query`. - /// - /// - Parameters: - /// - limit: How many items to return at one time (max 100) - /// - habitat: - /// - feeds: - /// - since: Supply this parameter to filter pets born since the provided date. - public init( - limit: Swift.Int32? = nil, - habitat: Operations.listPets.Input.Query.habitatPayload? = nil, - feeds: Operations.listPets.Input.Query.feedsPayload? = nil, - since: Components.Parameters.query_period_born_hyphen_since? = nil - ) { - self.limit = limit - self.habitat = habitat - self.feeds = feeds - self.since = since - } - } - public var query: Operations.listPets.Input.Query - /// - Remark: Generated from `#/paths/pets/GET/header`. - public struct Headers: Sendable, Hashable { - /// Request identifier - /// - /// - Remark: Generated from `#/paths/pets/GET/header/My-Request-UUID`. - public var My_hyphen_Request_hyphen_UUID: Swift.String? - public var accept: [OpenAPIRuntime.AcceptHeaderContentType] - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - My_hyphen_Request_hyphen_UUID: Request identifier - /// - accept: - public init( - My_hyphen_Request_hyphen_UUID: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() - ) { - self.My_hyphen_Request_hyphen_UUID = My_hyphen_Request_hyphen_UUID - self.accept = accept - } - } - public var headers: Operations.listPets.Input.Headers - /// - Remark: Generated from `#/paths/pets/GET/cookie`. - public struct Cookies: Sendable, Hashable { - /// Creates a new `Cookies`. - public init() {} - } - public var cookies: Operations.listPets.Input.Cookies - /// - Remark: Generated from `#/paths/pets/GET/requestBody`. - @frozen public enum Body: Sendable, Hashable {} - public var body: Operations.listPets.Input.Body? - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - query: - /// - headers: - /// - cookies: - /// - body: - public init( - path: Operations.listPets.Input.Path = .init(), - query: Operations.listPets.Input.Query = .init(), - headers: Operations.listPets.Input.Headers = .init(), - cookies: Operations.listPets.Input.Cookies = .init(), - body: Operations.listPets.Input.Body? = nil - ) { - self.path = path - self.query = query - self.headers = headers - self.cookies = cookies - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Ok: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/GET/responses/200/headers`. - public struct Headers: Sendable, Hashable { - /// Response identifier - /// - /// - Remark: Generated from `#/paths/pets/GET/responses/200/headers/My-Response-UUID`. - public var My_hyphen_Response_hyphen_UUID: Swift.String - /// A description here. - /// - /// - Remark: Generated from `#/paths/pets/GET/responses/200/headers/My-Tracing-Header`. - public var My_hyphen_Tracing_hyphen_Header: Components.Headers.TracingHeader? - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - My_hyphen_Response_hyphen_UUID: Response identifier - /// - My_hyphen_Tracing_hyphen_Header: A description here. - public init( - My_hyphen_Response_hyphen_UUID: Swift.String, - My_hyphen_Tracing_hyphen_Header: Components.Headers.TracingHeader? = nil - ) { - self.My_hyphen_Response_hyphen_UUID = My_hyphen_Response_hyphen_UUID - self.My_hyphen_Tracing_hyphen_Header = My_hyphen_Tracing_hyphen_Header - } - } - /// Received HTTP response headers - public var headers: Operations.listPets.Output.Ok.Headers - /// - Remark: Generated from `#/paths/pets/GET/responses/200/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/GET/responses/200/content/application\/json`. - case json(Components.Schemas.Pets) - } - /// Received HTTP response body - public var body: Operations.listPets.Output.Ok.Body - /// Creates a new `Ok`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init(headers: Operations.listPets.Output.Ok.Headers, body: Operations.listPets.Output.Ok.Body) { - self.headers = headers - self.body = body - } - } - /// A paged array of pets - /// - /// - Remark: Generated from `#/paths//pets/get(listPets)/responses/200`. - /// - /// HTTP response code: `200 ok`. - case ok(Operations.listPets.Output.Ok) - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/GET/responses/default/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.listPets.Output.Default.Headers - /// - Remark: Generated from `#/paths/pets/GET/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/GET/responses/default/content/application\/json`. - case json(Components.Schemas._Error) - } - /// Received HTTP response body - public var body: Operations.listPets.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.listPets.Output.Default.Headers = .init(), - body: Operations.listPets.Output.Default.Body - ) { - self.headers = headers - self.body = body - } - } - /// Unexpected error - /// - /// - Remark: Generated from `#/paths//pets/get(listPets)/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Int, Operations.listPets.Output.Default) - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(String) - public init?(rawValue: String) { - switch rawValue.lowercased() { - case "application/json": self = .json - default: self = .other(rawValue) - } - } - public var rawValue: String { - switch self { - case let .other(string): return string - case .json: return "application/json" - } - } - public static var allCases: [Self] { [.json] } - } - } - /// Create a pet - /// - /// - Remark: HTTP `POST /pets`. - /// - Remark: Generated from `#/paths//pets/post(createPet)`. - public enum createPet { - public static let id: String = "createPet" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/POST/path`. - public struct Path: Sendable, Hashable { - /// Creates a new `Path`. - public init() {} - } - public var path: Operations.createPet.Input.Path - /// - Remark: Generated from `#/paths/pets/POST/query`. - public struct Query: Sendable, Hashable { - /// Creates a new `Query`. - public init() {} - } - public var query: Operations.createPet.Input.Query - /// - Remark: Generated from `#/paths/pets/POST/header`. - public struct Headers: Sendable, Hashable { - /// A description here. - /// - /// - Remark: Generated from `#/paths/pets/POST/header/X-Extra-Arguments`. - public var X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? - public var accept: [OpenAPIRuntime.AcceptHeaderContentType] - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - X_hyphen_Extra_hyphen_Arguments: A description here. - /// - accept: - public init( - X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() - ) { - self.X_hyphen_Extra_hyphen_Arguments = X_hyphen_Extra_hyphen_Arguments - self.accept = accept - } - } - public var headers: Operations.createPet.Input.Headers - /// - Remark: Generated from `#/paths/pets/POST/cookie`. - public struct Cookies: Sendable, Hashable { - /// Creates a new `Cookies`. - public init() {} - } - public var cookies: Operations.createPet.Input.Cookies - /// - Remark: Generated from `#/paths/pets/POST/requestBody`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/POST/requestBody/content/application\/json`. - case json(Components.Schemas.CreatePetRequest) - } - public var body: Operations.createPet.Input.Body - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - query: - /// - headers: - /// - cookies: - /// - body: - public init( - path: Operations.createPet.Input.Path = .init(), - query: Operations.createPet.Input.Query = .init(), - headers: Operations.createPet.Input.Headers = .init(), - cookies: Operations.createPet.Input.Cookies = .init(), - body: Operations.createPet.Input.Body - ) { - self.path = path - self.query = query - self.headers = headers - self.cookies = cookies - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Created: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/POST/responses/201/headers`. - public struct Headers: Sendable, Hashable { - /// A description here. - /// - /// - Remark: Generated from `#/paths/pets/POST/responses/201/headers/X-Extra-Arguments`. - public var X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - X_hyphen_Extra_hyphen_Arguments: A description here. - public init(X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? = nil) { - self.X_hyphen_Extra_hyphen_Arguments = X_hyphen_Extra_hyphen_Arguments - } - } - /// Received HTTP response headers - public var headers: Operations.createPet.Output.Created.Headers - /// - Remark: Generated from `#/paths/pets/POST/responses/201/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/POST/responses/201/content/application\/json`. - case json(Components.Schemas.Pet) - } - /// Received HTTP response body - public var body: Operations.createPet.Output.Created.Body - /// Creates a new `Created`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.createPet.Output.Created.Headers = .init(), - body: Operations.createPet.Output.Created.Body - ) { - self.headers = headers - self.body = body - } - } - /// Successfully created pet - /// - /// - Remark: Generated from `#/paths//pets/post(createPet)/responses/201`. - /// - /// HTTP response code: `201 created`. - case created(Operations.createPet.Output.Created) - /// Bad request - /// - /// - Remark: Generated from `#/paths//pets/post(createPet)/responses/4XX`. - /// - /// HTTP response code: `400...499 clientError`. - case clientError(statusCode: Int, Components.Responses.ErrorBadRequest) - /// Undocumented response. - /// - /// A response with a code that is not documented in the OpenAPI document. - case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(String) - public init?(rawValue: String) { - switch rawValue.lowercased() { - case "application/json": self = .json - default: self = .other(rawValue) - } - } - public var rawValue: String { - switch self { - case let .other(string): return string - case .json: return "application/json" - } - } - public static var allCases: [Self] { [.json] } - } - } - /// - Remark: HTTP `GET /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/get(getStats)`. - public enum getStats { - public static let id: String = "getStats" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/stats/GET/path`. - public struct Path: Sendable, Hashable { - /// Creates a new `Path`. - public init() {} - } - public var path: Operations.getStats.Input.Path - /// - Remark: Generated from `#/paths/pets/stats/GET/query`. - public struct Query: Sendable, Hashable { - /// Creates a new `Query`. - public init() {} - } - public var query: Operations.getStats.Input.Query - /// - Remark: Generated from `#/paths/pets/stats/GET/header`. - public struct Headers: Sendable, Hashable { - public var accept: [OpenAPIRuntime.AcceptHeaderContentType] - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - accept: - public init( - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() - ) { self.accept = accept } - } - public var headers: Operations.getStats.Input.Headers - /// - Remark: Generated from `#/paths/pets/stats/GET/cookie`. - public struct Cookies: Sendable, Hashable { - /// Creates a new `Cookies`. - public init() {} - } - public var cookies: Operations.getStats.Input.Cookies - /// - Remark: Generated from `#/paths/pets/stats/GET/requestBody`. - @frozen public enum Body: Sendable, Hashable {} - public var body: Operations.getStats.Input.Body? - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - query: - /// - headers: - /// - cookies: - /// - body: - public init( - path: Operations.getStats.Input.Path = .init(), - query: Operations.getStats.Input.Query = .init(), - headers: Operations.getStats.Input.Headers = .init(), - cookies: Operations.getStats.Input.Cookies = .init(), - body: Operations.getStats.Input.Body? = nil - ) { - self.path = path - self.query = query - self.headers = headers - self.cookies = cookies - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Ok: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.getStats.Output.Ok.Headers - /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/content/application\/json`. - case json(Components.Schemas.PetStats) - /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/content/text\/plain`. - case plainText(Swift.String) - /// - Remark: Generated from `#/paths/pets/stats/GET/responses/200/content/application\/octet-stream`. - case binary(Foundation.Data) - } - /// Received HTTP response body - public var body: Operations.getStats.Output.Ok.Body - /// Creates a new `Ok`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.getStats.Output.Ok.Headers = .init(), - body: Operations.getStats.Output.Ok.Body - ) { - self.headers = headers - self.body = body - } - } - /// A successful response. - /// - /// - Remark: Generated from `#/paths//pets/stats/get(getStats)/responses/200`. - /// - /// HTTP response code: `200 ok`. - case ok(Operations.getStats.Output.Ok) - /// Undocumented response. - /// - /// A response with a code that is not documented in the OpenAPI document. - case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case plainText - case binary - case other(String) - public init?(rawValue: String) { - switch rawValue.lowercased() { - case "application/json": self = .json - case "text/plain": self = .plainText - case "application/octet-stream": self = .binary - default: self = .other(rawValue) - } - } - public var rawValue: String { - switch self { - case let .other(string): return string - case .json: return "application/json" - case .plainText: return "text/plain" - case .binary: return "application/octet-stream" - } - } - public static var allCases: [Self] { [.json, .plainText, .binary] } - } - } - /// - Remark: HTTP `POST /pets/stats`. - /// - Remark: Generated from `#/paths//pets/stats/post(postStats)`. - public enum postStats { - public static let id: String = "postStats" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/stats/POST/path`. - public struct Path: Sendable, Hashable { - /// Creates a new `Path`. - public init() {} - } - public var path: Operations.postStats.Input.Path - /// - Remark: Generated from `#/paths/pets/stats/POST/query`. - public struct Query: Sendable, Hashable { - /// Creates a new `Query`. - public init() {} - } - public var query: Operations.postStats.Input.Query - /// - Remark: Generated from `#/paths/pets/stats/POST/header`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - public var headers: Operations.postStats.Input.Headers - /// - Remark: Generated from `#/paths/pets/stats/POST/cookie`. - public struct Cookies: Sendable, Hashable { - /// Creates a new `Cookies`. - public init() {} - } - public var cookies: Operations.postStats.Input.Cookies - /// - Remark: Generated from `#/paths/pets/stats/POST/requestBody`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/stats/POST/requestBody/content/application\/json`. - case json(Components.Schemas.PetStats) - /// - Remark: Generated from `#/paths/pets/stats/POST/requestBody/content/text\/plain`. - case plainText(Swift.String) - /// - Remark: Generated from `#/paths/pets/stats/POST/requestBody/content/application\/octet-stream`. - case binary(Foundation.Data) - } - public var body: Operations.postStats.Input.Body - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - query: - /// - headers: - /// - cookies: - /// - body: - public init( - path: Operations.postStats.Input.Path = .init(), - query: Operations.postStats.Input.Query = .init(), - headers: Operations.postStats.Input.Headers = .init(), - cookies: Operations.postStats.Input.Cookies = .init(), - body: Operations.postStats.Input.Body - ) { - self.path = path - self.query = query - self.headers = headers - self.cookies = cookies - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Accepted: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/stats/POST/responses/202/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.postStats.Output.Accepted.Headers - /// - Remark: Generated from `#/paths/pets/stats/POST/responses/202/content`. - @frozen public enum Body: Sendable, Hashable {} - /// Received HTTP response body - public var body: Operations.postStats.Output.Accepted.Body? - /// Creates a new `Accepted`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.postStats.Output.Accepted.Headers = .init(), - body: Operations.postStats.Output.Accepted.Body? = nil - ) { - self.headers = headers - self.body = body - } - } - /// Accepted data. - /// - /// - Remark: Generated from `#/paths//pets/stats/post(postStats)/responses/202`. - /// - /// HTTP response code: `202 accepted`. - case accepted(Operations.postStats.Output.Accepted) - /// Undocumented response. - /// - /// A response with a code that is not documented in the OpenAPI document. - case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) - } - } - /// - Remark: HTTP `POST /probe/`. - /// - Remark: Generated from `#/paths//probe//post(probe)`. - public enum probe { - public static let id: String = "probe" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/probe/POST/path`. - public struct Path: Sendable, Hashable { - /// Creates a new `Path`. - public init() {} - } - public var path: Operations.probe.Input.Path - /// - Remark: Generated from `#/paths/probe/POST/query`. - public struct Query: Sendable, Hashable { - /// Creates a new `Query`. - public init() {} - } - public var query: Operations.probe.Input.Query - /// - Remark: Generated from `#/paths/probe/POST/header`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - public var headers: Operations.probe.Input.Headers - /// - Remark: Generated from `#/paths/probe/POST/cookie`. - public struct Cookies: Sendable, Hashable { - /// Creates a new `Cookies`. - public init() {} - } - public var cookies: Operations.probe.Input.Cookies - /// - Remark: Generated from `#/paths/probe/POST/requestBody`. - @frozen public enum Body: Sendable, Hashable {} - public var body: Operations.probe.Input.Body? - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - query: - /// - headers: - /// - cookies: - /// - body: - public init( - path: Operations.probe.Input.Path = .init(), - query: Operations.probe.Input.Query = .init(), - headers: Operations.probe.Input.Headers = .init(), - cookies: Operations.probe.Input.Cookies = .init(), - body: Operations.probe.Input.Body? = nil - ) { - self.path = path - self.query = query - self.headers = headers - self.cookies = cookies - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct NoContent: Sendable, Hashable { - /// - Remark: Generated from `#/paths/probe/POST/responses/204/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.probe.Output.NoContent.Headers - /// - Remark: Generated from `#/paths/probe/POST/responses/204/content`. - @frozen public enum Body: Sendable, Hashable {} - /// Received HTTP response body - public var body: Operations.probe.Output.NoContent.Body? - /// Creates a new `NoContent`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.probe.Output.NoContent.Headers = .init(), - body: Operations.probe.Output.NoContent.Body? = nil - ) { - self.headers = headers - self.body = body - } - } - /// Ack - /// - /// - Remark: Generated from `#/paths//probe//post(probe)/responses/204`. - /// - /// HTTP response code: `204 noContent`. - case noContent(Operations.probe.Output.NoContent) - /// Undocumented response. - /// - /// A response with a code that is not documented in the OpenAPI document. - case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) - } - } - /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. - /// - /// - Remark: HTTP `PATCH /pets/{petId}`. - /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. - public enum updatePet { - public static let id: String = "updatePet" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/path`. - public struct Path: Sendable, Hashable { - /// Id of the pet - /// - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/path/petId`. - public var petId: Swift.Int64 - /// Creates a new `Path`. - /// - /// - Parameters: - /// - petId: Id of the pet - public init(petId: Swift.Int64) { self.petId = petId } - } - public var path: Operations.updatePet.Input.Path - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/query`. - public struct Query: Sendable, Hashable { - /// Creates a new `Query`. - public init() {} - } - public var query: Operations.updatePet.Input.Query - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/header`. - public struct Headers: Sendable, Hashable { - public var accept: [OpenAPIRuntime.AcceptHeaderContentType] - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - accept: - public init( - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() - ) { self.accept = accept } - } - public var headers: Operations.updatePet.Input.Headers - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/cookie`. - public struct Cookies: Sendable, Hashable { - /// Creates a new `Cookies`. - public init() {} - } - public var cookies: Operations.updatePet.Input.Cookies - public var body: Components.RequestBodies.UpdatePetRequest? - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - query: - /// - headers: - /// - cookies: - /// - body: - public init( - path: Operations.updatePet.Input.Path, - query: Operations.updatePet.Input.Query = .init(), - headers: Operations.updatePet.Input.Headers = .init(), - cookies: Operations.updatePet.Input.Cookies = .init(), - body: Components.RequestBodies.UpdatePetRequest? = nil - ) { - self.path = path - self.query = query - self.headers = headers - self.cookies = cookies - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct NoContent: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/204/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.updatePet.Output.NoContent.Headers - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/204/content`. - @frozen public enum Body: Sendable, Hashable {} - /// Received HTTP response body - public var body: Operations.updatePet.Output.NoContent.Body? - /// Creates a new `NoContent`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.updatePet.Output.NoContent.Headers = .init(), - body: Operations.updatePet.Output.NoContent.Body? = nil - ) { - self.headers = headers - self.body = body - } - } - /// Successfully updated - /// - /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)/responses/204`. - /// - /// HTTP response code: `204 noContent`. - case noContent(Operations.updatePet.Output.NoContent) - public struct BadRequest: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/400/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.updatePet.Output.BadRequest.Headers - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/400/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/400/content/json`. - public struct jsonPayload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/400/content/json/message`. - public var message: Swift.String - /// Creates a new `jsonPayload`. - /// - /// - Parameters: - /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } - } - /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/400/content/application\/json`. - case json(Operations.updatePet.Output.BadRequest.Body.jsonPayload) - } - /// Received HTTP response body - public var body: Operations.updatePet.Output.BadRequest.Body - /// Creates a new `BadRequest`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.updatePet.Output.BadRequest.Headers = .init(), - body: Operations.updatePet.Output.BadRequest.Body - ) { - self.headers = headers - self.body = body - } - } - /// Update input error - /// - /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)/responses/400`. - /// - /// HTTP response code: `400 badRequest`. - case badRequest(Operations.updatePet.Output.BadRequest) - /// Undocumented response. - /// - /// A response with a code that is not documented in the OpenAPI document. - case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(String) - public init?(rawValue: String) { - switch rawValue.lowercased() { - case "application/json": self = .json - default: self = .other(rawValue) - } - } - public var rawValue: String { - switch self { - case let .other(string): return string - case .json: return "application/json" - } - } - public static var allCases: [Self] { [.json] } - } - } - /// Upload an avatar - /// - /// - Remark: HTTP `PUT /pets/{petId}/avatar`. - /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. - public enum uploadAvatarForPet { - public static let id: String = "uploadAvatarForPet" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/path`. - public struct Path: Sendable, Hashable { - /// The id of the pet to retrieve - /// - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/path/petId`. - public var petId: Components.Parameters.path_period_petId - /// Creates a new `Path`. - /// - /// - Parameters: - /// - petId: The id of the pet to retrieve - public init(petId: Components.Parameters.path_period_petId) { self.petId = petId } - } - public var path: Operations.uploadAvatarForPet.Input.Path - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/query`. - public struct Query: Sendable, Hashable { - /// Creates a new `Query`. - public init() {} - } - public var query: Operations.uploadAvatarForPet.Input.Query - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/header`. - public struct Headers: Sendable, Hashable { - public var accept: - [OpenAPIRuntime.AcceptHeaderContentType] - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - accept: - public init( - accept: [OpenAPIRuntime.AcceptHeaderContentType< - Operations.uploadAvatarForPet.AcceptableContentType - >] = .defaultValues() - ) { self.accept = accept } - } - public var headers: Operations.uploadAvatarForPet.Input.Headers - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/cookie`. - public struct Cookies: Sendable, Hashable { - /// Creates a new `Cookies`. - public init() {} - } - public var cookies: Operations.uploadAvatarForPet.Input.Cookies - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/requestBody`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/requestBody/content/application\/octet-stream`. - case binary(Foundation.Data) - } - public var body: Operations.uploadAvatarForPet.Input.Body - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - query: - /// - headers: - /// - cookies: - /// - body: - public init( - path: Operations.uploadAvatarForPet.Input.Path, - query: Operations.uploadAvatarForPet.Input.Query = .init(), - headers: Operations.uploadAvatarForPet.Input.Headers = .init(), - cookies: Operations.uploadAvatarForPet.Input.Cookies = .init(), - body: Operations.uploadAvatarForPet.Input.Body - ) { - self.path = path - self.query = query - self.headers = headers - self.cookies = cookies - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Ok: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/200/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.uploadAvatarForPet.Output.Ok.Headers - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/200/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/200/content/application\/octet-stream`. - case binary(Foundation.Data) - } - /// Received HTTP response body - public var body: Operations.uploadAvatarForPet.Output.Ok.Body - /// Creates a new `Ok`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.uploadAvatarForPet.Output.Ok.Headers = .init(), - body: Operations.uploadAvatarForPet.Output.Ok.Body - ) { - self.headers = headers - self.body = body - } - } - /// Echoes avatar back - /// - /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)/responses/200`. - /// - /// HTTP response code: `200 ok`. - case ok(Operations.uploadAvatarForPet.Output.Ok) - public struct PreconditionFailed: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/412/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.uploadAvatarForPet.Output.PreconditionFailed.Headers - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/412/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/412/content/application\/json`. - case json(Swift.String) - } - /// Received HTTP response body - public var body: Operations.uploadAvatarForPet.Output.PreconditionFailed.Body - /// Creates a new `PreconditionFailed`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.uploadAvatarForPet.Output.PreconditionFailed.Headers = .init(), - body: Operations.uploadAvatarForPet.Output.PreconditionFailed.Body - ) { - self.headers = headers - self.body = body - } - } - /// Avatar is not acceptable - /// - /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)/responses/412`. - /// - /// HTTP response code: `412 preconditionFailed`. - case preconditionFailed(Operations.uploadAvatarForPet.Output.PreconditionFailed) - public struct InternalServerError: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/500/headers`. - public struct Headers: Sendable, Hashable { - /// Creates a new `Headers`. - public init() {} - } - /// Received HTTP response headers - public var headers: Operations.uploadAvatarForPet.Output.InternalServerError.Headers - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/500/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/responses/500/content/text\/plain`. - case plainText(Swift.String) - } - /// Received HTTP response body - public var body: Operations.uploadAvatarForPet.Output.InternalServerError.Body - /// Creates a new `InternalServerError`. - /// - /// - Parameters: - /// - headers: Received HTTP response headers - /// - body: Received HTTP response body - public init( - headers: Operations.uploadAvatarForPet.Output.InternalServerError.Headers = .init(), - body: Operations.uploadAvatarForPet.Output.InternalServerError.Body - ) { - self.headers = headers - self.body = body - } - } - /// Server error - /// - /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)/responses/500`. - /// - /// HTTP response code: `500 internalServerError`. - case internalServerError(Operations.uploadAvatarForPet.Output.InternalServerError) - /// Undocumented response. - /// - /// A response with a code that is not documented in the OpenAPI document. - case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case binary - case json - case plainText - case other(String) - public init?(rawValue: String) { - switch rawValue.lowercased() { - case "application/octet-stream": self = .binary - case "application/json": self = .json - case "text/plain": self = .plainText - default: self = .other(rawValue) - } - } - public var rawValue: String { - switch self { - case let .other(string): return string - case .binary: return "application/octet-stream" - case .json: return "application/json" - case .plainText: return "text/plain" - } - } - public static var allCases: [Self] { [.binary, .json, .plainText] } - } - } -} diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift index ef1fc33f..65b548f0 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift @@ -325,56 +325,6 @@ final class SnippetBasedReferenceTests: XCTestCase { ) } - func testComponentsSchemasOneOf() throws { - try self.assertSchemasTranslation( - """ - schemas: - A: {} - MyOneOf: - oneOf: - - type: string - - type: integer - - $ref: '#/components/schemas/A' - """, - """ - public enum Schemas { - public typealias A = OpenAPIRuntime.OpenAPIValueContainer - @frozen public enum MyOneOf: Codable, Hashable, Sendable { - case case1(Swift.String) - case case2(Swift.Int) - case A(Components.Schemas.A) - case undocumented(OpenAPIRuntime.OpenAPIValueContainer) - public init(from decoder: any Decoder) throws { - do { - self = .case1(try .init(from: decoder)) - return - } catch {} - do { - self = .case2(try .init(from: decoder)) - return - } catch {} - do { - self = .A(try .init(from: decoder)) - return - } catch {} - let container = try decoder.singleValueContainer() - let value = try container.decode(OpenAPIRuntime.OpenAPIValueContainer.self) - self = .undocumented(value) - } - public func encode(to encoder: any Encoder) throws { - switch self { - case let .case1(value): try value.encode(to: encoder) - case let .case2(value): try value.encode(to: encoder) - case let .A(value): try value.encode(to: encoder) - case let .undocumented(value): try value.encode(to: encoder) - } - } - } - } - """ - ) - } - func testComponentsSchemasOneOfWithDiscriminator() throws { try self.assertSchemasTranslation( """ @@ -416,7 +366,6 @@ final class SnippetBasedReferenceTests: XCTestCase { @frozen public enum MyOneOf: Codable, Hashable, Sendable { case A(Components.Schemas.A) case B(Components.Schemas.B) - case undocumented(OpenAPIRuntime.OpenAPIObjectContainer) public enum CodingKeys: String, CodingKey { case which } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -425,16 +374,16 @@ final class SnippetBasedReferenceTests: XCTestCase { case "A", "#/components/schemas/A": self = .A(try .init(from: decoder)) case "B", "#/components/schemas/B": self = .B(try .init(from: decoder)) default: - let container = try decoder.singleValueContainer() - let value = try container.decode(OpenAPIRuntime.OpenAPIObjectContainer.self) - self = .undocumented(value) + throw DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath + ) } } public func encode(to encoder: any Encoder) throws { switch self { case let .A(value): try value.encode(to: encoder) case let .B(value): try value.encode(to: encoder) - case let .undocumented(value): try value.encode(to: encoder) } } } @@ -445,7 +394,6 @@ final class SnippetBasedReferenceTests: XCTestCase { func testComponentsSchemasOneOfWithDiscriminatorWithMapping() throws { try self.assertSchemasTranslation( - featureFlags: [.closedEnumsAndOneOfs], """ schemas: A: @@ -529,7 +477,6 @@ final class SnippetBasedReferenceTests: XCTestCase { func testComponentsSchemasOneOf_closed() throws { try self.assertSchemasTranslation( - featureFlags: [.closedEnumsAndOneOfs], """ schemas: A: {} @@ -579,7 +526,6 @@ final class SnippetBasedReferenceTests: XCTestCase { func testComponentsSchemasOneOf_open_pattern() throws { try self.assertSchemasTranslation( - featureFlags: [.closedEnumsAndOneOfs], """ schemas: A: @@ -771,60 +717,10 @@ final class SnippetBasedReferenceTests: XCTestCase { """, """ public enum Schemas { - @frozen - public enum MyEnum: RawRepresentable, Codable, Hashable, Sendable, - CaseIterable - { - case one - case _empty - case _tart - case _public - case undocumented(String) - public init?(rawValue: String) { - switch rawValue { - case "one": self = .one - case "": self = ._empty - case "$tart": self = ._tart - case "public": self = ._public - default: self = .undocumented(rawValue) - } - } - public var rawValue: String { - switch self { - case let .undocumented(string): return string - case .one: return "one" - case ._empty: return "" - case ._tart: return "$tart" - case ._public: return "public" - } - } - public static var allCases: [Self] { [.one, ._empty, ._tart, ._public] } - } - } - """ - ) - } - - func testComponentsSchemasEnum_closed() throws { - try self.assertSchemasTranslation( - featureFlags: [.closedEnumsAndOneOfs], - """ - schemas: - MyEnum: - type: string - enum: - - one - - - - $tart - - public - """, - """ - public enum Schemas { - @frozen - public enum MyEnum: String, Codable, Hashable, Sendable { + @frozen public enum MyEnum: String, Codable, Hashable, Sendable { case one = "one" case _empty = "" - case _tart = "$tart" + case _dollar_tart = "$tart" case _public = "public" } } @@ -834,7 +730,6 @@ final class SnippetBasedReferenceTests: XCTestCase { func testComponentsSchemasEnum_open_pattern() throws { try self.assertSchemasTranslation( - featureFlags: [.closedEnumsAndOneOfs], """ schemas: MyOpenEnum: @@ -1007,44 +902,6 @@ final class SnippetBasedReferenceTests: XCTestCase { func testComponentsResponsesResponseMultipleContentTypes() throws { try self.assertResponsesTranslation( - featureFlags: [], - ignoredDiagnosticMessages: [#"Feature "Multiple content types" is not supported, skipping"#], - """ - responses: - MultipleContentTypes: - description: Multiple content types - content: - application/json: - schema: - type: integer - text/plain: {} - application/octet-stream: {} - """, - """ - public enum Responses { - public struct MultipleContentTypes: Sendable, Hashable { - public struct Headers: Sendable, Hashable { public init() {} } - public var headers: Components.Responses.MultipleContentTypes.Headers - @frozen public enum Body: Sendable, Hashable { - case json(Swift.Int) - } - public var body: Components.Responses.MultipleContentTypes.Body - public init( - headers: Components.Responses.MultipleContentTypes.Headers = .init(), - body: Components.Responses.MultipleContentTypes.Body - ) { - self.headers = headers - self.body = body - } - } - } - """ - ) - try self.assertResponsesTranslation( - featureFlags: [ - .multipleContentTypes, - .proposal0001, - ], """ responses: MultipleContentTypes: @@ -1095,9 +952,9 @@ final class SnippetBasedReferenceTests: XCTestCase { public enum Responses { public struct BadRequest: Sendable, Hashable { public struct Headers: Sendable, Hashable { - public var X_Reason: Swift.String? - public init(X_Reason: Swift.String? = nil) { - self.X_Reason = X_Reason } + public var X_hyphen_Reason: Swift.String? + public init(X_hyphen_Reason: Swift.String? = nil) { + self.X_hyphen_Reason = X_hyphen_Reason } } public var headers: Components.Responses.BadRequest.Headers @frozen public enum Body: Sendable, Hashable {} @@ -1131,9 +988,9 @@ final class SnippetBasedReferenceTests: XCTestCase { public enum Responses { public struct BadRequest: Sendable, Hashable { public struct Headers: Sendable, Hashable { - public var X_Reason: Swift.String - public init(X_Reason: Swift.String) { - self.X_Reason = X_Reason } + public var X_hyphen_Reason: Swift.String + public init(X_hyphen_Reason: Swift.String) { + self.X_hyphen_Reason = X_hyphen_Reason } } public var headers: Components.Responses.BadRequest.Headers @frozen public enum Body: Sendable, Hashable {} @@ -1193,31 +1050,6 @@ final class SnippetBasedReferenceTests: XCTestCase { func testComponentsRequestBodiesMultipleContentTypes() throws { try self.assertRequestBodiesTranslation( - featureFlags: [], - ignoredDiagnosticMessages: [#"Feature "Multiple content types" is not supported, skipping"#], - """ - requestBodies: - MyResponseBody: - content: - application/json: - schema: - $ref: '#/components/schemas/MyBody' - text/plain: {} - application/octet-stream: {} - """, - """ - public enum RequestBodies { - @frozen public enum MyResponseBody: Sendable, Hashable { - case json(Components.Schemas.MyBody) - } - } - """ - ) - try self.assertRequestBodiesTranslation( - featureFlags: [ - .multipleContentTypes, - .proposal0001, - ], """ requestBodies: MyResponseBody: @@ -1445,7 +1277,7 @@ final class SnippetBasedReferenceTests: XCTestCase { types: """ public struct Input: Sendable, Hashable { public struct Path: Sendable, Hashable { public init() {} } - public var path: Operations.get_foo.Input.Path + public var path: Operations.get_sol_foo.Input.Path public struct Query: Sendable, Hashable { public var single: Swift.String? public var manyExploded: [Swift.String]? @@ -1460,19 +1292,19 @@ final class SnippetBasedReferenceTests: XCTestCase { self.manyUnexploded = manyUnexploded } } - public var query: Operations.get_foo.Input.Query + public var query: Operations.get_sol_foo.Input.Query public struct Headers: Sendable, Hashable { public init() {} } - public var headers: Operations.get_foo.Input.Headers + public var headers: Operations.get_sol_foo.Input.Headers public struct Cookies: Sendable, Hashable { public init() {} } - public var cookies: Operations.get_foo.Input.Cookies + public var cookies: Operations.get_sol_foo.Input.Cookies @frozen public enum Body: Sendable, Hashable {} - public var body: Operations.get_foo.Input.Body? + public var body: Operations.get_sol_foo.Input.Body? public init( - path: Operations.get_foo.Input.Path = .init(), - query: Operations.get_foo.Input.Query = .init(), - headers: Operations.get_foo.Input.Headers = .init(), - cookies: Operations.get_foo.Input.Cookies = .init(), - body: Operations.get_foo.Input.Body? = nil + path: Operations.get_sol_foo.Input.Path = .init(), + query: Operations.get_sol_foo.Input.Query = .init(), + headers: Operations.get_sol_foo.Input.Headers = .init(), + cookies: Operations.get_sol_foo.Input.Cookies = .init(), + body: Operations.get_sol_foo.Input.Body? = nil ) { self.path = path self.query = query @@ -1511,8 +1343,8 @@ final class SnippetBasedReferenceTests: XCTestCase { } """, server: """ - { request, metadata in let path: Operations.get_foo.Input.Path = .init() - let query: Operations.get_foo.Input.Query = .init( + { request, metadata in let path: Operations.get_sol_foo.Input.Path = .init() + let query: Operations.get_sol_foo.Input.Query = .init( single: try converter.getOptionalQueryItemAsURI( in: request.query, style: .form, @@ -1535,9 +1367,9 @@ final class SnippetBasedReferenceTests: XCTestCase { as: [Swift.String].self ) ) - let headers: Operations.get_foo.Input.Headers = .init() - let cookies: Operations.get_foo.Input.Cookies = .init() - return Operations.get_foo.Input( + let headers: Operations.get_sol_foo.Input.Headers = .init() + let cookies: Operations.get_sol_foo.Input.Cookies = .init() + return Operations.get_sol_foo.Input( path: path, query: query, headers: headers, diff --git a/Tests/PetstoreConsumerTests/Common.swift b/Tests/PetstoreConsumerTests/Common.swift index 229e20b0..b8b719c4 100644 --- a/Tests/PetstoreConsumerTests/Common.swift +++ b/Tests/PetstoreConsumerTests/Common.swift @@ -15,6 +15,6 @@ import XCTest extension Operations.listPets.Output { static var success: Self { - .ok(.init(headers: .init(My_Response_UUID: "abcd"), body: .json([]))) + .ok(.init(headers: .init(My_hyphen_Response_hyphen_UUID: "abcd"), body: .json([]))) } } diff --git a/Tests/PetstoreConsumerTests/Test_Client.swift b/Tests/PetstoreConsumerTests/Test_Client.swift index b40b16a7..004aa9ab 100644 --- a/Tests/PetstoreConsumerTests/Test_Client.swift +++ b/Tests/PetstoreConsumerTests/Test_Client.swift @@ -76,7 +76,7 @@ final class Test_Client: XCTestCase { since: .test ), headers: .init( - My_Request_UUID: "abcd-1234" + My_hyphen_Request_hyphen_UUID: "abcd-1234" ) ) ) @@ -84,8 +84,8 @@ final class Test_Client: XCTestCase { XCTFail("Unexpected response: \(response)") return } - XCTAssertEqual(value.headers.My_Response_UUID, "abcd") - XCTAssertEqual(value.headers.My_Tracing_Header, "1234") + XCTAssertEqual(value.headers.My_hyphen_Response_hyphen_UUID, "abcd") + XCTAssertEqual(value.headers.My_hyphen_Tracing_hyphen_Header, "1234") switch value.body { case .json(let pets): XCTAssertEqual(pets, [.init(id: 1, name: "Fluffz")]) @@ -136,7 +136,7 @@ final class Test_Client: XCTestCase { error, .init( code: 1, - me_sage: "Oh no!", + me_dollar_sage: "Oh no!", userData: try .init(unvalidatedValue: ["one": 1]) ) ) @@ -183,7 +183,7 @@ final class Test_Client: XCTestCase { let response = try await client.createPet( .init( headers: .init( - X_Extra_Arguments: .init(code: 1) + X_hyphen_Extra_hyphen_Arguments: .init(code: 1) ), body: .json(.init(name: "Fluffz")) ) @@ -192,7 +192,7 @@ final class Test_Client: XCTestCase { XCTFail("Unexpected response: \(response)") return } - XCTAssertEqual(value.headers.X_Extra_Arguments, .init(code: 1)) + XCTAssertEqual(value.headers.X_hyphen_Extra_hyphen_Arguments, .init(code: 1)) switch value.body { case .json(let pets): XCTAssertEqual(pets, .init(id: 1, name: "Fluffz")) @@ -222,7 +222,7 @@ final class Test_Client: XCTestCase { return } XCTAssertEqual(statusCode, 400) - XCTAssertEqual(value.headers.X_Reason, "bad luck") + XCTAssertEqual(value.headers.X_hyphen_Reason, "bad luck") switch value.body { case .json(let body): XCTAssertEqual(body, .init(code: 1)) @@ -351,7 +351,7 @@ final class Test_Client: XCTestCase { XCTAssertEqual( request.headerFields, [ - .init(name: "accept", value: "application/json") + .init(name: "accept", value: "application/json, text/plain, application/octet-stream") ] ) XCTAssertNil(request.body) @@ -375,6 +375,8 @@ final class Test_Client: XCTestCase { switch value.body { case .json(let stats): XCTAssertEqual(stats, .init(count: 1)) + default: + XCTFail("Unexpected content type") } } @@ -402,6 +404,156 @@ final class Test_Client: XCTestCase { switch value.body { case .json(let stats): XCTAssertEqual(stats, .init(count: 1)) + default: + XCTFail("Unexpected content type") + } + } + + func testGetStats_200_text() async throws { + transport = .init { request, baseURL, operationID in + XCTAssertEqual(operationID, "getStats") + XCTAssertEqual(request.path, "/pets/stats") + XCTAssertEqual(request.method, .get) + XCTAssertEqual( + request.headerFields, + [ + .init(name: "accept", value: "application/json, text/plain, application/octet-stream") + ] + ) + XCTAssertNil(request.body) + return .init( + statusCode: 200, + headers: [ + .init(name: "content-type", value: "text/plain") + ], + encodedBody: #""" + count is 1 + """# + ) + } + let response = try await client.getStats(.init()) + guard case let .ok(value) = response else { + XCTFail("Unexpected response: \(response)") + return + } + switch value.body { + case .plainText(let stats): + XCTAssertEqual(stats, "count is 1") + default: + XCTFail("Unexpected content type") + } + } + + func testGetStats_200_text_requestedSpecific() async throws { + transport = .init { request, baseURL, operationID in + XCTAssertEqual(operationID, "getStats") + XCTAssertEqual(request.path, "/pets/stats") + XCTAssertEqual(request.method, .get) + XCTAssertEqual( + request.headerFields, + [ + .init(name: "accept", value: "text/plain, application/json; q=0.500") + ] + ) + XCTAssertNil(request.body) + return .init( + statusCode: 200, + headers: [ + .init(name: "content-type", value: "text/plain") + ], + encodedBody: #""" + count is 1 + """# + ) + } + let response = try await client.getStats( + .init( + headers: .init(accept: [ + .init(contentType: .plainText), + .init(contentType: .json, quality: 0.5), + ]) + ) + ) + guard case let .ok(value) = response else { + XCTFail("Unexpected response: \(response)") + return + } + switch value.body { + case .plainText(let stats): + XCTAssertEqual(stats, "count is 1") + default: + XCTFail("Unexpected content type") + } + } + + func testGetStats_200_text_customAccept() async throws { + transport = .init { request, baseURL, operationID in + XCTAssertEqual(operationID, "getStats") + XCTAssertEqual(request.path, "/pets/stats") + XCTAssertEqual(request.method, .get) + XCTAssertEqual( + request.headerFields, + [ + .init(name: "accept", value: "application/json; q=0.800, text/plain") + ] + ) + XCTAssertNil(request.body) + return .init( + statusCode: 200, + headers: [ + .init(name: "content-type", value: "text/plain") + ], + encodedBody: #""" + count is 1 + """# + ) + } + let response = try await client.getStats( + .init( + headers: .init(accept: [ + .init(contentType: .json, quality: 0.8), + .init(contentType: .plainText), + ]) + ) + ) + guard case let .ok(value) = response else { + XCTFail("Unexpected response: \(response)") + return + } + switch value.body { + case .plainText(let stats): + XCTAssertEqual(stats, "count is 1") + default: + XCTFail("Unexpected content type") + } + } + + func testGetStats_200_binary() async throws { + transport = .init { request, baseURL, operationID in + XCTAssertEqual(operationID, "getStats") + XCTAssertEqual(request.path, "/pets/stats") + XCTAssertEqual(request.method, .get) + XCTAssertNil(request.body) + return .init( + statusCode: 200, + headers: [ + .init(name: "content-type", value: "application/octet-stream") + ], + encodedBody: #""" + count_is_1 + """# + ) + } + let response = try await client.getStats(.init()) + guard case let .ok(value) = response else { + XCTFail("Unexpected response: \(response)") + return + } + switch value.body { + case .binary(let stats): + XCTAssertEqual(String(decoding: stats, as: UTF8.self), "count_is_1") + default: + XCTFail("Unexpected content type") } } @@ -459,6 +611,66 @@ final class Test_Client: XCTestCase { } } + func testPostStats_202_text() async throws { + transport = .init { request, baseURL, operationID in + XCTAssertEqual(operationID, "postStats") + XCTAssertEqual(request.path, "/pets/stats") + XCTAssertNil(request.query) + XCTAssertEqual(baseURL.absoluteString, "/api") + XCTAssertEqual(request.method, .post) + XCTAssertEqual( + request.headerFields, + [ + .init(name: "content-type", value: "text/plain") + ] + ) + XCTAssertEqual( + request.body?.pretty, + #""" + count is 1 + """# + ) + return .init(statusCode: 202) + } + let response = try await client.postStats( + .init(body: .plainText("count is 1")) + ) + guard case .accepted = response else { + XCTFail("Unexpected response: \(response)") + return + } + } + + func testPostStats_202_binary() async throws { + transport = .init { request, baseURL, operationID in + XCTAssertEqual(operationID, "postStats") + XCTAssertEqual(request.path, "/pets/stats") + XCTAssertNil(request.query) + XCTAssertEqual(baseURL.absoluteString, "/api") + XCTAssertEqual(request.method, .post) + XCTAssertEqual( + request.headerFields, + [ + .init(name: "content-type", value: "application/octet-stream") + ] + ) + XCTAssertEqual( + request.body?.pretty, + #""" + count_is_1 + """# + ) + return .init(statusCode: 202) + } + let response = try await client.postStats( + .init(body: .binary(Data("count_is_1".utf8))) + ) + guard case .accepted = response else { + XCTFail("Unexpected response: \(response)") + return + } + } + @available(*, deprecated) func testProbe_204() async throws { transport = .init { request, baseURL, operationID in @@ -590,7 +802,7 @@ final class Test_Client: XCTestCase { return } switch value.body { - case .text(let text): + case .plainText(let text): XCTAssertEqual(text, Data.efghString) } } diff --git a/Tests/PetstoreConsumerTests/Test_Server.swift b/Tests/PetstoreConsumerTests/Test_Server.swift index b253df9c..0fa68950 100644 --- a/Tests/PetstoreConsumerTests/Test_Server.swift +++ b/Tests/PetstoreConsumerTests/Test_Server.swift @@ -36,13 +36,13 @@ final class Test_Server: XCTestCase { XCTAssertEqual(input.query.habitat, .water) XCTAssertEqual(input.query.since, .test) XCTAssertEqual(input.query.feeds, [.carnivore, .herbivore]) - XCTAssertEqual(input.headers.My_Request_UUID, "abcd-1234") + XCTAssertEqual(input.headers.My_hyphen_Request_hyphen_UUID, "abcd-1234") XCTAssertNil(input.body) return .ok( .init( headers: .init( - My_Response_UUID: "abcd", - My_Tracing_Header: "1234" + My_hyphen_Response_hyphen_UUID: "abcd", + My_hyphen_Tracing_hyphen_Header: "1234" ), body: .json([ .init(id: 1, name: "Fluffz") @@ -90,7 +90,7 @@ final class Test_Server: XCTestCase { listPetsBlock: { input in return .default( statusCode: 400, - .init(body: .json(.init(code: 1, me_sage: "Oh no!"))) + .init(body: .json(.init(code: 1, me_dollar_sage: "Oh no!"))) ) } ) @@ -123,7 +123,7 @@ final class Test_Server: XCTestCase { func testCreatePet_201() async throws { client = .init( createPetBlock: { input in - XCTAssertEqual(input.headers.X_Extra_Arguments, .init(code: 1)) + XCTAssertEqual(input.headers.X_hyphen_Extra_hyphen_Arguments, .init(code: 1)) guard case let .json(createPet) = input.body else { throw TestError.unexpectedValue(input.body) } @@ -131,7 +131,7 @@ final class Test_Server: XCTestCase { return .created( .init( headers: .init( - X_Extra_Arguments: .init(code: 1) + X_hyphen_Extra_hyphen_Arguments: .init(code: 1) ), body: .json( .init(id: 1, name: "Fluffz") @@ -183,7 +183,7 @@ final class Test_Server: XCTestCase { statusCode: 400, .init( headers: .init( - X_Reason: "bad luck" + X_hyphen_Reason: "bad luck" ), body: .json( .init(code: 1) @@ -440,6 +440,144 @@ final class Test_Server: XCTestCase { } catch {} } + func testGetStats_200_text() async throws { + client = .init( + getStatsBlock: { input in + return .ok(.init(body: .plainText("count is 1"))) + } + ) + let response = try await server.getStats( + .init( + path: "/api/pets/stats", + method: .patch, + headerFields: [ + .init(name: "accept", value: "application/json, text/plain, application/octet-stream") + ] + ), + .init() + ) + XCTAssertEqual(response.statusCode, 200) + XCTAssertEqual( + response.headerFields, + [ + .init(name: "content-type", value: "text/plain") + ] + ) + XCTAssertEqualStringifiedData( + response.body, + #""" + count is 1 + """# + ) + } + + func testGetStats_200_text_requestedSpecific() async throws { + client = .init( + getStatsBlock: { input in + XCTAssertEqual( + input.headers.accept, + [ + .init(contentType: .plainText), + .init(contentType: .json, quality: 0.5), + ] + ) + return .ok(.init(body: .plainText("count is 1"))) + } + ) + let response = try await server.getStats( + .init( + path: "/api/pets/stats", + method: .patch, + headerFields: [ + .init(name: "accept", value: "text/plain, application/json; q=0.500") + ] + ), + .init() + ) + XCTAssertEqual(response.statusCode, 200) + XCTAssertEqual( + response.headerFields, + [ + .init(name: "content-type", value: "text/plain") + ] + ) + XCTAssertEqualStringifiedData( + response.body, + #""" + count is 1 + """# + ) + } + + func testGetStats_200_text_customAccept() async throws { + client = .init( + getStatsBlock: { input in + XCTAssertEqual( + input.headers.accept, + [ + .init(contentType: .json, quality: 0.8), + .init(contentType: .plainText), + ] + ) + return .ok(.init(body: .plainText("count is 1"))) + } + ) + let response = try await server.getStats( + .init( + path: "/api/pets/stats", + method: .patch, + headerFields: [ + .init(name: "accept", value: "application/json; q=0.8, text/plain") + ] + ), + .init() + ) + XCTAssertEqual(response.statusCode, 200) + XCTAssertEqual( + response.headerFields, + [ + .init(name: "content-type", value: "text/plain") + ] + ) + XCTAssertEqualStringifiedData( + response.body, + #""" + count is 1 + """# + ) + } + + func testGetStats_200_binary() async throws { + client = .init( + getStatsBlock: { input in + return .ok(.init(body: .binary(Data("count_is_1".utf8)))) + } + ) + let response = try await server.getStats( + .init( + path: "/api/pets/stats", + method: .patch, + headerFields: [ + .init(name: "accept", value: "application/json, text/plain, application/octet-stream") + ] + ), + .init() + ) + XCTAssertEqual(response.statusCode, 200) + XCTAssertEqual( + response.headerFields, + [ + .init(name: "content-type", value: "application/octet-stream") + ] + ) + XCTAssertEqualStringifiedData( + response.body, + #""" + count_is_1 + """# + ) + } + func testPostStats_202_json() async throws { client = .init( postStatsBlock: { input in @@ -504,6 +642,68 @@ final class Test_Server: XCTestCase { XCTAssert(response.body.isEmpty) } + func testPostStats_202_text() async throws { + client = .init( + postStatsBlock: { input in + guard case let .plainText(stats) = input.body else { + throw TestError.unexpectedValue(input.body) + } + XCTAssertEqual(stats, "count is 1") + return .accepted(.init()) + } + ) + let response = try await server.postStats( + .init( + path: "/api/pets/stats", + method: .post, + headerFields: [ + .init(name: "content-type", value: "text/plain") + ], + encodedBody: #""" + count is 1 + """# + ), + .init() + ) + XCTAssertEqual(response.statusCode, 202) + XCTAssertEqual( + response.headerFields, + [] + ) + XCTAssert(response.body.isEmpty) + } + + func testPostStats_202_binary() async throws { + client = .init( + postStatsBlock: { input in + guard case let .binary(stats) = input.body else { + throw TestError.unexpectedValue(input.body) + } + XCTAssertEqualStringifiedData(stats, "count_is_1") + return .accepted(.init()) + } + ) + let response = try await server.postStats( + .init( + path: "/api/pets/stats", + method: .post, + headerFields: [ + .init(name: "content-type", value: "application/octet-stream") + ], + encodedBody: #""" + count_is_1 + """# + ), + .init() + ) + XCTAssertEqual(response.statusCode, 202) + XCTAssertEqual( + response.headerFields, + [] + ) + XCTAssert(response.body.isEmpty) + } + func testProbe_204() async throws { client = .init( probeBlock: { input in @@ -626,7 +826,7 @@ final class Test_Server: XCTestCase { throw TestError.unexpectedValue(input.body) } XCTAssertEqualStringifiedData(avatar, Data.abcdString) - return .internalServerError(.init(body: .text(Data.efghString))) + return .internalServerError(.init(body: .plainText(Data.efghString))) } ) let response = try await server.uploadAvatarForPet( diff --git a/Tests/PetstoreConsumerTests/Test_Types.swift b/Tests/PetstoreConsumerTests/Test_Types.swift index 46d28f9e..dabfe9d1 100644 --- a/Tests/PetstoreConsumerTests/Test_Types.swift +++ b/Tests/PetstoreConsumerTests/Test_Types.swift @@ -25,7 +25,7 @@ final class Test_Types: XCTestCase { func testStructCodingKeys() throws { let cases: [(Components.Schemas._Error.CodingKeys, String)] = [ (.code, "code"), - (.me_sage, "me$sage"), + (.me_dollar_sage, "me$sage"), ] for (value, rawValue) in cases { XCTAssertEqual(value.rawValue, rawValue) @@ -35,7 +35,7 @@ final class Test_Types: XCTestCase { func testEnumCoding() throws { let cases: [(Components.Schemas.PetKind, String)] = [ (.cat, "cat"), - (._nake, "$nake"), + (._dollar_nake, "$nake"), ] for (value, rawValue) in cases { XCTAssertEqual(value.rawValue, rawValue) @@ -188,9 +188,6 @@ final class Test_Types: XCTestCase { try _testRoundtrip( Components.Schemas.OneOfAny.case4(.init(message: "hello")) ) - try _testRoundtrip( - Components.Schemas.OneOfAny.undocumented(true) - ) } func testOneOfWithDiscriminator_roundtrip() throws { @@ -212,14 +209,6 @@ final class Test_Types: XCTestCase { ) ) ) - try _testRoundtrip( - Components.Schemas.OneOfObjectsWithDiscriminator - .undocumented( - .init(unvalidatedValue: [ - "kind": "nope" - ]) - ) - ) } func testOneOfWithDiscriminator_invalidDiscriminator() throws { diff --git a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Generated b/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Generated deleted file mode 120000 index a2357187..00000000 --- a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Generated +++ /dev/null @@ -1 +0,0 @@ -../OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore_FF_MultipleContentTypes \ No newline at end of file diff --git a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/TestClient.swift b/Tests/PetstoreConsumerTestsFFMultipleContentTypes/TestClient.swift deleted file mode 100644 index 8f731fc3..00000000 --- a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/TestClient.swift +++ /dev/null @@ -1,112 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftOpenAPIGenerator open source project -// -// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -import OpenAPIRuntime -import Foundation - -struct TestClient: APIProtocol { - - typealias ListPetsSignature = @Sendable (Operations.listPets.Input) async throws -> Operations.listPets.Output - var listPetsBlock: ListPetsSignature? - func listPets( - _ input: Operations.listPets.Input - ) async throws -> Operations.listPets.Output { - guard let block = listPetsBlock else { - throw UnspecifiedBlockError() - } - return try await block(input) - } - - typealias CreatePetSignature = @Sendable (Operations.createPet.Input) async throws -> Operations.createPet.Output - var createPetBlock: CreatePetSignature? - func createPet( - _ input: Operations.createPet.Input - ) async throws -> Operations.createPet.Output { - guard let block = createPetBlock else { - throw UnspecifiedBlockError() - } - return try await block(input) - } - - typealias GetStatsSignature = @Sendable (Operations.getStats.Input) async throws -> Operations.getStats.Output - var getStatsBlock: GetStatsSignature? - func getStats( - _ input: Operations.getStats.Input - ) async throws -> Operations.getStats.Output { - guard let block = getStatsBlock else { - throw UnspecifiedBlockError() - } - return try await block(input) - } - - typealias PostStatsSignature = @Sendable (Operations.postStats.Input) async throws -> Operations.postStats.Output - var postStatsBlock: PostStatsSignature? - func postStats( - _ input: Operations.postStats.Input - ) async throws -> Operations.postStats.Output { - guard let block = postStatsBlock else { - throw UnspecifiedBlockError() - } - return try await block(input) - } - - typealias ProbeSignature = @Sendable (Operations.probe.Input) async throws -> Operations.probe.Output - var probeBlock: ProbeSignature? - func probe( - _ input: Operations.probe.Input - ) async throws -> Operations.probe.Output { - guard let block = probeBlock else { - throw UnspecifiedBlockError() - } - return try await block(input) - } - - typealias UpdatePetSignature = @Sendable (Operations.updatePet.Input) async throws -> Operations.updatePet.Output - var updatePetBlock: UpdatePetSignature? - func updatePet( - _ input: Operations.updatePet.Input - ) async throws -> Operations.updatePet.Output { - guard let block = updatePetBlock else { - throw UnspecifiedBlockError() - } - return try await block(input) - } - - typealias UploadAvatarForPetSignature = @Sendable (Operations.uploadAvatarForPet.Input) async throws -> Operations - .uploadAvatarForPet.Output - var uploadAvatarForPetBlock: UploadAvatarForPetSignature? - func uploadAvatarForPet( - _ input: Operations.uploadAvatarForPet.Input - ) async throws -> Operations.uploadAvatarForPet.Output { - guard let block = uploadAvatarForPetBlock else { - throw UnspecifiedBlockError() - } - return try await block(input) - } -} - -struct UnspecifiedBlockError: Swift.Error, LocalizedError, CustomStringConvertible { - var function: StaticString - - var description: String { - "Unspecified block for \(function)" - } - - var errorDescription: String? { - description - } - - init(function: StaticString = #function) { - self.function = function - } -} diff --git a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/TestServer.swift b/Tests/PetstoreConsumerTestsFFMultipleContentTypes/TestServer.swift deleted file mode 100644 index 23b004ba..00000000 --- a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/TestServer.swift +++ /dev/null @@ -1,115 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftOpenAPIGenerator open source project -// -// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -import OpenAPIRuntime -import Foundation -import PetstoreConsumerTestCore - -extension APIProtocol { - func configuredServer( - for serverURLString: String = "/api" - ) throws -> TestServerTransport { - let transport = TestServerTransport() - try registerHandlers( - on: transport, - serverURL: try URL(validatingOpenAPIServerURL: serverURLString) - ) - return transport - } -} - -extension TestServerTransport { - - private func findHandler( - method: HTTPMethod, - path: [RouterPathComponent] - ) throws -> TestServerTransport.Handler { - guard - let handler = registered.first(where: { operation in - guard operation.inputs.method == method else { - return false - } - guard operation.inputs.path == path else { - return false - } - return true - }) - else { - throw TestError.noHandlerFound(method: method, path: path) - } - return handler.closure - } - - var listPets: Handler { - get throws { - try findHandler( - method: .get, - path: ["api", "pets"] - ) - } - } - - var createPet: Handler { - get throws { - try findHandler( - method: .post, - path: ["api", "pets"] - ) - } - } - - var updatePet: Handler { - get throws { - try findHandler( - method: .patch, - path: ["api", "pets", ":petId"] - ) - } - } - - var getStats: Handler { - get throws { - try findHandler( - method: .get, - path: ["api", "pets", "stats"] - ) - } - } - - var postStats: Handler { - get throws { - try findHandler( - method: .post, - path: ["api", "pets", "stats"] - ) - } - } - - var probe: Handler { - get throws { - try findHandler( - method: .post, - path: ["api", "probe"] - ) - } - } - - var uploadAvatarForPet: Handler { - get throws { - try findHandler( - method: .put, - path: ["api", "pets", ":petId", "avatar"] - ) - } - } -} diff --git a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Client.swift b/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Client.swift deleted file mode 100644 index 5f0b2b30..00000000 --- a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Client.swift +++ /dev/null @@ -1,242 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftOpenAPIGenerator open source project -// -// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -import XCTest -import OpenAPIRuntime -import PetstoreConsumerTestCore - -final class Test_Client: XCTestCase { - - var transport: TestClientTransport! - var client: Client { - get throws { - .init( - serverURL: try URL(validatingOpenAPIServerURL: "/api"), - transport: transport - ) - } - } - - override func setUp() async throws { - try await super.setUp() - continueAfterFailure = false - } - - func testGetStats_200_text() async throws { - transport = .init { request, baseURL, operationID in - XCTAssertEqual(operationID, "getStats") - XCTAssertEqual(request.path, "/pets/stats") - XCTAssertEqual(request.method, .get) - XCTAssertEqual( - request.headerFields, - [ - .init(name: "accept", value: "application/json, text/plain, application/octet-stream") - ] - ) - XCTAssertNil(request.body) - return .init( - statusCode: 200, - headers: [ - .init(name: "content-type", value: "text/plain") - ], - encodedBody: #""" - count is 1 - """# - ) - } - let response = try await client.getStats(.init()) - guard case let .ok(value) = response else { - XCTFail("Unexpected response: \(response)") - return - } - switch value.body { - case .plainText(let stats): - XCTAssertEqual(stats, "count is 1") - default: - XCTFail("Unexpected content type") - } - } - - func testGetStats_200_text_requestedSpecific() async throws { - transport = .init { request, baseURL, operationID in - XCTAssertEqual(operationID, "getStats") - XCTAssertEqual(request.path, "/pets/stats") - XCTAssertEqual(request.method, .get) - XCTAssertEqual( - request.headerFields, - [ - .init(name: "accept", value: "text/plain, application/json; q=0.500") - ] - ) - XCTAssertNil(request.body) - return .init( - statusCode: 200, - headers: [ - .init(name: "content-type", value: "text/plain") - ], - encodedBody: #""" - count is 1 - """# - ) - } - let response = try await client.getStats( - .init( - headers: .init(accept: [ - .init(contentType: .plainText), - .init(contentType: .json, quality: 0.5), - ]) - ) - ) - guard case let .ok(value) = response else { - XCTFail("Unexpected response: \(response)") - return - } - switch value.body { - case .plainText(let stats): - XCTAssertEqual(stats, "count is 1") - default: - XCTFail("Unexpected content type") - } - } - - func testGetStats_200_text_customAccept() async throws { - transport = .init { request, baseURL, operationID in - XCTAssertEqual(operationID, "getStats") - XCTAssertEqual(request.path, "/pets/stats") - XCTAssertEqual(request.method, .get) - XCTAssertEqual( - request.headerFields, - [ - .init(name: "accept", value: "application/json; q=0.800, text/plain") - ] - ) - XCTAssertNil(request.body) - return .init( - statusCode: 200, - headers: [ - .init(name: "content-type", value: "text/plain") - ], - encodedBody: #""" - count is 1 - """# - ) - } - let response = try await client.getStats( - .init( - headers: .init(accept: [ - .init(contentType: .json, quality: 0.8), - .init(contentType: .plainText), - ]) - ) - ) - guard case let .ok(value) = response else { - XCTFail("Unexpected response: \(response)") - return - } - switch value.body { - case .plainText(let stats): - XCTAssertEqual(stats, "count is 1") - default: - XCTFail("Unexpected content type") - } - } - - func testGetStats_200_binary() async throws { - transport = .init { request, baseURL, operationID in - XCTAssertEqual(operationID, "getStats") - XCTAssertEqual(request.path, "/pets/stats") - XCTAssertEqual(request.method, .get) - XCTAssertNil(request.body) - return .init( - statusCode: 200, - headers: [ - .init(name: "content-type", value: "application/octet-stream") - ], - encodedBody: #""" - count_is_1 - """# - ) - } - let response = try await client.getStats(.init()) - guard case let .ok(value) = response else { - XCTFail("Unexpected response: \(response)") - return - } - switch value.body { - case .binary(let stats): - XCTAssertEqual(String(decoding: stats, as: UTF8.self), "count_is_1") - default: - XCTFail("Unexpected content type") - } - } - - func testPostStats_202_text() async throws { - transport = .init { request, baseURL, operationID in - XCTAssertEqual(operationID, "postStats") - XCTAssertEqual(request.path, "/pets/stats") - XCTAssertNil(request.query) - XCTAssertEqual(baseURL.absoluteString, "/api") - XCTAssertEqual(request.method, .post) - XCTAssertEqual( - request.headerFields, - [ - .init(name: "content-type", value: "text/plain") - ] - ) - XCTAssertEqual( - request.body?.pretty, - #""" - count is 1 - """# - ) - return .init(statusCode: 202) - } - let response = try await client.postStats( - .init(body: .plainText("count is 1")) - ) - guard case .accepted = response else { - XCTFail("Unexpected response: \(response)") - return - } - } - - func testPostStats_202_binary() async throws { - transport = .init { request, baseURL, operationID in - XCTAssertEqual(operationID, "postStats") - XCTAssertEqual(request.path, "/pets/stats") - XCTAssertNil(request.query) - XCTAssertEqual(baseURL.absoluteString, "/api") - XCTAssertEqual(request.method, .post) - XCTAssertEqual( - request.headerFields, - [ - .init(name: "content-type", value: "application/octet-stream") - ] - ) - XCTAssertEqual( - request.body?.pretty, - #""" - count_is_1 - """# - ) - return .init(statusCode: 202) - } - let response = try await client.postStats( - .init(body: .binary(Data("count_is_1".utf8))) - ) - guard case .accepted = response else { - XCTFail("Unexpected response: \(response)") - return - } - } -} diff --git a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Server.swift b/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Server.swift deleted file mode 100644 index f5545bff..00000000 --- a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Server.swift +++ /dev/null @@ -1,231 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftOpenAPIGenerator open source project -// -// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -import XCTest -import OpenAPIRuntime -import PetstoreConsumerTestCore - -final class Test_Server: XCTestCase { - - var client: TestClient! - var server: TestServerTransport { - get throws { - try client.configuredServer() - } - } - - override func setUp() async throws { - try await super.setUp() - continueAfterFailure = false - } - - func testGetStats_200_text() async throws { - client = .init( - getStatsBlock: { input in - return .ok(.init(body: .plainText("count is 1"))) - } - ) - let response = try await server.getStats( - .init( - path: "/api/pets/stats", - method: .patch, - headerFields: [ - .init(name: "accept", value: "application/json, text/plain, application/octet-stream") - ] - ), - .init() - ) - XCTAssertEqual(response.statusCode, 200) - XCTAssertEqual( - response.headerFields, - [ - .init(name: "content-type", value: "text/plain") - ] - ) - XCTAssertEqualStringifiedData( - response.body, - #""" - count is 1 - """# - ) - } - - func testGetStats_200_text_requestedSpecific() async throws { - client = .init( - getStatsBlock: { input in - XCTAssertEqual( - input.headers.accept, - [ - .init(contentType: .plainText), - .init(contentType: .json, quality: 0.5), - ] - ) - return .ok(.init(body: .plainText("count is 1"))) - } - ) - let response = try await server.getStats( - .init( - path: "/api/pets/stats", - method: .patch, - headerFields: [ - .init(name: "accept", value: "text/plain, application/json; q=0.500") - ] - ), - .init() - ) - XCTAssertEqual(response.statusCode, 200) - XCTAssertEqual( - response.headerFields, - [ - .init(name: "content-type", value: "text/plain") - ] - ) - XCTAssertEqualStringifiedData( - response.body, - #""" - count is 1 - """# - ) - } - - func testGetStats_200_text_customAccept() async throws { - client = .init( - getStatsBlock: { input in - XCTAssertEqual( - input.headers.accept, - [ - .init(contentType: .json, quality: 0.8), - .init(contentType: .plainText), - ] - ) - return .ok(.init(body: .plainText("count is 1"))) - } - ) - let response = try await server.getStats( - .init( - path: "/api/pets/stats", - method: .patch, - headerFields: [ - .init(name: "accept", value: "application/json; q=0.8, text/plain") - ] - ), - .init() - ) - XCTAssertEqual(response.statusCode, 200) - XCTAssertEqual( - response.headerFields, - [ - .init(name: "content-type", value: "text/plain") - ] - ) - XCTAssertEqualStringifiedData( - response.body, - #""" - count is 1 - """# - ) - } - - func testGetStats_200_binary() async throws { - client = .init( - getStatsBlock: { input in - return .ok(.init(body: .binary(Data("count_is_1".utf8)))) - } - ) - let response = try await server.getStats( - .init( - path: "/api/pets/stats", - method: .patch, - headerFields: [ - .init(name: "accept", value: "application/json, text/plain, application/octet-stream") - ] - ), - .init() - ) - XCTAssertEqual(response.statusCode, 200) - XCTAssertEqual( - response.headerFields, - [ - .init(name: "content-type", value: "application/octet-stream") - ] - ) - XCTAssertEqualStringifiedData( - response.body, - #""" - count_is_1 - """# - ) - } - - func testPostStats_202_text() async throws { - client = .init( - postStatsBlock: { input in - guard case let .plainText(stats) = input.body else { - throw TestError.unexpectedValue(input.body) - } - XCTAssertEqual(stats, "count is 1") - return .accepted(.init()) - } - ) - let response = try await server.postStats( - .init( - path: "/api/pets/stats", - method: .post, - headerFields: [ - .init(name: "content-type", value: "text/plain") - ], - encodedBody: #""" - count is 1 - """# - ), - .init() - ) - XCTAssertEqual(response.statusCode, 202) - XCTAssertEqual( - response.headerFields, - [] - ) - XCTAssert(response.body.isEmpty) - } - - func testPostStats_202_binary() async throws { - client = .init( - postStatsBlock: { input in - guard case let .binary(stats) = input.body else { - throw TestError.unexpectedValue(input.body) - } - XCTAssertEqualStringifiedData(stats, "count_is_1") - return .accepted(.init()) - } - ) - let response = try await server.postStats( - .init( - path: "/api/pets/stats", - method: .post, - headerFields: [ - .init(name: "content-type", value: "application/octet-stream") - ], - encodedBody: #""" - count_is_1 - """# - ), - .init() - ) - XCTAssertEqual(response.statusCode, 202) - XCTAssertEqual( - response.headerFields, - [] - ) - XCTAssert(response.body.isEmpty) - } -} diff --git a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Types.swift b/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Types.swift deleted file mode 100644 index dabfe9d1..00000000 --- a/Tests/PetstoreConsumerTestsFFMultipleContentTypes/Test_Types.swift +++ /dev/null @@ -1,222 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftOpenAPIGenerator open source project -// -// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -import XCTest -import OpenAPIRuntime -import PetstoreConsumerTestCore - -final class Test_Types: XCTestCase { - - override func setUp() async throws { - try await super.setUp() - continueAfterFailure = false - } - - func testStructCodingKeys() throws { - let cases: [(Components.Schemas._Error.CodingKeys, String)] = [ - (.code, "code"), - (.me_dollar_sage, "me$sage"), - ] - for (value, rawValue) in cases { - XCTAssertEqual(value.rawValue, rawValue) - } - } - - func testEnumCoding() throws { - let cases: [(Components.Schemas.PetKind, String)] = [ - (.cat, "cat"), - (._dollar_nake, "$nake"), - ] - for (value, rawValue) in cases { - XCTAssertEqual(value.rawValue, rawValue) - } - } - - var testEncoder: JSONEncoder { - .init() - } - - var testDecoder: JSONDecoder { - .init() - } - - func roundtrip(_ value: T) throws -> T { - let data = try testEncoder.encode(value) - return try testDecoder.decode(T.self, from: data) - } - - func _testRoundtrip(_ value: T) throws { - let decodedValue = try roundtrip(value) - XCTAssertEqual(decodedValue, value) - } - - func testNoAdditionalPropertiesCoding_roundtrip() throws { - try _testRoundtrip( - Components.Schemas.NoAdditionalProperties(foo: "hi") - ) - } - - func testNoAdditionalPropertiesCoding_extraProperty() throws { - XCTAssertThrowsError( - try testDecoder.decode( - Components.Schemas.NoAdditionalProperties.self, - from: Data(#"{"foo":"hi","hello":1}"#.utf8) - ) - ) - } - - func testAnyAdditionalPropertiesCoding_roundtrip_noExtraProperty() throws { - try _testRoundtrip( - Components.Schemas.AnyAdditionalProperties( - foo: "hi", - additionalProperties: .init() - ) - ) - } - - func testAnyAdditionalPropertiesCoding_roundtrip_withExtraProperty() throws { - try _testRoundtrip( - Components.Schemas.AnyAdditionalProperties( - foo: "hi", - additionalProperties: .init(unvalidatedValue: [ - "hello": 1 - ]) - ) - ) - } - - func testTypedAdditionalPropertiesCoding_roundtrip_noExtraProperty() throws { - try _testRoundtrip( - Components.Schemas.TypedAdditionalProperties( - foo: "hi", - additionalProperties: [:] - ) - ) - } - - func testTypedAdditionalPropertiesCoding_roundtrip_withExtraProperty() throws { - try _testRoundtrip( - Components.Schemas.TypedAdditionalProperties( - foo: "hi", - additionalProperties: [ - "hello": 1 - ] - ) - ) - } - - func testAllOf_roundtrip() throws { - try _testRoundtrip( - Components.Schemas.AllOfObjects( - value1: .init(message: "hi"), - value2: .init(code: 1) - ) - ) - } - - func testAllOf_missingProperty() throws { - XCTAssertThrowsError( - try testDecoder.decode( - Components.Schemas.AllOfObjects.self, - from: Data(#"{}"#.utf8) - ) - ) - XCTAssertThrowsError( - try testDecoder.decode( - Components.Schemas.AllOfObjects.self, - from: Data(#"{"message":"hi"}"#.utf8) - ) - ) - XCTAssertThrowsError( - try testDecoder.decode( - Components.Schemas.AllOfObjects.self, - from: Data(#"{"code":1}"#.utf8) - ) - ) - } - - func testAnyOf_roundtrip() throws { - try _testRoundtrip( - Components.Schemas.AnyOfObjects( - value1: .init(message: "hi"), - value2: .init(code: 1) - ) - ) - try _testRoundtrip( - Components.Schemas.AnyOfObjects( - value1: .init(message: "hi"), - value2: nil - ) - ) - try _testRoundtrip( - Components.Schemas.AnyOfObjects( - value1: nil, - value2: .init(code: 1) - ) - ) - } - - func testAnyOf_allFailedToDecode() throws { - XCTAssertThrowsError( - try testDecoder.decode( - Components.Schemas.AnyOfObjects.self, - from: Data(#"{}"#.utf8) - ) - ) - } - - func testOneOfAny_roundtrip() throws { - try _testRoundtrip( - Components.Schemas.OneOfAny.case1("hi") - ) - try _testRoundtrip( - Components.Schemas.OneOfAny.case2(1) - ) - try _testRoundtrip( - Components.Schemas.OneOfAny.CodeError(.init(code: 2)) - ) - try _testRoundtrip( - Components.Schemas.OneOfAny.case4(.init(message: "hello")) - ) - } - - func testOneOfWithDiscriminator_roundtrip() throws { - try _testRoundtrip( - Components.Schemas.OneOfObjectsWithDiscriminator - .Walk( - .init( - kind: "Walk", - length: 1 - ) - ) - ) - try _testRoundtrip( - Components.Schemas.OneOfObjectsWithDiscriminator - .MessagedExercise( - .init( - value1: .init(kind: "MessagedExercise"), - value2: .init(message: "hello") - ) - ) - ) - } - - func testOneOfWithDiscriminator_invalidDiscriminator() throws { - XCTAssertThrowsError( - try testDecoder.decode( - Components.Schemas.OneOfObjectsWithDiscriminator.self, - from: Data(#"{}"#.utf8) - ) - ) - } -}