From c70e4f6a9d703d03d0c677b699ca6c193a2848fe Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:59:26 -0600 Subject: [PATCH 01/10] feat: enable (hacky) handling for anyOf and oneOf containing null --- .../GeneratorPipeline.swift | 252 ++- .../FileBasedReferenceTests.swift | 13 +- .../Resources/Docs/todolist.json | 488 +++++ .../ReferenceSources/Todolist/Client.swift | 661 ++++++ .../ReferenceSources/Todolist/Server.swift | 683 ++++++ .../ReferenceSources/Todolist/Types.swift | 1946 +++++++++++++++++ 6 files changed, 4041 insertions(+), 2 deletions(-) create mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json create mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift create mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift create mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index 8f4a8cf13..bcad3279a 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -69,7 +69,11 @@ struct GeneratorPipeline { /// - Returns: The output of the rendering stage. /// - Throws: An error if a non-recoverable issue occurs during pipeline execution. func run(_ input: RawInput) throws -> RenderedOutput { - try renderSwiftFilesStage.run(translateOpenAPIToStructuredSwiftStage.run(parseOpenAPIFileStage.run(input))) + var document = try parseOpenAPIFileStage.run(input) + + document.components.schemas = document.components.schemas.removingNullFromAnyOfAndOneOf() + + return try renderSwiftFilesStage.run(translateOpenAPIToStructuredSwiftStage.run(document)) } } @@ -133,3 +137,249 @@ func makeGeneratorPipeline( ) ) } + +extension JSONSchema { + /// Recursively removes null type entries from anyOf and oneOf arrays in the schema + /// When null is removed, it will set the schema context for that field as nullable to preserve semantics + /// This approach may not be 100% correct but it enables functionality that would otherwise fail. + /// + /// Background: currently, there are challenges with supporting OpenAPI definitions like this: + /// ``` + /// "phoneNumber": { + /// "description": "phone number", + /// "anyOf": [ + /// { "$ref": "#/components/schemas/PhoneNumber" }, + /// { "type": "null" } + /// ] + /// } + /// "phoneNumber2": { + /// "description": "phone number", + /// "oneOf": [ + /// { "$ref": "#/components/schemas/PhoneNumber" }, + /// { "type": "null" } + /// ] + /// } + /// "phoneNumber3": { + /// "description": "phone number", + /// "oneOf": [ + /// { "$ref": "#/components/schemas/PhoneNumber" }, + /// { "$ref": "#/components/schemas/PhoneNumber2" }, + /// { "type": "null" } + /// ] + /// } + /// ``` + /// This code will effectively treat those definitions as the following while marking them as nullable. + /// ``` + /// "phoneNumber": { + /// "description": "phone number", + /// "$ref": "#/components/schemas/PhoneNumber" + /// } + /// "phoneNumber2": { + /// "description": "phone number", + /// "$ref": "#/components/schemas/PhoneNumber" + /// } + /// "phoneNumber3": { + /// "description": "phone number", + /// "oneOf": [ + /// { "$ref": "#/components/schemas/PhoneNumber" }, + /// { "$ref": "#/components/schemas/PhoneNumber2" } + /// ] + /// } + /// ``` + func removingNullFromAnyOfAndOneOf() -> JSONSchema { + switch self.value { + case .object(let coreContext, let objectContext): + // Handle object properties + var newProperties = OrderedDictionary() + for (key, value) in objectContext.properties { + newProperties[key] = value.removingNullFromAnyOfAndOneOf() + } + + // Handle additionalProperties if it exists + let newAdditionalProperties: Either? + if let additionalProps = objectContext.additionalProperties { + switch additionalProps { + case .a(let boolValue): + newAdditionalProperties = .a(boolValue) + case .b(let schema): + newAdditionalProperties = .b(schema.removingNullFromAnyOfAndOneOf()) + } + } else { + newAdditionalProperties = nil + } + + // Create new ObjectContext + let newObjectContext = JSONSchema.ObjectContext( + properties: newProperties, + additionalProperties: newAdditionalProperties, + maxProperties: objectContext.maxProperties, + minProperties: objectContext.minProperties + ) + + return JSONSchema(schema: .object(coreContext, newObjectContext)) + + case .array(let coreContext, let arrayContext): + // Handle array items + let newItems = arrayContext.items?.removingNullFromAnyOfAndOneOf() + + let newArrayContext = JSONSchema.ArrayContext( + items: newItems, + maxItems: arrayContext.maxItems, + minItems: arrayContext.minItems, + prefixItems: arrayContext.prefixItems?.map { $0.removingNullFromAnyOfAndOneOf() }, + uniqueItems: arrayContext.uniqueItems + ) + + return JSONSchema(schema: .array(coreContext, newArrayContext)) + + case .all(of: let schemas, core: let coreContext): + // Handle allOf + let newSchemas = schemas.map { $0.removingNullFromAnyOfAndOneOf() } + return JSONSchema(schema: .all(of: newSchemas, core: coreContext)) + + case .one(of: let schemas, core: let coreContext): + // Handle oneOf - apply same null removal logic as anyOf + let filteredSchemas = schemas.compactMap { schema -> JSONSchema? in + // Remove schemas that are just null types + if case .null = schema.value { + return nil + } + return schema.removingNullFromAnyOfAndOneOf() + } + + // Check if we removed any null schemas + let hadNullSchema = schemas.count > filteredSchemas.count + + // If we only have one schema left after filtering, return it directly (and make it nullable if we removed null) + if filteredSchemas.count == 1 { + let resultSchema = filteredSchemas[0] + return hadNullSchema ? resultSchema.nullableSchemaObjectCopy() : resultSchema + } else if filteredSchemas.isEmpty { + // If all schemas were null, return a null schema (edge case) + return JSONSchema(schema: .null(coreContext)) + } else { + // Multiple schemas remain, keep as oneOf (and make nullable if we removed null) + let resultSchema = JSONSchema(schema: .one(of: filteredSchemas, core: coreContext)) + return hadNullSchema ? resultSchema.nullableSchemaObjectCopy() : resultSchema + } + + case .any(of: let schemas, core: let coreContext): + // Handle anyOf - this is where we remove null types + let filteredSchemas = schemas.compactMap { schema -> JSONSchema? in + // Remove schemas that are just null types + if case .null = schema.value { + return nil + } + return schema.removingNullFromAnyOfAndOneOf() + } + + // Check if we removed any null schemas + let hadNullSchema = schemas.count > filteredSchemas.count + + // If we only have one schema left after filtering, return it directly (and make it nullable if we removed null) + if filteredSchemas.count == 1 { + let resultSchema = filteredSchemas[0] + return hadNullSchema ? resultSchema.nullableSchemaObjectCopy() : resultSchema + } else if filteredSchemas.isEmpty { + // If all schemas were null, return a null schema (edge case) + return JSONSchema(schema: .null(coreContext)) + } else { + // Multiple schemas remain, keep as anyOf (and make nullable if we removed null) + let resultSchema = JSONSchema(schema: .any(of: filteredSchemas, core: coreContext)) + return hadNullSchema ? resultSchema.nullableSchemaObjectCopy() : resultSchema + } + + case .not(let schema, core: let coreContext): + // Handle not + return JSONSchema(schema: .not(schema.removingNullFromAnyOfAndOneOf(), core: coreContext)) + + case .reference: + // References remain unchanged + return self + + default: + // For primitive types (string, number, integer, boolean, null, fragment), return as-is + return self + } + } +} + +/// Extension for OpenAPI.ComponentDictionary +/// Need to constrain both the Key and Value types properly +extension OrderedDictionary where Key == OpenAPI.ComponentKey, Value == JSONSchema { + /// Removes null types from anyOf arrays in all JSONSchemas in the component dictionary + func removingNullFromAnyOfAndOneOf() -> OpenAPI.ComponentDictionary { + return self.mapValues { schema in + schema.removingNullFromAnyOfAndOneOf() + } + } +} + +/// Alternative approach using OrderedDictionary initializer +func removeNullFromComponentDictionary( + _ schemas: OpenAPI.ComponentDictionary +) -> OpenAPI.ComponentDictionary { + var processedSchemas = OrderedDictionary() + + for (key, schema) in schemas { + processedSchemas[key] = schema.removingNullFromAnyOfAndOneOf() + } + + return processedSchemas +} + + +extension JSONSchema { + /// in place of the existing/default` nullableSchemaObject()` located in `OpenAPIKit` + /// this version simply makes a copy changing on the value of nullable to true + public func nullableSchemaObjectCopy() -> JSONSchema { + switch value { + case .one(of: let schemas, core: let core): + return .init( + //warnings: warnings, // the init that allows maintaining warnings is internal + schema: .one(of: schemas, core: core.nullableContextCopy()) + ) + case .any(of: let schemas, core: let core): + return .init( + //warnings: warnings, // the init that allows maintaining warnings is internal + schema: .any(of: schemas, core: core.nullableContextCopy()) + ) + case .reference(let schema, let core): + return .init( + schema: .reference(schema, core.nullableContextCopy()) + ) + default: + return self.nullableSchemaObject() + } + } +} + +extension JSONSchema.CoreContext { + + /// only sets nullable to true while keeping everything else the same + /// this is similar to `nullableSchemaObject()` found in `OpenAPIKit`; however, + /// that version also modifies the required flag + func nullableContextCopy() -> JSONSchema.CoreContext { + + return JSONSchema.CoreContext( + format: format, + required: self.required, + nullable: true, + permissions: permissions, + deprecated: deprecated, + title: title, + description: description, + discriminator: discriminator, + externalDocs: externalDocs, + allowedValues: allowedValues, + defaultValue: defaultValue, + examples: examples, + anchor: anchor, + dynamicAnchor: dynamicAnchor, + defs: defs, + vendorExtensions: vendorExtensions, + _inferred: inferred + ) + + } +} diff --git a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift index 5596602bd..7f7e0369b 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift @@ -52,6 +52,8 @@ final class FileBasedReferenceTests: XCTestCase { } func testPetstore() throws { try _test(referenceProject: .init(name: .petstore)) } + + func testExample() throws { try _test(referenceProject: .init(name: .todolist)) } // MARK: - Private @@ -108,8 +110,17 @@ final class FileBasedReferenceTests: XCTestCase { enum ReferenceProjectName: String, Hashable, CaseIterable { case petstore + case todolist - var openAPIDocFileName: String { "\(rawValue).yaml" } + var openAPIDocFileName: String { + switch self { + case .petstore: + return "\(rawValue).yaml" + case .todolist: + return "\(rawValue).json" + } + + } var fixtureCodeDirectoryName: String { rawValue.capitalized } } diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json b/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json new file mode 100644 index 000000000..693dd4459 --- /dev/null +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json @@ -0,0 +1,488 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Open API example", + "summary": "An example Todo application", + "description": "# Todo API\n\nA very simple Todo app based on Aide Todo example in Rust\n", + "version": "" + }, + "paths": { + "/todo/": { + "get": { + "description": "List all Todo items.", + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/TodoList" } + } + } + } + } + }, + "post": { + "description": "Create a new incomplete Todo item.", + "requestBody": { + "description": "New Todo details.", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/NewTodo" } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "201": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/TodoCreated" } + } + } + }, + "409": { + "description": "conflict with username, email, phone, or similar unique required data", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + } + } + } + }, + "/todo/{id}": { + "get": { + "description": "Get a single Todo item.", + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the Todo.", + "required": true, + "schema": { + "description": "The ID of the Todo.", + "type": "string", + "format": "uuid" + }, + "style": "simple" + } + ], + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/TodoItem" }, + "example": { + "complete": false, + "description": "fix bugs", + "id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "404": { "description": "todo was not found" } + } + }, + "delete": { + "description": "Delete a Todo item.", + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the Todo.", + "required": true, + "schema": { + "description": "The ID of the Todo.", + "type": "string", + "format": "uuid" + }, + "style": "simple" + } + ], + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "204": { "description": "The Todo has been deleted." }, + "404": { "description": "The todo was not found" } + } + } + }, + "/todo/{id}/complete": { + "put": { + "description": "Complete a Todo.", + "parameters": [ + { + "in": "path", + "name": "id", + "description": "The ID of the Todo.", + "required": true, + "schema": { + "description": "The ID of the Todo.", + "type": "string", + "format": "uuid" + }, + "style": "simple" + } + ], + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "204": { "description": "no content" } + } + } + }, + "/todo/user/create": { + "post": { + "summary": "creates an account", + "description": "register a new account to be used", + "operationId": "create_user", + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/NewAccount" } + } + }, + "required": true + }, + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "201": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/Account" }, + "example": { + "email": "some@email.addr", + "id": "00000000-0000-0000-0000-000000000000", + "phoneNumber": { "countryCode": "1", "number": "5554443322" }, + "role": "user", + "username": "someUser" + } + } + } + }, + "400": { + "description": "bad request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorPayload" }, + "example": { "message": "msg" } + } + } + }, + "409": { + "description": "conflict with username, email, phone, or similar unique required data", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorPayload" }, + "example": { "message": "msg" } + } + } + }, + "500": { + "description": "parse error or missing data", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorPayload" }, + "example": { "message": "msg" } + } + } + } + }, + "security": [{ "ApiKey": ["user", "admin"] }] + } + }, + "/docs/": { + "get": { + "description": "This documentation page.", + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AppError" }, + "example": { + "error": "some error happened", + "error_id": "00000000-0000-0000-0000-000000000000" + } + } + } + }, + "200": { + "description": "HTML content", + "content": { "text/html": { "schema": { "type": "string" } } } + } + }, + "security": [{ "ApiKey": [] }] + } + } + }, + "components": { + "securitySchemes": { + "ApiKey": { + "type": "apiKey", + "in": "header", + "name": "X-Auth-Key", + "description": "A key that is ignored." + } + }, + "schemas": { + "Account": { + "type": "object", + "required": ["id", "role", "username"], + "properties": { + "email": { + "description": "email address", + "type": ["string", "null"] + }, + "id": { + "description": "internal uuid for the user", + "type": "string", + "format": "uuid" + }, + "phoneNumber": { + "description": "phone number", + "anyOf": [ + { "$ref": "#/components/schemas/PhoneNumber" }, + { "type": "null" } + ] + }, + "phoneNumber2": { + "description": "phone number", + "oneOf": [ + { "$ref": "#/components/schemas/PhoneNumber" }, + { "$ref": "#/components/schemas/PhoneNumber2" }, + { "type": "null" } + ] + }, + "phoneNumber3": { + "description": "phone number", + "oneOf": [ + { "$ref": "#/components/schemas/PhoneNumber" }, + { "type": "null" } + ] + }, + "role": { + "description": "The code (string) for referrals", + "$ref": "#/components/schemas/Role" + }, + "username": { + "description": "username as A-Za-z0-9", + "type": "string" + } + } + }, + "AppError": { + "description": "A default error response for most API errors.", + "type": "object", + "required": ["error", "error_id"], + "properties": { + "error": { "description": "An error message.", "type": "string" }, + "error_details": { + "description": "Optional Additional error details." + }, + "error_id": { + "description": "A unique error ID.", + "type": "string", + "format": "uuid" + } + } + }, + "ErrorPayload": { + "type": "object", + "required": ["message"], + "properties": { "message": { "type": "string" } } + }, + "NewAccount": { + "type": "object", + "required": ["role", "username"], + "properties": { + "email": { + "description": "email address", + "type": ["string", "null"] + }, + "phoneNumber": { + "description": "phone number", + "anyOf": [ + { "$ref": "#/components/schemas/PhoneNumber" }, + { "type": "null" } + ] + }, + "role": { + "description": "The code (string) for referrals", + "$ref": "#/components/schemas/Role" + }, + "username": { + "description": "username as A-Za-z0-9", + "type": "string" + } + } + }, + "NewTodo": { + "description": "New Todo details.", + "type": "object", + "required": ["description"], + "properties": { + "description": { + "description": "The description for the new Todo.", + "type": "string" + } + } + }, + "PhoneNumber": { + "type": "object", + "required": ["countryCode", "number"], + "properties": { + "countryCode": { + "description": "country code must contain only a set of digits 0-9", + "type": "string" + }, + "number": { + "description": "the number should be a set of digits \"333555222\".", + "type": "string" + } + } + }, + "PhoneNumber2": { + "type": "object", + "required": ["countryCode", "number"], + "properties": { + "countryCode": { + "description": "country code must contain only a set of digits 0-9", + "type": "string" + }, + "number": { + "description": "the number should be a set of digits \"333555222\".", + "type": "string" + } + } + }, + "Role": { "type": "string", "enum": ["user", "admin"] }, + "SelectTodo": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "description": "The ID of the Todo.", + "type": "string", + "format": "uuid" + } + } + }, + "TodoCreated": { + "description": "New Todo details.", + "type": "object", + "required": ["id"], + "properties": { + "id": { + "description": "The ID of the new Todo.", + "type": "string", + "format": "uuid" + } + } + }, + "TodoItem": { + "description": "A single Todo item.", + "type": "object", + "required": ["complete", "description", "id"], + "properties": { + "complete": { + "description": "Whether the item was completed.", + "type": "boolean" + }, + "description": { + "description": "The description of the item.", + "type": "string" + }, + "id": { "type": "string", "format": "uuid" } + } + }, + "TodoList": { + "type": "object", + "required": ["todo_ids"], + "properties": { + "todo_ids": { + "type": "array", + "items": { "type": "string", "format": "uuid" } + } + } + } + } + }, + "tags": [{ "name": "todo", "description": "Todo Management" }] +} + diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift new file mode 100644 index 000000000..7e0708b1b --- /dev/null +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift @@ -0,0 +1,661 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +/// # Todo API +/// +/// A very simple Todo app based on Aide Todo example in Rust +/// +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: Foundation.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 Todo items. + /// + /// - Remark: HTTP `GET /todo/`. + /// - Remark: Generated from `#/paths//todo//get`. + public func getTodo(_ input: Operations.GetTodo.Input) async throws -> Operations.GetTodo.Output { + try await client.send( + input: input, + forOperation: Operations.GetTodo.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/todo/", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetTodo.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.TodoList.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetTodo.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// Create a new incomplete Todo item. + /// + /// - Remark: HTTP `POST /todo/`. + /// - Remark: Generated from `#/paths//todo//post`. + public func postTodo(_ input: Operations.PostTodo.Input) async throws -> Operations.PostTodo.Output { + try await client.send( + input: input, + forOperation: Operations.PostTodo.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/todo/", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 201: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.PostTodo.Output.Created.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.TodoCreated.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .created(.init(body: body)) + case 409: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.PostTodo.Output.Conflict.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .conflict(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.PostTodo.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// Get a single Todo item. + /// + /// - Remark: HTTP `GET /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/get`. + public func getTodoId(_ input: Operations.GetTodoId.Input) async throws -> Operations.GetTodoId.Output { + try await client.send( + input: input, + forOperation: Operations.GetTodoId.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/todo/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetTodoId.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.TodoItem.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 404: + return .notFound(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetTodoId.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// Delete a Todo item. + /// + /// - Remark: HTTP `DELETE /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/delete`. + public func deleteTodoId(_ input: Operations.DeleteTodoId.Input) async throws -> Operations.DeleteTodoId.Output { + try await client.send( + input: input, + forOperation: Operations.DeleteTodoId.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/todo/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + case 404: + return .notFound(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.DeleteTodoId.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// Complete a Todo. + /// + /// - Remark: HTTP `PUT /todo/{id}/complete`. + /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. + public func putTodoIdComplete(_ input: Operations.PutTodoIdComplete.Input) async throws -> Operations.PutTodoIdComplete.Output { + try await client.send( + input: input, + forOperation: Operations.PutTodoIdComplete.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/todo/{}/complete", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.PutTodoIdComplete.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// creates an account + /// + /// register a new account to be used + /// + /// - Remark: HTTP `POST /todo/user/create`. + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. + public func createUser(_ input: Operations.CreateUser.Input) async throws -> Operations.CreateUser.Output { + try await client.send( + input: input, + forOperation: Operations.CreateUser.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/todo/user/create", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 201: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateUser.Output.Created.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.Account.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .created(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateUser.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.ErrorPayload.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + case 409: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateUser.Output.Conflict.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.ErrorPayload.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .conflict(.init(body: body)) + case 500: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateUser.Output.InternalServerError.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.ErrorPayload.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .internalServerError(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateUser.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// This documentation page. + /// + /// - Remark: HTTP `GET /docs/`. + /// - Remark: Generated from `#/paths//docs//get`. + public func getDocs(_ input: Operations.GetDocs.Input) async throws -> Operations.GetDocs.Output { + try await client.send( + input: input, + forOperation: Operations.GetDocs.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/docs/", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetDocs.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "text/html" + ] + ) + switch chosenContentType { + case "text/html": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .html(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetDocs.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.AppError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } +} diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift new file mode 100644 index 000000000..e994b9258 --- /dev/null +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift @@ -0,0 +1,683 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +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: Foundation.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.getTodo( + request: $0, + body: $1, + metadata: $2 + ) + }, + method: .get, + path: server.apiPathComponentsWithServerPrefix("/todo/") + ) + try transport.register( + { + try await server.postTodo( + request: $0, + body: $1, + metadata: $2 + ) + }, + method: .post, + path: server.apiPathComponentsWithServerPrefix("/todo/") + ) + try transport.register( + { + try await server.getTodoId( + request: $0, + body: $1, + metadata: $2 + ) + }, + method: .get, + path: server.apiPathComponentsWithServerPrefix("/todo/{id}") + ) + try transport.register( + { + try await server.deleteTodoId( + request: $0, + body: $1, + metadata: $2 + ) + }, + method: .delete, + path: server.apiPathComponentsWithServerPrefix("/todo/{id}") + ) + try transport.register( + { + try await server.putTodoIdComplete( + request: $0, + body: $1, + metadata: $2 + ) + }, + method: .put, + path: server.apiPathComponentsWithServerPrefix("/todo/{id}/complete") + ) + try transport.register( + { + try await server.createUser( + request: $0, + body: $1, + metadata: $2 + ) + }, + method: .post, + path: server.apiPathComponentsWithServerPrefix("/todo/user/create") + ) + try transport.register( + { + try await server.getDocs( + request: $0, + body: $1, + metadata: $2 + ) + }, + method: .get, + path: server.apiPathComponentsWithServerPrefix("/docs/") + ) + } +} + +fileprivate extension UniversalServer where APIHandler: APIProtocol { + /// List all Todo items. + /// + /// - Remark: HTTP `GET /todo/`. + /// - Remark: Generated from `#/paths//todo//get`. + func getTodo( + request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + metadata: OpenAPIRuntime.ServerRequestMetadata + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + try await handle( + request: request, + requestBody: body, + metadata: metadata, + forOperation: Operations.GetTodo.id, + using: { + APIHandler.getTodo($0) + }, + deserializer: { request, requestBody, metadata in + let headers: Operations.GetTodo.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) + return Operations.GetTodo.Input(headers: headers) + }, + serializer: { output, request in + switch output { + case let .ok(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 200) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .`default`(statusCode, value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + } + } + ) + } + /// Create a new incomplete Todo item. + /// + /// - Remark: HTTP `POST /todo/`. + /// - Remark: Generated from `#/paths//todo//post`. + func postTodo( + request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + metadata: OpenAPIRuntime.ServerRequestMetadata + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + try await handle( + request: request, + requestBody: body, + metadata: metadata, + forOperation: Operations.PostTodo.id, + using: { + APIHandler.postTodo($0) + }, + deserializer: { request, requestBody, metadata in + let headers: Operations.PostTodo.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) + let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) + let body: Operations.PostTodo.Input.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getRequiredRequestBodyAsJSON( + Components.Schemas.NewTodo.self, + from: requestBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return Operations.PostTodo.Input( + headers: headers, + body: body + ) + }, + serializer: { output, request in + switch output { + case let .created(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 201) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .conflict(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 409) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .`default`(statusCode, value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + } + } + ) + } + /// Get a single Todo item. + /// + /// - Remark: HTTP `GET /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/get`. + func getTodoId( + request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + metadata: OpenAPIRuntime.ServerRequestMetadata + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + try await handle( + request: request, + requestBody: body, + metadata: metadata, + forOperation: Operations.GetTodoId.id, + using: { + APIHandler.getTodoId($0) + }, + deserializer: { request, requestBody, metadata in + let path: Operations.GetTodoId.Input.Path = .init(id: try converter.getPathParameterAsURI( + in: metadata.pathParameters, + name: "id", + as: Swift.String.self + )) + let headers: Operations.GetTodoId.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) + return Operations.GetTodoId.Input( + path: path, + headers: headers + ) + }, + serializer: { output, request in + switch output { + case let .ok(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 200) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .notFound(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 404) + suppressMutabilityWarning(&response) + return (response, nil) + case let .`default`(statusCode, value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + } + } + ) + } + /// Delete a Todo item. + /// + /// - Remark: HTTP `DELETE /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/delete`. + func deleteTodoId( + request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + metadata: OpenAPIRuntime.ServerRequestMetadata + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + try await handle( + request: request, + requestBody: body, + metadata: metadata, + forOperation: Operations.DeleteTodoId.id, + using: { + APIHandler.deleteTodoId($0) + }, + deserializer: { request, requestBody, metadata in + let path: Operations.DeleteTodoId.Input.Path = .init(id: try converter.getPathParameterAsURI( + in: metadata.pathParameters, + name: "id", + as: Swift.String.self + )) + let headers: Operations.DeleteTodoId.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) + return Operations.DeleteTodoId.Input( + path: path, + headers: headers + ) + }, + serializer: { output, request in + switch output { + case let .noContent(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 204) + suppressMutabilityWarning(&response) + return (response, nil) + case let .notFound(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 404) + suppressMutabilityWarning(&response) + return (response, nil) + case let .`default`(statusCode, value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + } + } + ) + } + /// Complete a Todo. + /// + /// - Remark: HTTP `PUT /todo/{id}/complete`. + /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. + func putTodoIdComplete( + request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + metadata: OpenAPIRuntime.ServerRequestMetadata + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + try await handle( + request: request, + requestBody: body, + metadata: metadata, + forOperation: Operations.PutTodoIdComplete.id, + using: { + APIHandler.putTodoIdComplete($0) + }, + deserializer: { request, requestBody, metadata in + let path: Operations.PutTodoIdComplete.Input.Path = .init(id: try converter.getPathParameterAsURI( + in: metadata.pathParameters, + name: "id", + as: Swift.String.self + )) + let headers: Operations.PutTodoIdComplete.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) + return Operations.PutTodoIdComplete.Input( + path: path, + headers: headers + ) + }, + serializer: { output, request in + switch output { + case let .noContent(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 204) + suppressMutabilityWarning(&response) + return (response, nil) + case let .`default`(statusCode, value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + } + } + ) + } + /// creates an account + /// + /// register a new account to be used + /// + /// - Remark: HTTP `POST /todo/user/create`. + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. + func createUser( + request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + metadata: OpenAPIRuntime.ServerRequestMetadata + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + try await handle( + request: request, + requestBody: body, + metadata: metadata, + forOperation: Operations.CreateUser.id, + using: { + APIHandler.createUser($0) + }, + deserializer: { request, requestBody, metadata in + let headers: Operations.CreateUser.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) + let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) + let body: Operations.CreateUser.Input.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getRequiredRequestBodyAsJSON( + Components.Schemas.NewAccount.self, + from: requestBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return Operations.CreateUser.Input( + headers: headers, + body: body + ) + }, + serializer: { output, request in + switch output { + case let .created(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 201) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .badRequest(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 400) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .conflict(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 409) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .internalServerError(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 500) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + case let .`default`(statusCode, value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + } + } + ) + } + /// This documentation page. + /// + /// - Remark: HTTP `GET /docs/`. + /// - Remark: Generated from `#/paths//docs//get`. + func getDocs( + request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + metadata: OpenAPIRuntime.ServerRequestMetadata + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + try await handle( + request: request, + requestBody: body, + metadata: metadata, + forOperation: Operations.GetDocs.id, + using: { + APIHandler.getDocs($0) + }, + deserializer: { request, requestBody, metadata in + let headers: Operations.GetDocs.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) + return Operations.GetDocs.Input(headers: headers) + }, + serializer: { output, request in + switch output { + case let .ok(value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: 200) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .html(value): + try converter.validateAcceptIfPresent( + "text/html", + in: request.headerFields + ) + body = try converter.setResponseBodyAsBinary( + value, + headerFields: &response.headerFields, + contentType: "text/html" + ) + } + return (response, body) + case let .`default`(statusCode, value): + suppressUnusedWarning(value) + var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) + suppressMutabilityWarning(&response) + let body: OpenAPIRuntime.HTTPBody + switch value.body { + case let .json(value): + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) + body = try converter.setResponseBodyAsJSON( + value, + headerFields: &response.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (response, body) + } + } + ) + } +} diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift new file mode 100644 index 000000000..742efdadb --- /dev/null +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift @@ -0,0 +1,1946 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +public protocol APIProtocol: Sendable { + /// List all Todo items. + /// + /// - Remark: HTTP `GET /todo/`. + /// - Remark: Generated from `#/paths//todo//get`. + func getTodo(_ input: Operations.GetTodo.Input) async throws -> Operations.GetTodo.Output + /// Create a new incomplete Todo item. + /// + /// - Remark: HTTP `POST /todo/`. + /// - Remark: Generated from `#/paths//todo//post`. + func postTodo(_ input: Operations.PostTodo.Input) async throws -> Operations.PostTodo.Output + /// Get a single Todo item. + /// + /// - Remark: HTTP `GET /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/get`. + func getTodoId(_ input: Operations.GetTodoId.Input) async throws -> Operations.GetTodoId.Output + /// Delete a Todo item. + /// + /// - Remark: HTTP `DELETE /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/delete`. + func deleteTodoId(_ input: Operations.DeleteTodoId.Input) async throws -> Operations.DeleteTodoId.Output + /// Complete a Todo. + /// + /// - Remark: HTTP `PUT /todo/{id}/complete`. + /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. + func putTodoIdComplete(_ input: Operations.PutTodoIdComplete.Input) async throws -> Operations.PutTodoIdComplete.Output + /// creates an account + /// + /// register a new account to be used + /// + /// - Remark: HTTP `POST /todo/user/create`. + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. + func createUser(_ input: Operations.CreateUser.Input) async throws -> Operations.CreateUser.Output + /// This documentation page. + /// + /// - Remark: HTTP `GET /docs/`. + /// - Remark: Generated from `#/paths//docs//get`. + func getDocs(_ input: Operations.GetDocs.Input) async throws -> Operations.GetDocs.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// List all Todo items. + /// + /// - Remark: HTTP `GET /todo/`. + /// - Remark: Generated from `#/paths//todo//get`. + public func getTodo(headers: Operations.GetTodo.Input.Headers = .init()) async throws -> Operations.GetTodo.Output { + try await getTodo(Operations.GetTodo.Input(headers: headers)) + } + /// Create a new incomplete Todo item. + /// + /// - Remark: HTTP `POST /todo/`. + /// - Remark: Generated from `#/paths//todo//post`. + public func postTodo( + headers: Operations.PostTodo.Input.Headers = .init(), + body: Operations.PostTodo.Input.Body + ) async throws -> Operations.PostTodo.Output { + try await postTodo(Operations.PostTodo.Input( + headers: headers, + body: body + )) + } + /// Get a single Todo item. + /// + /// - Remark: HTTP `GET /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/get`. + public func getTodoId( + path: Operations.GetTodoId.Input.Path, + headers: Operations.GetTodoId.Input.Headers = .init() + ) async throws -> Operations.GetTodoId.Output { + try await getTodoId(Operations.GetTodoId.Input( + path: path, + headers: headers + )) + } + /// Delete a Todo item. + /// + /// - Remark: HTTP `DELETE /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/delete`. + public func deleteTodoId( + path: Operations.DeleteTodoId.Input.Path, + headers: Operations.DeleteTodoId.Input.Headers = .init() + ) async throws -> Operations.DeleteTodoId.Output { + try await deleteTodoId(Operations.DeleteTodoId.Input( + path: path, + headers: headers + )) + } + /// Complete a Todo. + /// + /// - Remark: HTTP `PUT /todo/{id}/complete`. + /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. + public func putTodoIdComplete( + path: Operations.PutTodoIdComplete.Input.Path, + headers: Operations.PutTodoIdComplete.Input.Headers = .init() + ) async throws -> Operations.PutTodoIdComplete.Output { + try await putTodoIdComplete(Operations.PutTodoIdComplete.Input( + path: path, + headers: headers + )) + } + /// creates an account + /// + /// register a new account to be used + /// + /// - Remark: HTTP `POST /todo/user/create`. + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. + public func createUser( + headers: Operations.CreateUser.Input.Headers = .init(), + body: Operations.CreateUser.Input.Body + ) async throws -> Operations.CreateUser.Output { + try await createUser(Operations.CreateUser.Input( + headers: headers, + body: body + )) + } + /// This documentation page. + /// + /// - Remark: HTTP `GET /docs/`. + /// - Remark: Generated from `#/paths//docs//get`. + public func getDocs(headers: Operations.GetDocs.Input.Headers = .init()) async throws -> Operations.GetDocs.Output { + try await getDocs(Operations.GetDocs.Input(headers: headers)) + } +} + +/// Server URLs defined in the OpenAPI document. +public enum Servers {} + +/// 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 { + /// - Remark: Generated from `#/components/schemas/Account`. + public struct Account: Codable, Hashable, Sendable { + /// email address + /// + /// - Remark: Generated from `#/components/schemas/Account/email`. + public var email: Swift.String? + /// internal uuid for the user + /// + /// - Remark: Generated from `#/components/schemas/Account/id`. + public var id: Swift.String + /// - Remark: Generated from `#/components/schemas/Account/phoneNumber`. + public var phoneNumber: Components.Schemas.PhoneNumber? + /// phone number + /// + /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2`. + @frozen public enum PhoneNumber2Payload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2/case1`. + case PhoneNumber(Components.Schemas.PhoneNumber) + /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2/case2`. + case PhoneNumber2(Components.Schemas.PhoneNumber2) + public init(from decoder: any Decoder) throws { + var errors: [any Error] = [] + do { + self = .PhoneNumber(try .init(from: decoder)) + return + } catch { + errors.append(error) + } + do { + self = .PhoneNumber2(try .init(from: decoder)) + return + } catch { + errors.append(error) + } + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + public func encode(to encoder: any Encoder) throws { + switch self { + case let .PhoneNumber(value): + try value.encode(to: encoder) + case let .PhoneNumber2(value): + try value.encode(to: encoder) + } + } + } + /// phone number + /// + /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2`. + public var phoneNumber2: Components.Schemas.Account.PhoneNumber2Payload? + /// - Remark: Generated from `#/components/schemas/Account/phoneNumber3`. + public var phoneNumber3: Components.Schemas.PhoneNumber? + /// The code (string) for referrals + /// + /// - Remark: Generated from `#/components/schemas/Account/role`. + public var role: Components.Schemas.Role + /// username as A-Za-z0-9 + /// + /// - Remark: Generated from `#/components/schemas/Account/username`. + public var username: Swift.String + /// Creates a new `Account`. + /// + /// - Parameters: + /// - email: email address + /// - id: internal uuid for the user + /// - phoneNumber: + /// - phoneNumber2: phone number + /// - phoneNumber3: + /// - role: The code (string) for referrals + /// - username: username as A-Za-z0-9 + public init( + email: Swift.String? = nil, + id: Swift.String, + phoneNumber: Components.Schemas.PhoneNumber? = nil, + phoneNumber2: Components.Schemas.Account.PhoneNumber2Payload? = nil, + phoneNumber3: Components.Schemas.PhoneNumber? = nil, + role: Components.Schemas.Role, + username: Swift.String + ) { + self.email = email + self.id = id + self.phoneNumber = phoneNumber + self.phoneNumber2 = phoneNumber2 + self.phoneNumber3 = phoneNumber3 + self.role = role + self.username = username + } + public enum CodingKeys: String, CodingKey { + case email + case id + case phoneNumber + case phoneNumber2 + case phoneNumber3 + case role + case username + } + } + /// A default error response for most API errors. + /// + /// - Remark: Generated from `#/components/schemas/AppError`. + public struct AppError: Codable, Hashable, Sendable { + /// An error message. + /// + /// - Remark: Generated from `#/components/schemas/AppError/error`. + public var error: Swift.String + /// Optional Additional error details. + /// + /// - Remark: Generated from `#/components/schemas/AppError/error_details`. + public var errorDetails: OpenAPIRuntime.OpenAPIValueContainer? + /// A unique error ID. + /// + /// - Remark: Generated from `#/components/schemas/AppError/error_id`. + public var errorId: Swift.String + /// Creates a new `AppError`. + /// + /// - Parameters: + /// - error: An error message. + /// - errorDetails: Optional Additional error details. + /// - errorId: A unique error ID. + public init( + error: Swift.String, + errorDetails: OpenAPIRuntime.OpenAPIValueContainer? = nil, + errorId: Swift.String + ) { + self.error = error + self.errorDetails = errorDetails + self.errorId = errorId + } + public enum CodingKeys: String, CodingKey { + case error + case errorDetails = "error_details" + case errorId = "error_id" + } + } + /// - Remark: Generated from `#/components/schemas/ErrorPayload`. + public struct ErrorPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ErrorPayload/message`. + public var message: Swift.String + /// Creates a new `ErrorPayload`. + /// + /// - Parameters: + /// - message: + public init(message: Swift.String) { + self.message = message + } + public enum CodingKeys: String, CodingKey { + case message + } + } + /// - Remark: Generated from `#/components/schemas/NewAccount`. + public struct NewAccount: Codable, Hashable, Sendable { + /// email address + /// + /// - Remark: Generated from `#/components/schemas/NewAccount/email`. + public var email: Swift.String? + /// - Remark: Generated from `#/components/schemas/NewAccount/phoneNumber`. + public var phoneNumber: Components.Schemas.PhoneNumber? + /// The code (string) for referrals + /// + /// - Remark: Generated from `#/components/schemas/NewAccount/role`. + public var role: Components.Schemas.Role + /// username as A-Za-z0-9 + /// + /// - Remark: Generated from `#/components/schemas/NewAccount/username`. + public var username: Swift.String + /// Creates a new `NewAccount`. + /// + /// - Parameters: + /// - email: email address + /// - phoneNumber: + /// - role: The code (string) for referrals + /// - username: username as A-Za-z0-9 + public init( + email: Swift.String? = nil, + phoneNumber: Components.Schemas.PhoneNumber? = nil, + role: Components.Schemas.Role, + username: Swift.String + ) { + self.email = email + self.phoneNumber = phoneNumber + self.role = role + self.username = username + } + public enum CodingKeys: String, CodingKey { + case email + case phoneNumber + case role + case username + } + } + /// New Todo details. + /// + /// - Remark: Generated from `#/components/schemas/NewTodo`. + public struct NewTodo: Codable, Hashable, Sendable { + /// The description for the new Todo. + /// + /// - Remark: Generated from `#/components/schemas/NewTodo/description`. + public var description: Swift.String + /// Creates a new `NewTodo`. + /// + /// - Parameters: + /// - description: The description for the new Todo. + public init(description: Swift.String) { + self.description = description + } + public enum CodingKeys: String, CodingKey { + case description + } + } + /// - Remark: Generated from `#/components/schemas/PhoneNumber`. + public struct PhoneNumber: Codable, Hashable, Sendable { + /// country code must contain only a set of digits 0-9 + /// + /// - Remark: Generated from `#/components/schemas/PhoneNumber/countryCode`. + public var countryCode: Swift.String + /// the number should be a set of digits "333555222". + /// + /// - Remark: Generated from `#/components/schemas/PhoneNumber/number`. + public var number: Swift.String + /// Creates a new `PhoneNumber`. + /// + /// - Parameters: + /// - countryCode: country code must contain only a set of digits 0-9 + /// - number: the number should be a set of digits "333555222". + public init( + countryCode: Swift.String, + number: Swift.String + ) { + self.countryCode = countryCode + self.number = number + } + public enum CodingKeys: String, CodingKey { + case countryCode + case number + } + } + /// - Remark: Generated from `#/components/schemas/PhoneNumber2`. + public struct PhoneNumber2: Codable, Hashable, Sendable { + /// country code must contain only a set of digits 0-9 + /// + /// - Remark: Generated from `#/components/schemas/PhoneNumber2/countryCode`. + public var countryCode: Swift.String + /// the number should be a set of digits "333555222". + /// + /// - Remark: Generated from `#/components/schemas/PhoneNumber2/number`. + public var number: Swift.String + /// Creates a new `PhoneNumber2`. + /// + /// - Parameters: + /// - countryCode: country code must contain only a set of digits 0-9 + /// - number: the number should be a set of digits "333555222". + public init( + countryCode: Swift.String, + number: Swift.String + ) { + self.countryCode = countryCode + self.number = number + } + public enum CodingKeys: String, CodingKey { + case countryCode + case number + } + } + /// - Remark: Generated from `#/components/schemas/Role`. + @frozen public enum Role: String, Codable, Hashable, Sendable, CaseIterable { + case user = "user" + case admin = "admin" + } + /// - Remark: Generated from `#/components/schemas/SelectTodo`. + public struct SelectTodo: Codable, Hashable, Sendable { + /// The ID of the Todo. + /// + /// - Remark: Generated from `#/components/schemas/SelectTodo/id`. + public var id: Swift.String + /// Creates a new `SelectTodo`. + /// + /// - Parameters: + /// - id: The ID of the Todo. + public init(id: Swift.String) { + self.id = id + } + public enum CodingKeys: String, CodingKey { + case id + } + } + /// New Todo details. + /// + /// - Remark: Generated from `#/components/schemas/TodoCreated`. + public struct TodoCreated: Codable, Hashable, Sendable { + /// The ID of the new Todo. + /// + /// - Remark: Generated from `#/components/schemas/TodoCreated/id`. + public var id: Swift.String + /// Creates a new `TodoCreated`. + /// + /// - Parameters: + /// - id: The ID of the new Todo. + public init(id: Swift.String) { + self.id = id + } + public enum CodingKeys: String, CodingKey { + case id + } + } + /// A single Todo item. + /// + /// - Remark: Generated from `#/components/schemas/TodoItem`. + public struct TodoItem: Codable, Hashable, Sendable { + /// Whether the item was completed. + /// + /// - Remark: Generated from `#/components/schemas/TodoItem/complete`. + public var complete: Swift.Bool + /// The description of the item. + /// + /// - Remark: Generated from `#/components/schemas/TodoItem/description`. + public var description: Swift.String + /// - Remark: Generated from `#/components/schemas/TodoItem/id`. + public var id: Swift.String + /// Creates a new `TodoItem`. + /// + /// - Parameters: + /// - complete: Whether the item was completed. + /// - description: The description of the item. + /// - id: + public init( + complete: Swift.Bool, + description: Swift.String, + id: Swift.String + ) { + self.complete = complete + self.description = description + self.id = id + } + public enum CodingKeys: String, CodingKey { + case complete + case description + case id + } + } + /// - Remark: Generated from `#/components/schemas/TodoList`. + public struct TodoList: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/TodoList/todo_ids`. + public var todoIds: [Swift.String] + /// Creates a new `TodoList`. + /// + /// - Parameters: + /// - todoIds: + public init(todoIds: [Swift.String]) { + self.todoIds = todoIds + } + public enum CodingKeys: String, CodingKey { + case todoIds = "todo_ids" + } + } + } + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + public enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + public enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + public enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + public enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +public enum Operations { + /// List all Todo items. + /// + /// - Remark: HTTP `GET /todo/`. + /// - Remark: Generated from `#/paths//todo//get`. + public enum GetTodo { + public static let id: Swift.String = "get/todo/" + public struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/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.GetTodo.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + public init(headers: Operations.GetTodo.Input.Headers = .init()) { + self.headers = headers + } + } + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/GET/responses/200/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/GET/responses/200/content/application\/json`. + case json(Components.Schemas.TodoList) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.TodoList { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.GetTodo.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.GetTodo.Output.Ok.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo//get/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.GetTodo.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + public var ok: Operations.GetTodo.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + public struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/GET/responses/default/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/GET/responses/default/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.GetTodo.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.GetTodo.Output.Default.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo//get/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.GetTodo.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + public var `default`: Operations.GetTodo.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + @frozen public enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + public init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + public var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + public static var allCases: [Self] { + [ + .json + ] + } + } + } + /// Create a new incomplete Todo item. + /// + /// - Remark: HTTP `POST /todo/`. + /// - Remark: Generated from `#/paths//todo//post`. + public enum PostTodo { + public static let id: Swift.String = "post/todo/" + public struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/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.PostTodo.Input.Headers + /// - Remark: Generated from `#/paths/todo/POST/requestBody`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/requestBody/content/application\/json`. + case json(Components.Schemas.NewTodo) + } + public var body: Operations.PostTodo.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + public init( + headers: Operations.PostTodo.Input.Headers = .init(), + body: Operations.PostTodo.Input.Body + ) { + self.headers = headers + self.body = body + } + } + @frozen public enum Output: Sendable, Hashable { + public struct Created: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/responses/201/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/responses/201/content/application\/json`. + case json(Components.Schemas.TodoCreated) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.TodoCreated { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.PostTodo.Output.Created.Body + /// Creates a new `Created`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.PostTodo.Output.Created.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo//post/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.PostTodo.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + public var created: Operations.PostTodo.Output.Created { + get throws { + switch self { + case let .created(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + public struct Conflict: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/responses/409/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/responses/409/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.PostTodo.Output.Conflict.Body + /// Creates a new `Conflict`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.PostTodo.Output.Conflict.Body) { + self.body = body + } + } + /// conflict with username, email, phone, or similar unique required data + /// + /// - Remark: Generated from `#/paths//todo//post/responses/409`. + /// + /// HTTP response code: `409 conflict`. + case conflict(Operations.PostTodo.Output.Conflict) + /// The associated value of the enum case if `self` is `.conflict`. + /// + /// - Throws: An error if `self` is not `.conflict`. + /// - SeeAlso: `.conflict`. + public var conflict: Operations.PostTodo.Output.Conflict { + get throws { + switch self { + case let .conflict(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "conflict", + response: self + ) + } + } + } + public struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/responses/default/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/POST/responses/default/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.PostTodo.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.PostTodo.Output.Default.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo//post/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.PostTodo.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + public var `default`: Operations.PostTodo.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + @frozen public enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + public init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + public var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + public static var allCases: [Self] { + [ + .json + ] + } + } + } + /// Get a single Todo item. + /// + /// - Remark: HTTP `GET /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/get`. + public enum GetTodoId { + public static let id: Swift.String = "get/todo/{id}" + public struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/GET/path`. + public struct Path: Sendable, Hashable { + /// The ID of the Todo. + /// + /// - Remark: Generated from `#/paths/todo/{id}/GET/path/id`. + public var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: The ID of the Todo. + public init(id: Swift.String) { + self.id = id + } + } + public var path: Operations.GetTodoId.Input.Path + /// - Remark: Generated from `#/paths/todo/{id}/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.GetTodoId.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + public init( + path: Operations.GetTodoId.Input.Path, + headers: Operations.GetTodoId.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/200/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.TodoItem) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.TodoItem { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.GetTodoId.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.GetTodoId.Output.Ok.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo/{id}/get/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.GetTodoId.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + public var ok: Operations.GetTodoId.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + public struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + public init() {} + } + /// todo was not found + /// + /// - Remark: Generated from `#/paths//todo/{id}/get/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.GetTodoId.Output.NotFound) + /// todo was not found + /// + /// - Remark: Generated from `#/paths//todo/{id}/get/responses/404`. + /// + /// HTTP response code: `404 notFound`. + public static var notFound: Self { + .notFound(.init()) + } + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + public var notFound: Operations.GetTodoId.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + public struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/default/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/default/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.GetTodoId.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.GetTodoId.Output.Default.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo/{id}/get/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.GetTodoId.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + public var `default`: Operations.GetTodoId.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + @frozen public enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + public init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + public var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + public static var allCases: [Self] { + [ + .json + ] + } + } + } + /// Delete a Todo item. + /// + /// - Remark: HTTP `DELETE /todo/{id}`. + /// - Remark: Generated from `#/paths//todo/{id}/delete`. + public enum DeleteTodoId { + public static let id: Swift.String = "delete/todo/{id}" + public struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/DELETE/path`. + public struct Path: Sendable, Hashable { + /// The ID of the Todo. + /// + /// - Remark: Generated from `#/paths/todo/{id}/DELETE/path/id`. + public var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: The ID of the Todo. + public init(id: Swift.String) { + self.id = id + } + } + public var path: Operations.DeleteTodoId.Input.Path + /// - Remark: Generated from `#/paths/todo/{id}/DELETE/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.DeleteTodoId.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + public init( + path: Operations.DeleteTodoId.Input.Path, + headers: Operations.DeleteTodoId.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + @frozen public enum Output: Sendable, Hashable { + public struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + public init() {} + } + /// The Todo has been deleted. + /// + /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.DeleteTodoId.Output.NoContent) + /// The Todo has been deleted. + /// + /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/204`. + /// + /// HTTP response code: `204 noContent`. + public static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + public var noContent: Operations.DeleteTodoId.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + public struct NotFound: Sendable, Hashable { + /// Creates a new `NotFound`. + public init() {} + } + /// The todo was not found + /// + /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/404`. + /// + /// HTTP response code: `404 notFound`. + case notFound(Operations.DeleteTodoId.Output.NotFound) + /// The todo was not found + /// + /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/404`. + /// + /// HTTP response code: `404 notFound`. + public static var notFound: Self { + .notFound(.init()) + } + /// The associated value of the enum case if `self` is `.notFound`. + /// + /// - Throws: An error if `self` is not `.notFound`. + /// - SeeAlso: `.notFound`. + public var notFound: Operations.DeleteTodoId.Output.NotFound { + get throws { + switch self { + case let .notFound(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "notFound", + response: self + ) + } + } + } + public struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/DELETE/responses/default/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/DELETE/responses/default/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.DeleteTodoId.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.DeleteTodoId.Output.Default.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.DeleteTodoId.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + public var `default`: Operations.DeleteTodoId.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + @frozen public enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + public init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + public var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + public static var allCases: [Self] { + [ + .json + ] + } + } + } + /// Complete a Todo. + /// + /// - Remark: HTTP `PUT /todo/{id}/complete`. + /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. + public enum PutTodoIdComplete { + public static let id: Swift.String = "put/todo/{id}/complete" + public struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/path`. + public struct Path: Sendable, Hashable { + /// The ID of the Todo. + /// + /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/path/id`. + public var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: The ID of the Todo. + public init(id: Swift.String) { + self.id = id + } + } + public var path: Operations.PutTodoIdComplete.Input.Path + /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/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.PutTodoIdComplete.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + public init( + path: Operations.PutTodoIdComplete.Input.Path, + headers: Operations.PutTodoIdComplete.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + @frozen public enum Output: Sendable, Hashable { + public struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + public init() {} + } + /// no content + /// + /// - Remark: Generated from `#/paths//todo/{id}/complete/put/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.PutTodoIdComplete.Output.NoContent) + /// no content + /// + /// - Remark: Generated from `#/paths//todo/{id}/complete/put/responses/204`. + /// + /// HTTP response code: `204 noContent`. + public static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + public var noContent: Operations.PutTodoIdComplete.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + public struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/responses/default/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/responses/default/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.PutTodoIdComplete.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.PutTodoIdComplete.Output.Default.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo/{id}/complete/put/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.PutTodoIdComplete.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + public var `default`: Operations.PutTodoIdComplete.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + @frozen public enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + public init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + public var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + public static var allCases: [Self] { + [ + .json + ] + } + } + } + /// creates an account + /// + /// register a new account to be used + /// + /// - Remark: HTTP `POST /todo/user/create`. + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. + public enum CreateUser { + public static let id: Swift.String = "create_user" + public struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/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.CreateUser.Input.Headers + /// - Remark: Generated from `#/paths/todo/user/create/POST/requestBody`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/requestBody/content/application\/json`. + case json(Components.Schemas.NewAccount) + } + public var body: Operations.CreateUser.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + public init( + headers: Operations.CreateUser.Input.Headers = .init(), + body: Operations.CreateUser.Input.Body + ) { + self.headers = headers + self.body = body + } + } + @frozen public enum Output: Sendable, Hashable { + public struct Created: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/201/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/201/content/application\/json`. + case json(Components.Schemas.Account) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.Account { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.CreateUser.Output.Created.Body + /// Creates a new `Created`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.CreateUser.Output.Created.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.CreateUser.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + public var created: Operations.CreateUser.Output.Created { + get throws { + switch self { + case let .created(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + public struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/400/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/400/content/application\/json`. + case json(Components.Schemas.ErrorPayload) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.ErrorPayload { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.CreateUser.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.CreateUser.Output.BadRequest.Body) { + self.body = body + } + } + /// bad request + /// + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CreateUser.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + public var badRequest: Operations.CreateUser.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + public struct Conflict: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/409/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/409/content/application\/json`. + case json(Components.Schemas.ErrorPayload) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.ErrorPayload { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.CreateUser.Output.Conflict.Body + /// Creates a new `Conflict`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.CreateUser.Output.Conflict.Body) { + self.body = body + } + } + /// conflict with username, email, phone, or similar unique required data + /// + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/409`. + /// + /// HTTP response code: `409 conflict`. + case conflict(Operations.CreateUser.Output.Conflict) + /// The associated value of the enum case if `self` is `.conflict`. + /// + /// - Throws: An error if `self` is not `.conflict`. + /// - SeeAlso: `.conflict`. + public var conflict: Operations.CreateUser.Output.Conflict { + get throws { + switch self { + case let .conflict(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "conflict", + response: self + ) + } + } + } + public struct InternalServerError: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/500/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/500/content/application\/json`. + case json(Components.Schemas.ErrorPayload) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.ErrorPayload { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.CreateUser.Output.InternalServerError.Body + /// Creates a new `InternalServerError`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.CreateUser.Output.InternalServerError.Body) { + self.body = body + } + } + /// parse error or missing data + /// + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/500`. + /// + /// HTTP response code: `500 internalServerError`. + case internalServerError(Operations.CreateUser.Output.InternalServerError) + /// The associated value of the enum case if `self` is `.internalServerError`. + /// + /// - Throws: An error if `self` is not `.internalServerError`. + /// - SeeAlso: `.internalServerError`. + public var internalServerError: Operations.CreateUser.Output.InternalServerError { + get throws { + switch self { + case let .internalServerError(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "internalServerError", + response: self + ) + } + } + } + public struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/default/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/default/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.CreateUser.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.CreateUser.Output.Default.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.CreateUser.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + public var `default`: Operations.CreateUser.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + @frozen public enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + public init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + public var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + public static var allCases: [Self] { + [ + .json + ] + } + } + } + /// This documentation page. + /// + /// - Remark: HTTP `GET /docs/`. + /// - Remark: Generated from `#/paths//docs//get`. + public enum GetDocs { + public static let id: Swift.String = "get/docs/" + public struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/docs/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.GetDocs.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + public init(headers: Operations.GetDocs.Input.Headers = .init()) { + self.headers = headers + } + } + @frozen public enum Output: Sendable, Hashable { + public struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/docs/GET/responses/200/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/docs/GET/responses/200/content/text\/html`. + case html(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.html`. + /// + /// - Throws: An error if `self` is not `.html`. + /// - SeeAlso: `.html`. + public var html: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .html(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.GetDocs.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.GetDocs.Output.Ok.Body) { + self.body = body + } + } + /// HTML content + /// + /// - Remark: Generated from `#/paths//docs//get/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.GetDocs.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + public var ok: Operations.GetDocs.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + public struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/docs/GET/responses/default/content`. + @frozen public enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/docs/GET/responses/default/content/application\/json`. + case json(Components.Schemas.AppError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + public var json: Components.Schemas.AppError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + public var body: Operations.GetDocs.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + public init(body: Operations.GetDocs.Output.Default.Body) { + self.body = body + } + } + /// + /// + /// - Remark: Generated from `#/paths//docs//get/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.GetDocs.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + public var `default`: Operations.GetDocs.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + @frozen public enum AcceptableContentType: AcceptableProtocol { + case html + case json + case other(Swift.String) + public init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "text/html": + self = .html + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + public var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .html: + return "text/html" + case .json: + return "application/json" + } + } + public static var allCases: [Self] { + [ + .html, + .json + ] + } + } + } +} From a4fa39bdba33cf942ac79d1c077f47ccd0661aa7 Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:02:06 -0600 Subject: [PATCH 02/10] chore: formating changes --- .../GeneratorPipeline.swift | 64 ++++--------------- 1 file changed, 13 insertions(+), 51 deletions(-) diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index bcad3279a..dbc91e320 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -72,7 +72,6 @@ struct GeneratorPipeline { var document = try parseOpenAPIFileStage.run(input) document.components.schemas = document.components.schemas.removingNullFromAnyOfAndOneOf() - return try renderSwiftFilesStage.run(translateOpenAPIToStructuredSwiftStage.run(document)) } } @@ -191,23 +190,17 @@ extension JSONSchema { case .object(let coreContext, let objectContext): // Handle object properties var newProperties = OrderedDictionary() - for (key, value) in objectContext.properties { - newProperties[key] = value.removingNullFromAnyOfAndOneOf() - } - + for (key, value) in objectContext.properties { newProperties[key] = value.removingNullFromAnyOfAndOneOf() } // Handle additionalProperties if it exists let newAdditionalProperties: Either? if let additionalProps = objectContext.additionalProperties { switch additionalProps { - case .a(let boolValue): - newAdditionalProperties = .a(boolValue) - case .b(let schema): - newAdditionalProperties = .b(schema.removingNullFromAnyOfAndOneOf()) + case .a(let boolValue): newAdditionalProperties = .a(boolValue) + case .b(let schema): newAdditionalProperties = .b(schema.removingNullFromAnyOfAndOneOf()) } } else { newAdditionalProperties = nil } - // Create new ObjectContext let newObjectContext = JSONSchema.ObjectContext( properties: newProperties, @@ -215,13 +208,10 @@ extension JSONSchema { maxProperties: objectContext.maxProperties, minProperties: objectContext.minProperties ) - return JSONSchema(schema: .object(coreContext, newObjectContext)) - case .array(let coreContext, let arrayContext): // Handle array items let newItems = arrayContext.items?.removingNullFromAnyOfAndOneOf() - let newArrayContext = JSONSchema.ArrayContext( items: newItems, maxItems: arrayContext.maxItems, @@ -229,27 +219,20 @@ extension JSONSchema { prefixItems: arrayContext.prefixItems?.map { $0.removingNullFromAnyOfAndOneOf() }, uniqueItems: arrayContext.uniqueItems ) - return JSONSchema(schema: .array(coreContext, newArrayContext)) - case .all(of: let schemas, core: let coreContext): // Handle allOf let newSchemas = schemas.map { $0.removingNullFromAnyOfAndOneOf() } return JSONSchema(schema: .all(of: newSchemas, core: coreContext)) - case .one(of: let schemas, core: let coreContext): // Handle oneOf - apply same null removal logic as anyOf let filteredSchemas = schemas.compactMap { schema -> JSONSchema? in // Remove schemas that are just null types - if case .null = schema.value { - return nil - } + if case .null = schema.value { return nil } return schema.removingNullFromAnyOfAndOneOf() } - // Check if we removed any null schemas let hadNullSchema = schemas.count > filteredSchemas.count - // If we only have one schema left after filtering, return it directly (and make it nullable if we removed null) if filteredSchemas.count == 1 { let resultSchema = filteredSchemas[0] @@ -262,20 +245,15 @@ extension JSONSchema { let resultSchema = JSONSchema(schema: .one(of: filteredSchemas, core: coreContext)) return hadNullSchema ? resultSchema.nullableSchemaObjectCopy() : resultSchema } - case .any(of: let schemas, core: let coreContext): // Handle anyOf - this is where we remove null types let filteredSchemas = schemas.compactMap { schema -> JSONSchema? in // Remove schemas that are just null types - if case .null = schema.value { - return nil - } + if case .null = schema.value { return nil } return schema.removingNullFromAnyOfAndOneOf() } - // Check if we removed any null schemas let hadNullSchema = schemas.count > filteredSchemas.count - // If we only have one schema left after filtering, return it directly (and make it nullable if we removed null) if filteredSchemas.count == 1 { let resultSchema = filteredSchemas[0] @@ -288,15 +266,12 @@ extension JSONSchema { let resultSchema = JSONSchema(schema: .any(of: filteredSchemas, core: coreContext)) return hadNullSchema ? resultSchema.nullableSchemaObjectCopy() : resultSchema } - case .not(let schema, core: let coreContext): // Handle not return JSONSchema(schema: .not(schema.removingNullFromAnyOfAndOneOf(), core: coreContext)) - case .reference: // References remain unchanged return self - default: // For primitive types (string, number, integer, boolean, null, fragment), return as-is return self @@ -309,26 +284,19 @@ extension JSONSchema { extension OrderedDictionary where Key == OpenAPI.ComponentKey, Value == JSONSchema { /// Removes null types from anyOf arrays in all JSONSchemas in the component dictionary func removingNullFromAnyOfAndOneOf() -> OpenAPI.ComponentDictionary { - return self.mapValues { schema in - schema.removingNullFromAnyOfAndOneOf() - } + self.mapValues { schema in schema.removingNullFromAnyOfAndOneOf() } } } /// Alternative approach using OrderedDictionary initializer -func removeNullFromComponentDictionary( - _ schemas: OpenAPI.ComponentDictionary -) -> OpenAPI.ComponentDictionary { +func removeNullFromComponentDictionary(_ schemas: OpenAPI.ComponentDictionary) + -> OpenAPI.ComponentDictionary +{ var processedSchemas = OrderedDictionary() - - for (key, schema) in schemas { - processedSchemas[key] = schema.removingNullFromAnyOfAndOneOf() - } - + for (key, schema) in schemas { processedSchemas[key] = schema.removingNullFromAnyOfAndOneOf() } return processedSchemas } - extension JSONSchema { /// in place of the existing/default` nullableSchemaObject()` located in `OpenAPIKit` /// this version simply makes a copy changing on the value of nullable to true @@ -344,24 +312,18 @@ extension JSONSchema { //warnings: warnings, // the init that allows maintaining warnings is internal schema: .any(of: schemas, core: core.nullableContextCopy()) ) - case .reference(let schema, let core): - return .init( - schema: .reference(schema, core.nullableContextCopy()) - ) - default: - return self.nullableSchemaObject() + case .reference(let schema, let core): return .init(schema: .reference(schema, core.nullableContextCopy())) + default: return self.nullableSchemaObject() } } } extension JSONSchema.CoreContext { - /// only sets nullable to true while keeping everything else the same /// this is similar to `nullableSchemaObject()` found in `OpenAPIKit`; however, /// that version also modifies the required flag func nullableContextCopy() -> JSONSchema.CoreContext { - - return JSONSchema.CoreContext( + JSONSchema.CoreContext( format: format, required: self.required, nullable: true, From 6d7f534ebe39cfd9ab140e118db5bfeb1bc81073 Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Thu, 25 Sep 2025 14:09:40 -0600 Subject: [PATCH 03/10] chore: update comment only --- Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index dbc91e320..64431b451 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -321,7 +321,8 @@ extension JSONSchema { extension JSONSchema.CoreContext { /// only sets nullable to true while keeping everything else the same /// this is similar to `nullableSchemaObject()` found in `OpenAPIKit`; however, - /// that version also modifies the required flag + /// that version *might* modify the required parameter (not sure as Xcode treats + /// `required` as a reserved word) func nullableContextCopy() -> JSONSchema.CoreContext { JSONSchema.CoreContext( format: format, From def1390ed8f7c8353d7f9335b25c9a014bf0aebc Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Fri, 26 Sep 2025 09:52:12 -0600 Subject: [PATCH 04/10] fix: I think we can use the built-in nullableContext --- .../GeneratorPipeline.swift | 35 ++----------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index 64431b451..bf3a936b5 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -305,44 +305,15 @@ extension JSONSchema { case .one(of: let schemas, core: let core): return .init( //warnings: warnings, // the init that allows maintaining warnings is internal - schema: .one(of: schemas, core: core.nullableContextCopy()) + schema: .one(of: schemas, core: core.nullableContext()) ) case .any(of: let schemas, core: let core): return .init( //warnings: warnings, // the init that allows maintaining warnings is internal - schema: .any(of: schemas, core: core.nullableContextCopy()) + schema: .any(of: schemas, core: core.nullableContext()) ) - case .reference(let schema, let core): return .init(schema: .reference(schema, core.nullableContextCopy())) + case .reference(let schema, let core): return .init(schema: .reference(schema, core.nullableContext())) default: return self.nullableSchemaObject() } } } - -extension JSONSchema.CoreContext { - /// only sets nullable to true while keeping everything else the same - /// this is similar to `nullableSchemaObject()` found in `OpenAPIKit`; however, - /// that version *might* modify the required parameter (not sure as Xcode treats - /// `required` as a reserved word) - func nullableContextCopy() -> JSONSchema.CoreContext { - JSONSchema.CoreContext( - format: format, - required: self.required, - nullable: true, - permissions: permissions, - deprecated: deprecated, - title: title, - description: description, - discriminator: discriminator, - externalDocs: externalDocs, - allowedValues: allowedValues, - defaultValue: defaultValue, - examples: examples, - anchor: anchor, - dynamicAnchor: dynamicAnchor, - defs: defs, - vendorExtensions: vendorExtensions, - _inferred: inferred - ) - - } -} From 6ec897b7004592a9cf375a29f3f977dd19934261 Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:30:21 -0600 Subject: [PATCH 05/10] chore: improve feat integration point --- .../GeneratorPipeline.swift | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index bf3a936b5..83d567520 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -69,10 +69,7 @@ struct GeneratorPipeline { /// - Returns: The output of the rendering stage. /// - Throws: An error if a non-recoverable issue occurs during pipeline execution. func run(_ input: RawInput) throws -> RenderedOutput { - var document = try parseOpenAPIFileStage.run(input) - - document.components.schemas = document.components.schemas.removingNullFromAnyOfAndOneOf() - return try renderSwiftFilesStage.run(translateOpenAPIToStructuredSwiftStage.run(document)) + return try renderSwiftFilesStage.run(translateOpenAPIToStructuredSwiftStage.run(parseOpenAPIFileStage.run(input))) } } @@ -112,9 +109,10 @@ func makeGeneratorPipeline( return filteredDoc } let validateDoc = { (doc: OpenAPI.Document) -> OpenAPI.Document in - let validationDiagnostics = try validator(doc, config) + let sanitizedDoc = sanitizeSchemaNulls(doc) + let validationDiagnostics = try validator(sanitizedDoc, config) for diagnostic in validationDiagnostics { try diagnostics.emit(diagnostic) } - return doc + return sanitizedDoc } return .init( parseOpenAPIFileStage: .init( @@ -288,13 +286,11 @@ extension OrderedDictionary where Key == OpenAPI.ComponentKey, Value == JSONSche } } -/// Alternative approach using OrderedDictionary initializer -func removeNullFromComponentDictionary(_ schemas: OpenAPI.ComponentDictionary) - -> OpenAPI.ComponentDictionary -{ - var processedSchemas = OrderedDictionary() - for (key, schema) in schemas { processedSchemas[key] = schema.removingNullFromAnyOfAndOneOf() } - return processedSchemas +/// uses `removingNullFromAnyOfAndOneOf()` to remove from an OpenAPI Document +func sanitizeSchemaNulls(_ doc: OpenAPI.Document) -> OpenAPI.Document { + var doc = doc + doc.components.schemas = doc.components.schemas.removingNullFromAnyOfAndOneOf() + return doc } extension JSONSchema { From ff3edb66f9badf24f9e7b898d963fc2c634bb0d3 Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:42:05 -0600 Subject: [PATCH 06/10] feat: implement snippet tests - remove file based tests --- .../FileBasedReferenceTests.swift | 13 +- .../Resources/Docs/todolist.json | 488 ----- .../ReferenceSources/Todolist/Client.swift | 661 ------ .../ReferenceSources/Todolist/Server.swift | 683 ------ .../ReferenceSources/Todolist/Types.swift | 1946 ----------------- .../SnippetBasedReferenceTests.swift | 281 ++- 6 files changed, 280 insertions(+), 3792 deletions(-) delete mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json delete mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift delete mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift delete mode 100644 Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift diff --git a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift index 7f7e0369b..5596602bd 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift @@ -52,8 +52,6 @@ final class FileBasedReferenceTests: XCTestCase { } func testPetstore() throws { try _test(referenceProject: .init(name: .petstore)) } - - func testExample() throws { try _test(referenceProject: .init(name: .todolist)) } // MARK: - Private @@ -110,17 +108,8 @@ final class FileBasedReferenceTests: XCTestCase { enum ReferenceProjectName: String, Hashable, CaseIterable { case petstore - case todolist - var openAPIDocFileName: String { - switch self { - case .petstore: - return "\(rawValue).yaml" - case .todolist: - return "\(rawValue).json" - } - - } + var openAPIDocFileName: String { "\(rawValue).yaml" } var fixtureCodeDirectoryName: String { rawValue.capitalized } } diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json b/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json deleted file mode 100644 index 693dd4459..000000000 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/todolist.json +++ /dev/null @@ -1,488 +0,0 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "Open API example", - "summary": "An example Todo application", - "description": "# Todo API\n\nA very simple Todo app based on Aide Todo example in Rust\n", - "version": "" - }, - "paths": { - "/todo/": { - "get": { - "description": "List all Todo items.", - "responses": { - "default": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/TodoList" } - } - } - } - } - }, - "post": { - "description": "Create a new incomplete Todo item.", - "requestBody": { - "description": "New Todo details.", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/NewTodo" } - } - }, - "required": true - }, - "responses": { - "default": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "201": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/TodoCreated" } - } - } - }, - "409": { - "description": "conflict with username, email, phone, or similar unique required data", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - } - } - } - }, - "/todo/{id}": { - "get": { - "description": "Get a single Todo item.", - "parameters": [ - { - "in": "path", - "name": "id", - "description": "The ID of the Todo.", - "required": true, - "schema": { - "description": "The ID of the Todo.", - "type": "string", - "format": "uuid" - }, - "style": "simple" - } - ], - "responses": { - "default": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "200": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/TodoItem" }, - "example": { - "complete": false, - "description": "fix bugs", - "id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "404": { "description": "todo was not found" } - } - }, - "delete": { - "description": "Delete a Todo item.", - "parameters": [ - { - "in": "path", - "name": "id", - "description": "The ID of the Todo.", - "required": true, - "schema": { - "description": "The ID of the Todo.", - "type": "string", - "format": "uuid" - }, - "style": "simple" - } - ], - "responses": { - "default": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "204": { "description": "The Todo has been deleted." }, - "404": { "description": "The todo was not found" } - } - } - }, - "/todo/{id}/complete": { - "put": { - "description": "Complete a Todo.", - "parameters": [ - { - "in": "path", - "name": "id", - "description": "The ID of the Todo.", - "required": true, - "schema": { - "description": "The ID of the Todo.", - "type": "string", - "format": "uuid" - }, - "style": "simple" - } - ], - "responses": { - "default": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "204": { "description": "no content" } - } - } - }, - "/todo/user/create": { - "post": { - "summary": "creates an account", - "description": "register a new account to be used", - "operationId": "create_user", - "requestBody": { - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/NewAccount" } - } - }, - "required": true - }, - "responses": { - "default": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "201": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/Account" }, - "example": { - "email": "some@email.addr", - "id": "00000000-0000-0000-0000-000000000000", - "phoneNumber": { "countryCode": "1", "number": "5554443322" }, - "role": "user", - "username": "someUser" - } - } - } - }, - "400": { - "description": "bad request", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ErrorPayload" }, - "example": { "message": "msg" } - } - } - }, - "409": { - "description": "conflict with username, email, phone, or similar unique required data", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ErrorPayload" }, - "example": { "message": "msg" } - } - } - }, - "500": { - "description": "parse error or missing data", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/ErrorPayload" }, - "example": { "message": "msg" } - } - } - } - }, - "security": [{ "ApiKey": ["user", "admin"] }] - } - }, - "/docs/": { - "get": { - "description": "This documentation page.", - "responses": { - "default": { - "description": "", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/AppError" }, - "example": { - "error": "some error happened", - "error_id": "00000000-0000-0000-0000-000000000000" - } - } - } - }, - "200": { - "description": "HTML content", - "content": { "text/html": { "schema": { "type": "string" } } } - } - }, - "security": [{ "ApiKey": [] }] - } - } - }, - "components": { - "securitySchemes": { - "ApiKey": { - "type": "apiKey", - "in": "header", - "name": "X-Auth-Key", - "description": "A key that is ignored." - } - }, - "schemas": { - "Account": { - "type": "object", - "required": ["id", "role", "username"], - "properties": { - "email": { - "description": "email address", - "type": ["string", "null"] - }, - "id": { - "description": "internal uuid for the user", - "type": "string", - "format": "uuid" - }, - "phoneNumber": { - "description": "phone number", - "anyOf": [ - { "$ref": "#/components/schemas/PhoneNumber" }, - { "type": "null" } - ] - }, - "phoneNumber2": { - "description": "phone number", - "oneOf": [ - { "$ref": "#/components/schemas/PhoneNumber" }, - { "$ref": "#/components/schemas/PhoneNumber2" }, - { "type": "null" } - ] - }, - "phoneNumber3": { - "description": "phone number", - "oneOf": [ - { "$ref": "#/components/schemas/PhoneNumber" }, - { "type": "null" } - ] - }, - "role": { - "description": "The code (string) for referrals", - "$ref": "#/components/schemas/Role" - }, - "username": { - "description": "username as A-Za-z0-9", - "type": "string" - } - } - }, - "AppError": { - "description": "A default error response for most API errors.", - "type": "object", - "required": ["error", "error_id"], - "properties": { - "error": { "description": "An error message.", "type": "string" }, - "error_details": { - "description": "Optional Additional error details." - }, - "error_id": { - "description": "A unique error ID.", - "type": "string", - "format": "uuid" - } - } - }, - "ErrorPayload": { - "type": "object", - "required": ["message"], - "properties": { "message": { "type": "string" } } - }, - "NewAccount": { - "type": "object", - "required": ["role", "username"], - "properties": { - "email": { - "description": "email address", - "type": ["string", "null"] - }, - "phoneNumber": { - "description": "phone number", - "anyOf": [ - { "$ref": "#/components/schemas/PhoneNumber" }, - { "type": "null" } - ] - }, - "role": { - "description": "The code (string) for referrals", - "$ref": "#/components/schemas/Role" - }, - "username": { - "description": "username as A-Za-z0-9", - "type": "string" - } - } - }, - "NewTodo": { - "description": "New Todo details.", - "type": "object", - "required": ["description"], - "properties": { - "description": { - "description": "The description for the new Todo.", - "type": "string" - } - } - }, - "PhoneNumber": { - "type": "object", - "required": ["countryCode", "number"], - "properties": { - "countryCode": { - "description": "country code must contain only a set of digits 0-9", - "type": "string" - }, - "number": { - "description": "the number should be a set of digits \"333555222\".", - "type": "string" - } - } - }, - "PhoneNumber2": { - "type": "object", - "required": ["countryCode", "number"], - "properties": { - "countryCode": { - "description": "country code must contain only a set of digits 0-9", - "type": "string" - }, - "number": { - "description": "the number should be a set of digits \"333555222\".", - "type": "string" - } - } - }, - "Role": { "type": "string", "enum": ["user", "admin"] }, - "SelectTodo": { - "type": "object", - "required": ["id"], - "properties": { - "id": { - "description": "The ID of the Todo.", - "type": "string", - "format": "uuid" - } - } - }, - "TodoCreated": { - "description": "New Todo details.", - "type": "object", - "required": ["id"], - "properties": { - "id": { - "description": "The ID of the new Todo.", - "type": "string", - "format": "uuid" - } - } - }, - "TodoItem": { - "description": "A single Todo item.", - "type": "object", - "required": ["complete", "description", "id"], - "properties": { - "complete": { - "description": "Whether the item was completed.", - "type": "boolean" - }, - "description": { - "description": "The description of the item.", - "type": "string" - }, - "id": { "type": "string", "format": "uuid" } - } - }, - "TodoList": { - "type": "object", - "required": ["todo_ids"], - "properties": { - "todo_ids": { - "type": "array", - "items": { "type": "string", "format": "uuid" } - } - } - } - } - }, - "tags": [{ "name": "todo", "description": "Todo Management" }] -} - diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift deleted file mode 100644 index 7e0708b1b..000000000 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Client.swift +++ /dev/null @@ -1,661 +0,0 @@ -// Generated by swift-openapi-generator, do not modify. -@_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date -#else -import struct Foundation.URL -import struct Foundation.Data -import struct Foundation.Date -#endif -import HTTPTypes -/// # Todo API -/// -/// A very simple Todo app based on Aide Todo example in Rust -/// -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: Foundation.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 Todo items. - /// - /// - Remark: HTTP `GET /todo/`. - /// - Remark: Generated from `#/paths//todo//get`. - public func getTodo(_ input: Operations.GetTodo.Input) async throws -> Operations.GetTodo.Output { - try await client.send( - input: input, - forOperation: Operations.GetTodo.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/todo/", - parameters: [] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .get - ) - suppressMutabilityWarning(&request) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - return (request, nil) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 200: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.GetTodo.Output.Ok.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.TodoList.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .ok(.init(body: body)) - default: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.GetTodo.Output.Default.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .`default`( - statusCode: response.status.code, - .init(body: body) - ) - } - } - ) - } - /// Create a new incomplete Todo item. - /// - /// - Remark: HTTP `POST /todo/`. - /// - Remark: Generated from `#/paths//todo//post`. - public func postTodo(_ input: Operations.PostTodo.Input) async throws -> Operations.PostTodo.Output { - try await client.send( - input: input, - forOperation: Operations.PostTodo.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/todo/", - parameters: [] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .post - ) - suppressMutabilityWarning(&request) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - let body: OpenAPIRuntime.HTTPBody? - switch input.body { - case let .json(value): - body = try converter.setRequiredRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (request, body) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 201: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.PostTodo.Output.Created.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.TodoCreated.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .created(.init(body: body)) - case 409: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.PostTodo.Output.Conflict.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .conflict(.init(body: body)) - default: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.PostTodo.Output.Default.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .`default`( - statusCode: response.status.code, - .init(body: body) - ) - } - } - ) - } - /// Get a single Todo item. - /// - /// - Remark: HTTP `GET /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/get`. - public func getTodoId(_ input: Operations.GetTodoId.Input) async throws -> Operations.GetTodoId.Output { - try await client.send( - input: input, - forOperation: Operations.GetTodoId.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/todo/{}", - parameters: [ - input.path.id - ] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .get - ) - suppressMutabilityWarning(&request) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - return (request, nil) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 200: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.GetTodoId.Output.Ok.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.TodoItem.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .ok(.init(body: body)) - case 404: - return .notFound(.init()) - default: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.GetTodoId.Output.Default.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .`default`( - statusCode: response.status.code, - .init(body: body) - ) - } - } - ) - } - /// Delete a Todo item. - /// - /// - Remark: HTTP `DELETE /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/delete`. - public func deleteTodoId(_ input: Operations.DeleteTodoId.Input) async throws -> Operations.DeleteTodoId.Output { - try await client.send( - input: input, - forOperation: Operations.DeleteTodoId.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/todo/{}", - parameters: [ - input.path.id - ] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .delete - ) - suppressMutabilityWarning(&request) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - return (request, nil) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 204: - return .noContent(.init()) - case 404: - return .notFound(.init()) - default: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.DeleteTodoId.Output.Default.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .`default`( - statusCode: response.status.code, - .init(body: body) - ) - } - } - ) - } - /// Complete a Todo. - /// - /// - Remark: HTTP `PUT /todo/{id}/complete`. - /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. - public func putTodoIdComplete(_ input: Operations.PutTodoIdComplete.Input) async throws -> Operations.PutTodoIdComplete.Output { - try await client.send( - input: input, - forOperation: Operations.PutTodoIdComplete.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/todo/{}/complete", - parameters: [ - input.path.id - ] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .put - ) - suppressMutabilityWarning(&request) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - return (request, nil) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 204: - return .noContent(.init()) - default: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.PutTodoIdComplete.Output.Default.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .`default`( - statusCode: response.status.code, - .init(body: body) - ) - } - } - ) - } - /// creates an account - /// - /// register a new account to be used - /// - /// - Remark: HTTP `POST /todo/user/create`. - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. - public func createUser(_ input: Operations.CreateUser.Input) async throws -> Operations.CreateUser.Output { - try await client.send( - input: input, - forOperation: Operations.CreateUser.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/todo/user/create", - parameters: [] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .post - ) - suppressMutabilityWarning(&request) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - let body: OpenAPIRuntime.HTTPBody? - switch input.body { - case let .json(value): - body = try converter.setRequiredRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (request, body) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 201: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.CreateUser.Output.Created.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.Account.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .created(.init(body: body)) - case 400: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.CreateUser.Output.BadRequest.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.ErrorPayload.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .badRequest(.init(body: body)) - case 409: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.CreateUser.Output.Conflict.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.ErrorPayload.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .conflict(.init(body: body)) - case 500: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.CreateUser.Output.InternalServerError.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.ErrorPayload.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .internalServerError(.init(body: body)) - default: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.CreateUser.Output.Default.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .`default`( - statusCode: response.status.code, - .init(body: body) - ) - } - } - ) - } - /// This documentation page. - /// - /// - Remark: HTTP `GET /docs/`. - /// - Remark: Generated from `#/paths//docs//get`. - public func getDocs(_ input: Operations.GetDocs.Input) async throws -> Operations.GetDocs.Output { - try await client.send( - input: input, - forOperation: Operations.GetDocs.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/docs/", - parameters: [] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .get - ) - suppressMutabilityWarning(&request) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - return (request, nil) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 200: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.GetDocs.Output.Ok.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "text/html" - ] - ) - switch chosenContentType { - case "text/html": - body = try converter.getResponseBodyAsBinary( - OpenAPIRuntime.HTTPBody.self, - from: responseBody, - transforming: { value in - .html(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .ok(.init(body: body)) - default: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.GetDocs.Output.Default.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.AppError.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .`default`( - statusCode: response.status.code, - .init(body: body) - ) - } - } - ) - } -} diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift deleted file mode 100644 index e994b9258..000000000 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Server.swift +++ /dev/null @@ -1,683 +0,0 @@ -// Generated by swift-openapi-generator, do not modify. -@_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date -#else -import struct Foundation.URL -import struct Foundation.Data -import struct Foundation.Date -#endif -import HTTPTypes -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: Foundation.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.getTodo( - request: $0, - body: $1, - metadata: $2 - ) - }, - method: .get, - path: server.apiPathComponentsWithServerPrefix("/todo/") - ) - try transport.register( - { - try await server.postTodo( - request: $0, - body: $1, - metadata: $2 - ) - }, - method: .post, - path: server.apiPathComponentsWithServerPrefix("/todo/") - ) - try transport.register( - { - try await server.getTodoId( - request: $0, - body: $1, - metadata: $2 - ) - }, - method: .get, - path: server.apiPathComponentsWithServerPrefix("/todo/{id}") - ) - try transport.register( - { - try await server.deleteTodoId( - request: $0, - body: $1, - metadata: $2 - ) - }, - method: .delete, - path: server.apiPathComponentsWithServerPrefix("/todo/{id}") - ) - try transport.register( - { - try await server.putTodoIdComplete( - request: $0, - body: $1, - metadata: $2 - ) - }, - method: .put, - path: server.apiPathComponentsWithServerPrefix("/todo/{id}/complete") - ) - try transport.register( - { - try await server.createUser( - request: $0, - body: $1, - metadata: $2 - ) - }, - method: .post, - path: server.apiPathComponentsWithServerPrefix("/todo/user/create") - ) - try transport.register( - { - try await server.getDocs( - request: $0, - body: $1, - metadata: $2 - ) - }, - method: .get, - path: server.apiPathComponentsWithServerPrefix("/docs/") - ) - } -} - -fileprivate extension UniversalServer where APIHandler: APIProtocol { - /// List all Todo items. - /// - /// - Remark: HTTP `GET /todo/`. - /// - Remark: Generated from `#/paths//todo//get`. - func getTodo( - request: HTTPTypes.HTTPRequest, - body: OpenAPIRuntime.HTTPBody?, - metadata: OpenAPIRuntime.ServerRequestMetadata - ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { - try await handle( - request: request, - requestBody: body, - metadata: metadata, - forOperation: Operations.GetTodo.id, - using: { - APIHandler.getTodo($0) - }, - deserializer: { request, requestBody, metadata in - let headers: Operations.GetTodo.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) - return Operations.GetTodo.Input(headers: headers) - }, - serializer: { output, request in - switch output { - case let .ok(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 200) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - } - } - ) - } - /// Create a new incomplete Todo item. - /// - /// - Remark: HTTP `POST /todo/`. - /// - Remark: Generated from `#/paths//todo//post`. - func postTodo( - request: HTTPTypes.HTTPRequest, - body: OpenAPIRuntime.HTTPBody?, - metadata: OpenAPIRuntime.ServerRequestMetadata - ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { - try await handle( - request: request, - requestBody: body, - metadata: metadata, - forOperation: Operations.PostTodo.id, - using: { - APIHandler.postTodo($0) - }, - deserializer: { request, requestBody, metadata in - let headers: Operations.PostTodo.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) - let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) - let body: Operations.PostTodo.Input.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getRequiredRequestBodyAsJSON( - Components.Schemas.NewTodo.self, - from: requestBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return Operations.PostTodo.Input( - headers: headers, - body: body - ) - }, - serializer: { output, request in - switch output { - case let .created(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 201) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .conflict(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 409) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - } - } - ) - } - /// Get a single Todo item. - /// - /// - Remark: HTTP `GET /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/get`. - func getTodoId( - request: HTTPTypes.HTTPRequest, - body: OpenAPIRuntime.HTTPBody?, - metadata: OpenAPIRuntime.ServerRequestMetadata - ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { - try await handle( - request: request, - requestBody: body, - metadata: metadata, - forOperation: Operations.GetTodoId.id, - using: { - APIHandler.getTodoId($0) - }, - deserializer: { request, requestBody, metadata in - let path: Operations.GetTodoId.Input.Path = .init(id: try converter.getPathParameterAsURI( - in: metadata.pathParameters, - name: "id", - as: Swift.String.self - )) - let headers: Operations.GetTodoId.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) - return Operations.GetTodoId.Input( - path: path, - headers: headers - ) - }, - serializer: { output, request in - switch output { - case let .ok(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 200) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .notFound(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 404) - suppressMutabilityWarning(&response) - return (response, nil) - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - } - } - ) - } - /// Delete a Todo item. - /// - /// - Remark: HTTP `DELETE /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/delete`. - func deleteTodoId( - request: HTTPTypes.HTTPRequest, - body: OpenAPIRuntime.HTTPBody?, - metadata: OpenAPIRuntime.ServerRequestMetadata - ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { - try await handle( - request: request, - requestBody: body, - metadata: metadata, - forOperation: Operations.DeleteTodoId.id, - using: { - APIHandler.deleteTodoId($0) - }, - deserializer: { request, requestBody, metadata in - let path: Operations.DeleteTodoId.Input.Path = .init(id: try converter.getPathParameterAsURI( - in: metadata.pathParameters, - name: "id", - as: Swift.String.self - )) - let headers: Operations.DeleteTodoId.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) - return Operations.DeleteTodoId.Input( - path: path, - headers: headers - ) - }, - serializer: { output, request in - switch output { - case let .noContent(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 204) - suppressMutabilityWarning(&response) - return (response, nil) - case let .notFound(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 404) - suppressMutabilityWarning(&response) - return (response, nil) - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - } - } - ) - } - /// Complete a Todo. - /// - /// - Remark: HTTP `PUT /todo/{id}/complete`. - /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. - func putTodoIdComplete( - request: HTTPTypes.HTTPRequest, - body: OpenAPIRuntime.HTTPBody?, - metadata: OpenAPIRuntime.ServerRequestMetadata - ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { - try await handle( - request: request, - requestBody: body, - metadata: metadata, - forOperation: Operations.PutTodoIdComplete.id, - using: { - APIHandler.putTodoIdComplete($0) - }, - deserializer: { request, requestBody, metadata in - let path: Operations.PutTodoIdComplete.Input.Path = .init(id: try converter.getPathParameterAsURI( - in: metadata.pathParameters, - name: "id", - as: Swift.String.self - )) - let headers: Operations.PutTodoIdComplete.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) - return Operations.PutTodoIdComplete.Input( - path: path, - headers: headers - ) - }, - serializer: { output, request in - switch output { - case let .noContent(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 204) - suppressMutabilityWarning(&response) - return (response, nil) - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - } - } - ) - } - /// creates an account - /// - /// register a new account to be used - /// - /// - Remark: HTTP `POST /todo/user/create`. - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. - func createUser( - request: HTTPTypes.HTTPRequest, - body: OpenAPIRuntime.HTTPBody?, - metadata: OpenAPIRuntime.ServerRequestMetadata - ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { - try await handle( - request: request, - requestBody: body, - metadata: metadata, - forOperation: Operations.CreateUser.id, - using: { - APIHandler.createUser($0) - }, - deserializer: { request, requestBody, metadata in - let headers: Operations.CreateUser.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) - let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) - let body: Operations.CreateUser.Input.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getRequiredRequestBodyAsJSON( - Components.Schemas.NewAccount.self, - from: requestBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return Operations.CreateUser.Input( - headers: headers, - body: body - ) - }, - serializer: { output, request in - switch output { - case let .created(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 201) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .badRequest(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 400) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .conflict(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 409) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .internalServerError(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 500) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - } - } - ) - } - /// This documentation page. - /// - /// - Remark: HTTP `GET /docs/`. - /// - Remark: Generated from `#/paths//docs//get`. - func getDocs( - request: HTTPTypes.HTTPRequest, - body: OpenAPIRuntime.HTTPBody?, - metadata: OpenAPIRuntime.ServerRequestMetadata - ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { - try await handle( - request: request, - requestBody: body, - metadata: metadata, - forOperation: Operations.GetDocs.id, - using: { - APIHandler.getDocs($0) - }, - deserializer: { request, requestBody, metadata in - let headers: Operations.GetDocs.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) - return Operations.GetDocs.Input(headers: headers) - }, - serializer: { output, request in - switch output { - case let .ok(value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: 200) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .html(value): - try converter.validateAcceptIfPresent( - "text/html", - in: request.headerFields - ) - body = try converter.setResponseBodyAsBinary( - value, - headerFields: &response.headerFields, - contentType: "text/html" - ) - } - return (response, body) - case let .`default`(statusCode, value): - suppressUnusedWarning(value) - var response = HTTPTypes.HTTPResponse(soar_statusCode: statusCode) - suppressMutabilityWarning(&response) - let body: OpenAPIRuntime.HTTPBody - switch value.body { - case let .json(value): - try converter.validateAcceptIfPresent( - "application/json", - in: request.headerFields - ) - body = try converter.setResponseBodyAsJSON( - value, - headerFields: &response.headerFields, - contentType: "application/json; charset=utf-8" - ) - } - return (response, body) - } - } - ) - } -} diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift deleted file mode 100644 index 742efdadb..000000000 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Todolist/Types.swift +++ /dev/null @@ -1,1946 +0,0 @@ -// Generated by swift-openapi-generator, do not modify. -@_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date -#else -import struct Foundation.URL -import struct Foundation.Data -import struct Foundation.Date -#endif -/// A type that performs HTTP operations defined by the OpenAPI document. -public protocol APIProtocol: Sendable { - /// List all Todo items. - /// - /// - Remark: HTTP `GET /todo/`. - /// - Remark: Generated from `#/paths//todo//get`. - func getTodo(_ input: Operations.GetTodo.Input) async throws -> Operations.GetTodo.Output - /// Create a new incomplete Todo item. - /// - /// - Remark: HTTP `POST /todo/`. - /// - Remark: Generated from `#/paths//todo//post`. - func postTodo(_ input: Operations.PostTodo.Input) async throws -> Operations.PostTodo.Output - /// Get a single Todo item. - /// - /// - Remark: HTTP `GET /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/get`. - func getTodoId(_ input: Operations.GetTodoId.Input) async throws -> Operations.GetTodoId.Output - /// Delete a Todo item. - /// - /// - Remark: HTTP `DELETE /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/delete`. - func deleteTodoId(_ input: Operations.DeleteTodoId.Input) async throws -> Operations.DeleteTodoId.Output - /// Complete a Todo. - /// - /// - Remark: HTTP `PUT /todo/{id}/complete`. - /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. - func putTodoIdComplete(_ input: Operations.PutTodoIdComplete.Input) async throws -> Operations.PutTodoIdComplete.Output - /// creates an account - /// - /// register a new account to be used - /// - /// - Remark: HTTP `POST /todo/user/create`. - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. - func createUser(_ input: Operations.CreateUser.Input) async throws -> Operations.CreateUser.Output - /// This documentation page. - /// - /// - Remark: HTTP `GET /docs/`. - /// - Remark: Generated from `#/paths//docs//get`. - func getDocs(_ input: Operations.GetDocs.Input) async throws -> Operations.GetDocs.Output -} - -/// Convenience overloads for operation inputs. -extension APIProtocol { - /// List all Todo items. - /// - /// - Remark: HTTP `GET /todo/`. - /// - Remark: Generated from `#/paths//todo//get`. - public func getTodo(headers: Operations.GetTodo.Input.Headers = .init()) async throws -> Operations.GetTodo.Output { - try await getTodo(Operations.GetTodo.Input(headers: headers)) - } - /// Create a new incomplete Todo item. - /// - /// - Remark: HTTP `POST /todo/`. - /// - Remark: Generated from `#/paths//todo//post`. - public func postTodo( - headers: Operations.PostTodo.Input.Headers = .init(), - body: Operations.PostTodo.Input.Body - ) async throws -> Operations.PostTodo.Output { - try await postTodo(Operations.PostTodo.Input( - headers: headers, - body: body - )) - } - /// Get a single Todo item. - /// - /// - Remark: HTTP `GET /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/get`. - public func getTodoId( - path: Operations.GetTodoId.Input.Path, - headers: Operations.GetTodoId.Input.Headers = .init() - ) async throws -> Operations.GetTodoId.Output { - try await getTodoId(Operations.GetTodoId.Input( - path: path, - headers: headers - )) - } - /// Delete a Todo item. - /// - /// - Remark: HTTP `DELETE /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/delete`. - public func deleteTodoId( - path: Operations.DeleteTodoId.Input.Path, - headers: Operations.DeleteTodoId.Input.Headers = .init() - ) async throws -> Operations.DeleteTodoId.Output { - try await deleteTodoId(Operations.DeleteTodoId.Input( - path: path, - headers: headers - )) - } - /// Complete a Todo. - /// - /// - Remark: HTTP `PUT /todo/{id}/complete`. - /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. - public func putTodoIdComplete( - path: Operations.PutTodoIdComplete.Input.Path, - headers: Operations.PutTodoIdComplete.Input.Headers = .init() - ) async throws -> Operations.PutTodoIdComplete.Output { - try await putTodoIdComplete(Operations.PutTodoIdComplete.Input( - path: path, - headers: headers - )) - } - /// creates an account - /// - /// register a new account to be used - /// - /// - Remark: HTTP `POST /todo/user/create`. - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. - public func createUser( - headers: Operations.CreateUser.Input.Headers = .init(), - body: Operations.CreateUser.Input.Body - ) async throws -> Operations.CreateUser.Output { - try await createUser(Operations.CreateUser.Input( - headers: headers, - body: body - )) - } - /// This documentation page. - /// - /// - Remark: HTTP `GET /docs/`. - /// - Remark: Generated from `#/paths//docs//get`. - public func getDocs(headers: Operations.GetDocs.Input.Headers = .init()) async throws -> Operations.GetDocs.Output { - try await getDocs(Operations.GetDocs.Input(headers: headers)) - } -} - -/// Server URLs defined in the OpenAPI document. -public enum Servers {} - -/// 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 { - /// - Remark: Generated from `#/components/schemas/Account`. - public struct Account: Codable, Hashable, Sendable { - /// email address - /// - /// - Remark: Generated from `#/components/schemas/Account/email`. - public var email: Swift.String? - /// internal uuid for the user - /// - /// - Remark: Generated from `#/components/schemas/Account/id`. - public var id: Swift.String - /// - Remark: Generated from `#/components/schemas/Account/phoneNumber`. - public var phoneNumber: Components.Schemas.PhoneNumber? - /// phone number - /// - /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2`. - @frozen public enum PhoneNumber2Payload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2/case1`. - case PhoneNumber(Components.Schemas.PhoneNumber) - /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2/case2`. - case PhoneNumber2(Components.Schemas.PhoneNumber2) - public init(from decoder: any Decoder) throws { - var errors: [any Error] = [] - do { - self = .PhoneNumber(try .init(from: decoder)) - return - } catch { - errors.append(error) - } - do { - self = .PhoneNumber2(try .init(from: decoder)) - return - } catch { - errors.append(error) - } - throw Swift.DecodingError.failedToDecodeOneOfSchema( - type: Self.self, - codingPath: decoder.codingPath, - errors: errors - ) - } - public func encode(to encoder: any Encoder) throws { - switch self { - case let .PhoneNumber(value): - try value.encode(to: encoder) - case let .PhoneNumber2(value): - try value.encode(to: encoder) - } - } - } - /// phone number - /// - /// - Remark: Generated from `#/components/schemas/Account/phoneNumber2`. - public var phoneNumber2: Components.Schemas.Account.PhoneNumber2Payload? - /// - Remark: Generated from `#/components/schemas/Account/phoneNumber3`. - public var phoneNumber3: Components.Schemas.PhoneNumber? - /// The code (string) for referrals - /// - /// - Remark: Generated from `#/components/schemas/Account/role`. - public var role: Components.Schemas.Role - /// username as A-Za-z0-9 - /// - /// - Remark: Generated from `#/components/schemas/Account/username`. - public var username: Swift.String - /// Creates a new `Account`. - /// - /// - Parameters: - /// - email: email address - /// - id: internal uuid for the user - /// - phoneNumber: - /// - phoneNumber2: phone number - /// - phoneNumber3: - /// - role: The code (string) for referrals - /// - username: username as A-Za-z0-9 - public init( - email: Swift.String? = nil, - id: Swift.String, - phoneNumber: Components.Schemas.PhoneNumber? = nil, - phoneNumber2: Components.Schemas.Account.PhoneNumber2Payload? = nil, - phoneNumber3: Components.Schemas.PhoneNumber? = nil, - role: Components.Schemas.Role, - username: Swift.String - ) { - self.email = email - self.id = id - self.phoneNumber = phoneNumber - self.phoneNumber2 = phoneNumber2 - self.phoneNumber3 = phoneNumber3 - self.role = role - self.username = username - } - public enum CodingKeys: String, CodingKey { - case email - case id - case phoneNumber - case phoneNumber2 - case phoneNumber3 - case role - case username - } - } - /// A default error response for most API errors. - /// - /// - Remark: Generated from `#/components/schemas/AppError`. - public struct AppError: Codable, Hashable, Sendable { - /// An error message. - /// - /// - Remark: Generated from `#/components/schemas/AppError/error`. - public var error: Swift.String - /// Optional Additional error details. - /// - /// - Remark: Generated from `#/components/schemas/AppError/error_details`. - public var errorDetails: OpenAPIRuntime.OpenAPIValueContainer? - /// A unique error ID. - /// - /// - Remark: Generated from `#/components/schemas/AppError/error_id`. - public var errorId: Swift.String - /// Creates a new `AppError`. - /// - /// - Parameters: - /// - error: An error message. - /// - errorDetails: Optional Additional error details. - /// - errorId: A unique error ID. - public init( - error: Swift.String, - errorDetails: OpenAPIRuntime.OpenAPIValueContainer? = nil, - errorId: Swift.String - ) { - self.error = error - self.errorDetails = errorDetails - self.errorId = errorId - } - public enum CodingKeys: String, CodingKey { - case error - case errorDetails = "error_details" - case errorId = "error_id" - } - } - /// - Remark: Generated from `#/components/schemas/ErrorPayload`. - public struct ErrorPayload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/ErrorPayload/message`. - public var message: Swift.String - /// Creates a new `ErrorPayload`. - /// - /// - Parameters: - /// - message: - public init(message: Swift.String) { - self.message = message - } - public enum CodingKeys: String, CodingKey { - case message - } - } - /// - Remark: Generated from `#/components/schemas/NewAccount`. - public struct NewAccount: Codable, Hashable, Sendable { - /// email address - /// - /// - Remark: Generated from `#/components/schemas/NewAccount/email`. - public var email: Swift.String? - /// - Remark: Generated from `#/components/schemas/NewAccount/phoneNumber`. - public var phoneNumber: Components.Schemas.PhoneNumber? - /// The code (string) for referrals - /// - /// - Remark: Generated from `#/components/schemas/NewAccount/role`. - public var role: Components.Schemas.Role - /// username as A-Za-z0-9 - /// - /// - Remark: Generated from `#/components/schemas/NewAccount/username`. - public var username: Swift.String - /// Creates a new `NewAccount`. - /// - /// - Parameters: - /// - email: email address - /// - phoneNumber: - /// - role: The code (string) for referrals - /// - username: username as A-Za-z0-9 - public init( - email: Swift.String? = nil, - phoneNumber: Components.Schemas.PhoneNumber? = nil, - role: Components.Schemas.Role, - username: Swift.String - ) { - self.email = email - self.phoneNumber = phoneNumber - self.role = role - self.username = username - } - public enum CodingKeys: String, CodingKey { - case email - case phoneNumber - case role - case username - } - } - /// New Todo details. - /// - /// - Remark: Generated from `#/components/schemas/NewTodo`. - public struct NewTodo: Codable, Hashable, Sendable { - /// The description for the new Todo. - /// - /// - Remark: Generated from `#/components/schemas/NewTodo/description`. - public var description: Swift.String - /// Creates a new `NewTodo`. - /// - /// - Parameters: - /// - description: The description for the new Todo. - public init(description: Swift.String) { - self.description = description - } - public enum CodingKeys: String, CodingKey { - case description - } - } - /// - Remark: Generated from `#/components/schemas/PhoneNumber`. - public struct PhoneNumber: Codable, Hashable, Sendable { - /// country code must contain only a set of digits 0-9 - /// - /// - Remark: Generated from `#/components/schemas/PhoneNumber/countryCode`. - public var countryCode: Swift.String - /// the number should be a set of digits "333555222". - /// - /// - Remark: Generated from `#/components/schemas/PhoneNumber/number`. - public var number: Swift.String - /// Creates a new `PhoneNumber`. - /// - /// - Parameters: - /// - countryCode: country code must contain only a set of digits 0-9 - /// - number: the number should be a set of digits "333555222". - public init( - countryCode: Swift.String, - number: Swift.String - ) { - self.countryCode = countryCode - self.number = number - } - public enum CodingKeys: String, CodingKey { - case countryCode - case number - } - } - /// - Remark: Generated from `#/components/schemas/PhoneNumber2`. - public struct PhoneNumber2: Codable, Hashable, Sendable { - /// country code must contain only a set of digits 0-9 - /// - /// - Remark: Generated from `#/components/schemas/PhoneNumber2/countryCode`. - public var countryCode: Swift.String - /// the number should be a set of digits "333555222". - /// - /// - Remark: Generated from `#/components/schemas/PhoneNumber2/number`. - public var number: Swift.String - /// Creates a new `PhoneNumber2`. - /// - /// - Parameters: - /// - countryCode: country code must contain only a set of digits 0-9 - /// - number: the number should be a set of digits "333555222". - public init( - countryCode: Swift.String, - number: Swift.String - ) { - self.countryCode = countryCode - self.number = number - } - public enum CodingKeys: String, CodingKey { - case countryCode - case number - } - } - /// - Remark: Generated from `#/components/schemas/Role`. - @frozen public enum Role: String, Codable, Hashable, Sendable, CaseIterable { - case user = "user" - case admin = "admin" - } - /// - Remark: Generated from `#/components/schemas/SelectTodo`. - public struct SelectTodo: Codable, Hashable, Sendable { - /// The ID of the Todo. - /// - /// - Remark: Generated from `#/components/schemas/SelectTodo/id`. - public var id: Swift.String - /// Creates a new `SelectTodo`. - /// - /// - Parameters: - /// - id: The ID of the Todo. - public init(id: Swift.String) { - self.id = id - } - public enum CodingKeys: String, CodingKey { - case id - } - } - /// New Todo details. - /// - /// - Remark: Generated from `#/components/schemas/TodoCreated`. - public struct TodoCreated: Codable, Hashable, Sendable { - /// The ID of the new Todo. - /// - /// - Remark: Generated from `#/components/schemas/TodoCreated/id`. - public var id: Swift.String - /// Creates a new `TodoCreated`. - /// - /// - Parameters: - /// - id: The ID of the new Todo. - public init(id: Swift.String) { - self.id = id - } - public enum CodingKeys: String, CodingKey { - case id - } - } - /// A single Todo item. - /// - /// - Remark: Generated from `#/components/schemas/TodoItem`. - public struct TodoItem: Codable, Hashable, Sendable { - /// Whether the item was completed. - /// - /// - Remark: Generated from `#/components/schemas/TodoItem/complete`. - public var complete: Swift.Bool - /// The description of the item. - /// - /// - Remark: Generated from `#/components/schemas/TodoItem/description`. - public var description: Swift.String - /// - Remark: Generated from `#/components/schemas/TodoItem/id`. - public var id: Swift.String - /// Creates a new `TodoItem`. - /// - /// - Parameters: - /// - complete: Whether the item was completed. - /// - description: The description of the item. - /// - id: - public init( - complete: Swift.Bool, - description: Swift.String, - id: Swift.String - ) { - self.complete = complete - self.description = description - self.id = id - } - public enum CodingKeys: String, CodingKey { - case complete - case description - case id - } - } - /// - Remark: Generated from `#/components/schemas/TodoList`. - public struct TodoList: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/TodoList/todo_ids`. - public var todoIds: [Swift.String] - /// Creates a new `TodoList`. - /// - /// - Parameters: - /// - todoIds: - public init(todoIds: [Swift.String]) { - self.todoIds = todoIds - } - public enum CodingKeys: String, CodingKey { - case todoIds = "todo_ids" - } - } - } - /// Types generated from the `#/components/parameters` section of the OpenAPI document. - public enum Parameters {} - /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. - public enum RequestBodies {} - /// Types generated from the `#/components/responses` section of the OpenAPI document. - public enum Responses {} - /// Types generated from the `#/components/headers` section of the OpenAPI document. - public enum Headers {} -} - -/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. -public enum Operations { - /// List all Todo items. - /// - /// - Remark: HTTP `GET /todo/`. - /// - Remark: Generated from `#/paths//todo//get`. - public enum GetTodo { - public static let id: Swift.String = "get/todo/" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/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.GetTodo.Input.Headers - /// Creates a new `Input`. - /// - /// - Parameters: - /// - headers: - public init(headers: Operations.GetTodo.Input.Headers = .init()) { - self.headers = headers - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Ok: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/GET/responses/200/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/GET/responses/200/content/application\/json`. - case json(Components.Schemas.TodoList) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.TodoList { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.GetTodo.Output.Ok.Body - /// Creates a new `Ok`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.GetTodo.Output.Ok.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo//get/responses/200`. - /// - /// HTTP response code: `200 ok`. - case ok(Operations.GetTodo.Output.Ok) - /// The associated value of the enum case if `self` is `.ok`. - /// - /// - Throws: An error if `self` is not `.ok`. - /// - SeeAlso: `.ok`. - public var ok: Operations.GetTodo.Output.Ok { - get throws { - switch self { - case let .ok(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "ok", - response: self - ) - } - } - } - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/GET/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/GET/responses/default/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.GetTodo.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.GetTodo.Output.Default.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo//get/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Swift.Int, Operations.GetTodo.Output.Default) - /// The associated value of the enum case if `self` is `.`default``. - /// - /// - Throws: An error if `self` is not `.`default``. - /// - SeeAlso: `.`default``. - public var `default`: Operations.GetTodo.Output.Default { - get throws { - switch self { - case let .`default`(_, response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "default", - response: self - ) - } - } - } - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(Swift.String) - public init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - public var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .json: - return "application/json" - } - } - public static var allCases: [Self] { - [ - .json - ] - } - } - } - /// Create a new incomplete Todo item. - /// - /// - Remark: HTTP `POST /todo/`. - /// - Remark: Generated from `#/paths//todo//post`. - public enum PostTodo { - public static let id: Swift.String = "post/todo/" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/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.PostTodo.Input.Headers - /// - Remark: Generated from `#/paths/todo/POST/requestBody`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/requestBody/content/application\/json`. - case json(Components.Schemas.NewTodo) - } - public var body: Operations.PostTodo.Input.Body - /// Creates a new `Input`. - /// - /// - Parameters: - /// - headers: - /// - body: - public init( - headers: Operations.PostTodo.Input.Headers = .init(), - body: Operations.PostTodo.Input.Body - ) { - self.headers = headers - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Created: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/responses/201/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/responses/201/content/application\/json`. - case json(Components.Schemas.TodoCreated) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.TodoCreated { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.PostTodo.Output.Created.Body - /// Creates a new `Created`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.PostTodo.Output.Created.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo//post/responses/201`. - /// - /// HTTP response code: `201 created`. - case created(Operations.PostTodo.Output.Created) - /// The associated value of the enum case if `self` is `.created`. - /// - /// - Throws: An error if `self` is not `.created`. - /// - SeeAlso: `.created`. - public var created: Operations.PostTodo.Output.Created { - get throws { - switch self { - case let .created(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "created", - response: self - ) - } - } - } - public struct Conflict: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/responses/409/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/responses/409/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.PostTodo.Output.Conflict.Body - /// Creates a new `Conflict`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.PostTodo.Output.Conflict.Body) { - self.body = body - } - } - /// conflict with username, email, phone, or similar unique required data - /// - /// - Remark: Generated from `#/paths//todo//post/responses/409`. - /// - /// HTTP response code: `409 conflict`. - case conflict(Operations.PostTodo.Output.Conflict) - /// The associated value of the enum case if `self` is `.conflict`. - /// - /// - Throws: An error if `self` is not `.conflict`. - /// - SeeAlso: `.conflict`. - public var conflict: Operations.PostTodo.Output.Conflict { - get throws { - switch self { - case let .conflict(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "conflict", - response: self - ) - } - } - } - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/POST/responses/default/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.PostTodo.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.PostTodo.Output.Default.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo//post/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Swift.Int, Operations.PostTodo.Output.Default) - /// The associated value of the enum case if `self` is `.`default``. - /// - /// - Throws: An error if `self` is not `.`default``. - /// - SeeAlso: `.`default``. - public var `default`: Operations.PostTodo.Output.Default { - get throws { - switch self { - case let .`default`(_, response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "default", - response: self - ) - } - } - } - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(Swift.String) - public init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - public var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .json: - return "application/json" - } - } - public static var allCases: [Self] { - [ - .json - ] - } - } - } - /// Get a single Todo item. - /// - /// - Remark: HTTP `GET /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/get`. - public enum GetTodoId { - public static let id: Swift.String = "get/todo/{id}" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/GET/path`. - public struct Path: Sendable, Hashable { - /// The ID of the Todo. - /// - /// - Remark: Generated from `#/paths/todo/{id}/GET/path/id`. - public var id: Swift.String - /// Creates a new `Path`. - /// - /// - Parameters: - /// - id: The ID of the Todo. - public init(id: Swift.String) { - self.id = id - } - } - public var path: Operations.GetTodoId.Input.Path - /// - Remark: Generated from `#/paths/todo/{id}/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.GetTodoId.Input.Headers - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - headers: - public init( - path: Operations.GetTodoId.Input.Path, - headers: Operations.GetTodoId.Input.Headers = .init() - ) { - self.path = path - self.headers = headers - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Ok: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/200/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/200/content/application\/json`. - case json(Components.Schemas.TodoItem) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.TodoItem { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.GetTodoId.Output.Ok.Body - /// Creates a new `Ok`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.GetTodoId.Output.Ok.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo/{id}/get/responses/200`. - /// - /// HTTP response code: `200 ok`. - case ok(Operations.GetTodoId.Output.Ok) - /// The associated value of the enum case if `self` is `.ok`. - /// - /// - Throws: An error if `self` is not `.ok`. - /// - SeeAlso: `.ok`. - public var ok: Operations.GetTodoId.Output.Ok { - get throws { - switch self { - case let .ok(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "ok", - response: self - ) - } - } - } - public struct NotFound: Sendable, Hashable { - /// Creates a new `NotFound`. - public init() {} - } - /// todo was not found - /// - /// - Remark: Generated from `#/paths//todo/{id}/get/responses/404`. - /// - /// HTTP response code: `404 notFound`. - case notFound(Operations.GetTodoId.Output.NotFound) - /// todo was not found - /// - /// - Remark: Generated from `#/paths//todo/{id}/get/responses/404`. - /// - /// HTTP response code: `404 notFound`. - public static var notFound: Self { - .notFound(.init()) - } - /// The associated value of the enum case if `self` is `.notFound`. - /// - /// - Throws: An error if `self` is not `.notFound`. - /// - SeeAlso: `.notFound`. - public var notFound: Operations.GetTodoId.Output.NotFound { - get throws { - switch self { - case let .notFound(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "notFound", - response: self - ) - } - } - } - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/GET/responses/default/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.GetTodoId.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.GetTodoId.Output.Default.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo/{id}/get/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Swift.Int, Operations.GetTodoId.Output.Default) - /// The associated value of the enum case if `self` is `.`default``. - /// - /// - Throws: An error if `self` is not `.`default``. - /// - SeeAlso: `.`default``. - public var `default`: Operations.GetTodoId.Output.Default { - get throws { - switch self { - case let .`default`(_, response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "default", - response: self - ) - } - } - } - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(Swift.String) - public init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - public var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .json: - return "application/json" - } - } - public static var allCases: [Self] { - [ - .json - ] - } - } - } - /// Delete a Todo item. - /// - /// - Remark: HTTP `DELETE /todo/{id}`. - /// - Remark: Generated from `#/paths//todo/{id}/delete`. - public enum DeleteTodoId { - public static let id: Swift.String = "delete/todo/{id}" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/DELETE/path`. - public struct Path: Sendable, Hashable { - /// The ID of the Todo. - /// - /// - Remark: Generated from `#/paths/todo/{id}/DELETE/path/id`. - public var id: Swift.String - /// Creates a new `Path`. - /// - /// - Parameters: - /// - id: The ID of the Todo. - public init(id: Swift.String) { - self.id = id - } - } - public var path: Operations.DeleteTodoId.Input.Path - /// - Remark: Generated from `#/paths/todo/{id}/DELETE/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.DeleteTodoId.Input.Headers - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - headers: - public init( - path: Operations.DeleteTodoId.Input.Path, - headers: Operations.DeleteTodoId.Input.Headers = .init() - ) { - self.path = path - self.headers = headers - } - } - @frozen public enum Output: Sendable, Hashable { - public struct NoContent: Sendable, Hashable { - /// Creates a new `NoContent`. - public init() {} - } - /// The Todo has been deleted. - /// - /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/204`. - /// - /// HTTP response code: `204 noContent`. - case noContent(Operations.DeleteTodoId.Output.NoContent) - /// The Todo has been deleted. - /// - /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/204`. - /// - /// HTTP response code: `204 noContent`. - public static var noContent: Self { - .noContent(.init()) - } - /// The associated value of the enum case if `self` is `.noContent`. - /// - /// - Throws: An error if `self` is not `.noContent`. - /// - SeeAlso: `.noContent`. - public var noContent: Operations.DeleteTodoId.Output.NoContent { - get throws { - switch self { - case let .noContent(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "noContent", - response: self - ) - } - } - } - public struct NotFound: Sendable, Hashable { - /// Creates a new `NotFound`. - public init() {} - } - /// The todo was not found - /// - /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/404`. - /// - /// HTTP response code: `404 notFound`. - case notFound(Operations.DeleteTodoId.Output.NotFound) - /// The todo was not found - /// - /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/404`. - /// - /// HTTP response code: `404 notFound`. - public static var notFound: Self { - .notFound(.init()) - } - /// The associated value of the enum case if `self` is `.notFound`. - /// - /// - Throws: An error if `self` is not `.notFound`. - /// - SeeAlso: `.notFound`. - public var notFound: Operations.DeleteTodoId.Output.NotFound { - get throws { - switch self { - case let .notFound(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "notFound", - response: self - ) - } - } - } - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/DELETE/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/DELETE/responses/default/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.DeleteTodoId.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.DeleteTodoId.Output.Default.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo/{id}/delete/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Swift.Int, Operations.DeleteTodoId.Output.Default) - /// The associated value of the enum case if `self` is `.`default``. - /// - /// - Throws: An error if `self` is not `.`default``. - /// - SeeAlso: `.`default``. - public var `default`: Operations.DeleteTodoId.Output.Default { - get throws { - switch self { - case let .`default`(_, response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "default", - response: self - ) - } - } - } - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(Swift.String) - public init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - public var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .json: - return "application/json" - } - } - public static var allCases: [Self] { - [ - .json - ] - } - } - } - /// Complete a Todo. - /// - /// - Remark: HTTP `PUT /todo/{id}/complete`. - /// - Remark: Generated from `#/paths//todo/{id}/complete/put`. - public enum PutTodoIdComplete { - public static let id: Swift.String = "put/todo/{id}/complete" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/path`. - public struct Path: Sendable, Hashable { - /// The ID of the Todo. - /// - /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/path/id`. - public var id: Swift.String - /// Creates a new `Path`. - /// - /// - Parameters: - /// - id: The ID of the Todo. - public init(id: Swift.String) { - self.id = id - } - } - public var path: Operations.PutTodoIdComplete.Input.Path - /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/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.PutTodoIdComplete.Input.Headers - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - headers: - public init( - path: Operations.PutTodoIdComplete.Input.Path, - headers: Operations.PutTodoIdComplete.Input.Headers = .init() - ) { - self.path = path - self.headers = headers - } - } - @frozen public enum Output: Sendable, Hashable { - public struct NoContent: Sendable, Hashable { - /// Creates a new `NoContent`. - public init() {} - } - /// no content - /// - /// - Remark: Generated from `#/paths//todo/{id}/complete/put/responses/204`. - /// - /// HTTP response code: `204 noContent`. - case noContent(Operations.PutTodoIdComplete.Output.NoContent) - /// no content - /// - /// - Remark: Generated from `#/paths//todo/{id}/complete/put/responses/204`. - /// - /// HTTP response code: `204 noContent`. - public static var noContent: Self { - .noContent(.init()) - } - /// The associated value of the enum case if `self` is `.noContent`. - /// - /// - Throws: An error if `self` is not `.noContent`. - /// - SeeAlso: `.noContent`. - public var noContent: Operations.PutTodoIdComplete.Output.NoContent { - get throws { - switch self { - case let .noContent(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "noContent", - response: self - ) - } - } - } - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/{id}/complete/PUT/responses/default/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.PutTodoIdComplete.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.PutTodoIdComplete.Output.Default.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo/{id}/complete/put/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Swift.Int, Operations.PutTodoIdComplete.Output.Default) - /// The associated value of the enum case if `self` is `.`default``. - /// - /// - Throws: An error if `self` is not `.`default``. - /// - SeeAlso: `.`default``. - public var `default`: Operations.PutTodoIdComplete.Output.Default { - get throws { - switch self { - case let .`default`(_, response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "default", - response: self - ) - } - } - } - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(Swift.String) - public init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - public var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .json: - return "application/json" - } - } - public static var allCases: [Self] { - [ - .json - ] - } - } - } - /// creates an account - /// - /// register a new account to be used - /// - /// - Remark: HTTP `POST /todo/user/create`. - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)`. - public enum CreateUser { - public static let id: Swift.String = "create_user" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/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.CreateUser.Input.Headers - /// - Remark: Generated from `#/paths/todo/user/create/POST/requestBody`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/requestBody/content/application\/json`. - case json(Components.Schemas.NewAccount) - } - public var body: Operations.CreateUser.Input.Body - /// Creates a new `Input`. - /// - /// - Parameters: - /// - headers: - /// - body: - public init( - headers: Operations.CreateUser.Input.Headers = .init(), - body: Operations.CreateUser.Input.Body - ) { - self.headers = headers - self.body = body - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Created: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/201/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/201/content/application\/json`. - case json(Components.Schemas.Account) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.Account { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.CreateUser.Output.Created.Body - /// Creates a new `Created`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.CreateUser.Output.Created.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/201`. - /// - /// HTTP response code: `201 created`. - case created(Operations.CreateUser.Output.Created) - /// The associated value of the enum case if `self` is `.created`. - /// - /// - Throws: An error if `self` is not `.created`. - /// - SeeAlso: `.created`. - public var created: Operations.CreateUser.Output.Created { - get throws { - switch self { - case let .created(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "created", - response: self - ) - } - } - } - public struct BadRequest: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/400/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/400/content/application\/json`. - case json(Components.Schemas.ErrorPayload) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.ErrorPayload { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.CreateUser.Output.BadRequest.Body - /// Creates a new `BadRequest`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.CreateUser.Output.BadRequest.Body) { - self.body = body - } - } - /// bad request - /// - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/400`. - /// - /// HTTP response code: `400 badRequest`. - case badRequest(Operations.CreateUser.Output.BadRequest) - /// The associated value of the enum case if `self` is `.badRequest`. - /// - /// - Throws: An error if `self` is not `.badRequest`. - /// - SeeAlso: `.badRequest`. - public var badRequest: Operations.CreateUser.Output.BadRequest { - get throws { - switch self { - case let .badRequest(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "badRequest", - response: self - ) - } - } - } - public struct Conflict: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/409/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/409/content/application\/json`. - case json(Components.Schemas.ErrorPayload) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.ErrorPayload { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.CreateUser.Output.Conflict.Body - /// Creates a new `Conflict`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.CreateUser.Output.Conflict.Body) { - self.body = body - } - } - /// conflict with username, email, phone, or similar unique required data - /// - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/409`. - /// - /// HTTP response code: `409 conflict`. - case conflict(Operations.CreateUser.Output.Conflict) - /// The associated value of the enum case if `self` is `.conflict`. - /// - /// - Throws: An error if `self` is not `.conflict`. - /// - SeeAlso: `.conflict`. - public var conflict: Operations.CreateUser.Output.Conflict { - get throws { - switch self { - case let .conflict(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "conflict", - response: self - ) - } - } - } - public struct InternalServerError: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/500/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/500/content/application\/json`. - case json(Components.Schemas.ErrorPayload) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.ErrorPayload { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.CreateUser.Output.InternalServerError.Body - /// Creates a new `InternalServerError`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.CreateUser.Output.InternalServerError.Body) { - self.body = body - } - } - /// parse error or missing data - /// - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/500`. - /// - /// HTTP response code: `500 internalServerError`. - case internalServerError(Operations.CreateUser.Output.InternalServerError) - /// The associated value of the enum case if `self` is `.internalServerError`. - /// - /// - Throws: An error if `self` is not `.internalServerError`. - /// - SeeAlso: `.internalServerError`. - public var internalServerError: Operations.CreateUser.Output.InternalServerError { - get throws { - switch self { - case let .internalServerError(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "internalServerError", - response: self - ) - } - } - } - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/todo/user/create/POST/responses/default/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.CreateUser.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.CreateUser.Output.Default.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//todo/user/create/post(create_user)/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Swift.Int, Operations.CreateUser.Output.Default) - /// The associated value of the enum case if `self` is `.`default``. - /// - /// - Throws: An error if `self` is not `.`default``. - /// - SeeAlso: `.`default``. - public var `default`: Operations.CreateUser.Output.Default { - get throws { - switch self { - case let .`default`(_, response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "default", - response: self - ) - } - } - } - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case json - case other(Swift.String) - public init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - public var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .json: - return "application/json" - } - } - public static var allCases: [Self] { - [ - .json - ] - } - } - } - /// This documentation page. - /// - /// - Remark: HTTP `GET /docs/`. - /// - Remark: Generated from `#/paths//docs//get`. - public enum GetDocs { - public static let id: Swift.String = "get/docs/" - public struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/docs/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.GetDocs.Input.Headers - /// Creates a new `Input`. - /// - /// - Parameters: - /// - headers: - public init(headers: Operations.GetDocs.Input.Headers = .init()) { - self.headers = headers - } - } - @frozen public enum Output: Sendable, Hashable { - public struct Ok: Sendable, Hashable { - /// - Remark: Generated from `#/paths/docs/GET/responses/200/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/docs/GET/responses/200/content/text\/html`. - case html(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.html`. - /// - /// - Throws: An error if `self` is not `.html`. - /// - SeeAlso: `.html`. - public var html: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .html(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.GetDocs.Output.Ok.Body - /// Creates a new `Ok`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.GetDocs.Output.Ok.Body) { - self.body = body - } - } - /// HTML content - /// - /// - Remark: Generated from `#/paths//docs//get/responses/200`. - /// - /// HTTP response code: `200 ok`. - case ok(Operations.GetDocs.Output.Ok) - /// The associated value of the enum case if `self` is `.ok`. - /// - /// - Throws: An error if `self` is not `.ok`. - /// - SeeAlso: `.ok`. - public var ok: Operations.GetDocs.Output.Ok { - get throws { - switch self { - case let .ok(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "ok", - response: self - ) - } - } - } - public struct Default: Sendable, Hashable { - /// - Remark: Generated from `#/paths/docs/GET/responses/default/content`. - @frozen public enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/docs/GET/responses/default/content/application\/json`. - case json(Components.Schemas.AppError) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - public var json: Components.Schemas.AppError { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - public var body: Operations.GetDocs.Output.Default.Body - /// Creates a new `Default`. - /// - /// - Parameters: - /// - body: Received HTTP response body - public init(body: Operations.GetDocs.Output.Default.Body) { - self.body = body - } - } - /// - /// - /// - Remark: Generated from `#/paths//docs//get/responses/default`. - /// - /// HTTP response code: `default`. - case `default`(statusCode: Swift.Int, Operations.GetDocs.Output.Default) - /// The associated value of the enum case if `self` is `.`default``. - /// - /// - Throws: An error if `self` is not `.`default``. - /// - SeeAlso: `.`default``. - public var `default`: Operations.GetDocs.Output.Default { - get throws { - switch self { - case let .`default`(_, response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "default", - response: self - ) - } - } - } - } - @frozen public enum AcceptableContentType: AcceptableProtocol { - case html - case json - case other(Swift.String) - public init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "text/html": - self = .html - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - public var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .html: - return "text/html" - case .json: - return "application/json" - } - } - public static var allCases: [Self] { - [ - .html, - .json - ] - } - } - } -} diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift index d1e6341c0..bf2aed761 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift @@ -844,6 +844,145 @@ final class SnippetBasedReferenceTests: XCTestCase { """ ) } + + func testComponentsSchemasAnyOfWithNull_singleRef() throws { + try self.assertSchemasTranslation( + """ + schemas: + A: + type: object + properties: + b: + anyOf: + - $ref: "#/components/schemas/B" + - type: "null" + B: + type: object + required: ["c"] + properties: + c: + type: string + """, + """ + public enum Schemas { + public struct A: Codable, Hashable, Sendable { + public var b: Components.Schemas.B? + public init(b: Components.Schemas.B? = nil) { + self.b = b + } + public enum CodingKeys: String, CodingKey { + case b + } + } + public struct B: Codable, Hashable, Sendable { + public var c: Swift.String + public init(c: Swift.String) { + self.c = c + } + public enum CodingKeys: String, CodingKey { + case c + } + } + } + """ + ) + } + + func testComponentsSchemasAnyOfWithNull_multiRef() throws { + try self.assertSchemasTranslation( + """ + schemas: + A: + type: object + properties: + b: + anyOf: + - $ref: "#/components/schemas/B1" + - $ref: "#/components/schemas/B2" + - type: "null" + B1: + type: object + required: ["c"] + properties: + c: + type: string + B2: + type: object + required: ["d"] + properties: + d: + type: string + """, + """ + public enum Schemas { + public struct A: Codable, Hashable, Sendable { + public struct bPayload: Codable, Hashable, Sendable { + public var value1: Components.Schemas.B1? + public var value2: Components.Schemas.B2? + public init( + value1: Components.Schemas.B1? = nil, + value2: Components.Schemas.B2? = nil + ) { + self.value1 = value1 + self.value2 = value2 + } + public init(from decoder: any Decoder) throws { + var errors: [any Error] = [] + do { + self.value1 = try .init(from: decoder) + } catch { + errors.append(error) + } + do { + self.value2 = try .init(from: decoder) + } catch { + errors.append(error) + } + try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( + [ + self.value1, + self.value2 + ], + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + public func encode(to encoder: any Encoder) throws { + try self.value1?.encode(to: encoder) + try self.value2?.encode(to: encoder) + } + } + public var b: Components.Schemas.A.bPayload? + public init(b: Components.Schemas.A.bPayload? = nil) { + self.b = b + } + public enum CodingKeys: String, CodingKey { + case b + } + } + public struct B1: Codable, Hashable, Sendable { + public var c: Swift.String + public init(c: Swift.String) { + self.c = c + } + public enum CodingKeys: String, CodingKey { + case c + } + } + public struct B2: Codable, Hashable, Sendable { + public var d: Swift.String + public init(d: Swift.String) { + self.d = d + } + public enum CodingKeys: String, CodingKey { + case d + } + } + } + """ + ) + } func testComponentsSchemasOneOfWithDiscriminator() throws { try self.assertSchemasTranslation( @@ -1099,6 +1238,140 @@ final class SnippetBasedReferenceTests: XCTestCase { ) } + func testComponentsSchemasOneOfWithNull_singleRef_closed() throws { + try self.assertSchemasTranslation( + """ + schemas: + A: + type: object + properties: + b: + oneOf: + - $ref: "#/components/schemas/B" + - type: "null" + B: + type: object + required: ["c"] + properties: + c: + type: string + """, + """ + public enum Schemas { + public struct A: Codable, Hashable, Sendable { + public var b: Components.Schemas.B? + public init(b: Components.Schemas.B? = nil) { + self.b = b + } + public enum CodingKeys: String, CodingKey { + case b + } + } + public struct B: Codable, Hashable, Sendable { + public var c: Swift.String + public init(c: Swift.String) { + self.c = c + } + public enum CodingKeys: String, CodingKey { + case c + } + } + } + """ + ) + } + + func testComponentsSchemasOneOfWithNull_multiRef_closed() throws { + try self.assertSchemasTranslation( + """ + schemas: + A: + type: object + properties: + b: + oneOf: + - $ref: "#/components/schemas/B1" + - $ref: "#/components/schemas/B2" + - type: "null" + B1: + type: object + required: ["c"] + properties: + c: + type: string + B2: + type: object + required: ["d"] + properties: + d: + type: string + """, + """ + public enum Schemas { + public struct A: Codable, Hashable, Sendable { + @frozen public enum bPayload: Codable, Hashable, Sendable { + case B1(Components.Schemas.B1) + case B2(Components.Schemas.B2) + public init(from decoder: any Decoder) throws { + var errors: [any Error] = [] + do { + self = .B1(try .init(from: decoder)) + return + } catch { + errors.append(error) + } + do { + self = .B2(try .init(from: decoder)) + return + } catch { + errors.append(error) + } + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + public func encode(to encoder: any Encoder) throws { + switch self { + case let .B1(value): + try value.encode(to: encoder) + case let .B2(value): + try value.encode(to: encoder) + } + } + } + public var b: Components.Schemas.A.bPayload? + public init(b: Components.Schemas.A.bPayload? = nil) { + self.b = b + } + public enum CodingKeys: String, CodingKey { + case b + } + } + public struct B1: Codable, Hashable, Sendable { + public var c: Swift.String + public init(c: Swift.String) { + self.c = c + } + public enum CodingKeys: String, CodingKey { + case c + } + } + public struct B2: Codable, Hashable, Sendable { + public var d: Swift.String + public init(d: Swift.String) { + self.d = d + } + public enum CodingKeys: String, CodingKey { + case d + } + } + } + """ + ) + } + func testComponentsSchemasOneOf_open_pattern() throws { try self.assertSchemasTranslation( """ @@ -6240,10 +6513,12 @@ final class SnippetBasedReferenceTests: XCTestCase { extension SnippetBasedReferenceTests { func makeTypesTranslator(openAPIDocumentYAML: String) throws -> TypesFileTranslator { let document = try YAMLDecoder().decode(OpenAPI.Document.self, from: openAPIDocumentYAML) + // remove removingNullFromAnyOfAndOneOf() to match what we do in `GeneratorPipeline` + let sanitizedDocument = sanitizeSchemaNulls(document) return TypesFileTranslator( config: Config(mode: .types, access: .public, namingStrategy: .defensive), diagnostics: XCTestDiagnosticCollector(test: self), - components: document.components + components: sanitizedDocument.components ) } @@ -6256,7 +6531,9 @@ extension SnippetBasedReferenceTests { ignoredDiagnosticMessages: Set = [], componentsYAML: String ) throws -> TypesFileTranslator { - let components = try YAMLDecoder().decode(OpenAPI.Components.self, from: componentsYAML) + var components = try YAMLDecoder().decode(OpenAPI.Components.self, from: componentsYAML) + // remove removingNullFromAnyOfAndOneOf() to match what we do in `GeneratorPipeline` + components.schemas = components.schemas.removingNullFromAnyOfAndOneOf() return TypesFileTranslator( config: Config( mode: .types, From ed88d9c52941fb9143f85798351dcd47ddf5fcb2 Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:51:27 -0600 Subject: [PATCH 07/10] fix: comment said remove twice --- .../SnippetBasedReferenceTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift index bf2aed761..f46a3124c 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift @@ -6513,7 +6513,7 @@ final class SnippetBasedReferenceTests: XCTestCase { extension SnippetBasedReferenceTests { func makeTypesTranslator(openAPIDocumentYAML: String) throws -> TypesFileTranslator { let document = try YAMLDecoder().decode(OpenAPI.Document.self, from: openAPIDocumentYAML) - // remove removingNullFromAnyOfAndOneOf() to match what we do in `GeneratorPipeline` + // removingNullFromAnyOfAndOneOf() to match what we do in `GeneratorPipeline` let sanitizedDocument = sanitizeSchemaNulls(document) return TypesFileTranslator( config: Config(mode: .types, access: .public, namingStrategy: .defensive), @@ -6532,7 +6532,7 @@ extension SnippetBasedReferenceTests { componentsYAML: String ) throws -> TypesFileTranslator { var components = try YAMLDecoder().decode(OpenAPI.Components.self, from: componentsYAML) - // remove removingNullFromAnyOfAndOneOf() to match what we do in `GeneratorPipeline` + // removingNullFromAnyOfAndOneOf() to match what we do in `GeneratorPipeline` components.schemas = components.schemas.removingNullFromAnyOfAndOneOf() return TypesFileTranslator( config: Config( From 491a8a2c35068bfa567a1e970222ccd61a507451 Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:53:34 -0600 Subject: [PATCH 08/10] fix: remove unnecessary return --- Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index 83d567520..c7c430d54 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -69,7 +69,7 @@ struct GeneratorPipeline { /// - Returns: The output of the rendering stage. /// - Throws: An error if a non-recoverable issue occurs during pipeline execution. func run(_ input: RawInput) throws -> RenderedOutput { - return try renderSwiftFilesStage.run(translateOpenAPIToStructuredSwiftStage.run(parseOpenAPIFileStage.run(input))) + try renderSwiftFilesStage.run(translateOpenAPIToStructuredSwiftStage.run(parseOpenAPIFileStage.run(input))) } } From 75d22ac0470288dd9271b243e9c93c2f8aa15b84 Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Sat, 27 Sep 2025 14:31:05 -0600 Subject: [PATCH 09/10] chore: refactor simplify using existing nullableSchemaObject() --- .../GeneratorPipeline.swift | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index c7c430d54..d960bbe73 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -294,22 +294,13 @@ func sanitizeSchemaNulls(_ doc: OpenAPI.Document) -> OpenAPI.Document { } extension JSONSchema { - /// in place of the existing/default` nullableSchemaObject()` located in `OpenAPIKit` - /// this version simply makes a copy changing on the value of nullable to true + /// this simply makes a copy changing on the value of nullable to true, it handles `.reference` + /// directly or calls nullableSchemaObject()` located in `OpenAPIKit` public func nullableSchemaObjectCopy() -> JSONSchema { - switch value { - case .one(of: let schemas, core: let core): - return .init( - //warnings: warnings, // the init that allows maintaining warnings is internal - schema: .one(of: schemas, core: core.nullableContext()) - ) - case .any(of: let schemas, core: let core): - return .init( - //warnings: warnings, // the init that allows maintaining warnings is internal - schema: .any(of: schemas, core: core.nullableContext()) - ) - case .reference(let schema, let core): return .init(schema: .reference(schema, core.nullableContext())) - default: return self.nullableSchemaObject() + if case let .reference(schema, core) = value { + return .init(schema: .reference(schema, core.nullableContext())) + } else { + return self.nullableSchemaObject() } } } From dadc09d6d2ac24052c996354305980fa67acb53e Mon Sep 17 00:00:00 2001 From: David Pasirstein <6080874+dpasirst@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:08:33 -0600 Subject: [PATCH 10/10] chore: update comments only --- Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index d960bbe73..1a2f59832 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -287,6 +287,9 @@ extension OrderedDictionary where Key == OpenAPI.ComponentKey, Value == JSONSche } /// uses `removingNullFromAnyOfAndOneOf()` to remove from an OpenAPI Document +/// resulting in removing the nulls from anyOf/oneOf while marking it as nullable +/// - Parameter doc: the `OpenAPI.Document` to remove the nulls from +/// - Returns: a revised `OpenAPI.Document` func sanitizeSchemaNulls(_ doc: OpenAPI.Document) -> OpenAPI.Document { var doc = doc doc.components.schemas = doc.components.schemas.removingNullFromAnyOfAndOneOf() @@ -296,6 +299,7 @@ func sanitizeSchemaNulls(_ doc: OpenAPI.Document) -> OpenAPI.Document { extension JSONSchema { /// this simply makes a copy changing on the value of nullable to true, it handles `.reference` /// directly or calls nullableSchemaObject()` located in `OpenAPIKit` + /// - Returns: a nullable copy of the `JSONSchema` public func nullableSchemaObjectCopy() -> JSONSchema { if case let .reference(schema, core) = value { return .init(schema: .reference(schema, core.nullableContext()))