From 30741137ba8e092576978f845934823953c61ed4 Mon Sep 17 00:00:00 2001 From: Honza Dvorsky Date: Wed, 25 Oct 2023 09:07:46 +0200 Subject: [PATCH] Remove swift-syntax/swift-format as generator dependencies (#343) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove swift-syntax/swift-format as generator dependencies ### Motivation The swift-syntax/swift-format dependencies were only used to reformat the code before writing to disk, and significantly increased build and execution times, as well as leading to more dependency graph conflicts for our adopters. Turns out we can relatively easily remove the dependency, so doing that in this PR. ### Modifications Removed swift-format/swift-syntax as dependencies and replaced them with an improved version of `TextBasedRenderer`, which now adds some basic indentation, surprisingly getting us pretty close to the previous formatting. ### Result No more swift-syntax/swift-format dependency, but the generated code still looks very reasonable, and build/execution times should get noticably faster. ### Test Plan Adapted unit tests, integration tests: snippet and file-based tests. All passing now. Reviewed by: glbrntt Builds: ✔︎ pull request validation (5.10) - Build finished. ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (compatibility test) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. https://github.com/apple/swift-openapi-generator/pull/343 --- Package.swift | 20 +- .../Extensions/Foundation.swift | 25 - .../Extensions/SwiftFormat.swift | 63 -- .../GeneratorPipeline.swift | 8 +- .../Renderer/TextBasedRenderer.swift | 943 +++++++++++------- .../translateStructBlueprint.swift | 2 +- .../Renderer/Test_TextBasedRenderer.swift | 324 +++--- .../StructureHelpers.swift | 2 +- .../CompatabilityTest.swift | 2 - .../FileBasedReferenceTests.swift | 14 +- .../ReferenceSources/Petstore/Client.swift | 338 +++++-- .../ReferenceSources/Petstore/Server.swift | 306 ++++-- .../ReferenceSources/Petstore/Types.swift | 876 +++++++++++----- .../SnippetBasedReferenceTests.swift | 703 +++++++++---- scripts/run-swift-format.sh | 2 +- 15 files changed, 2345 insertions(+), 1283 deletions(-) delete mode 100644 Sources/_OpenAPIGeneratorCore/Extensions/SwiftFormat.swift diff --git a/Package.swift b/Package.swift index 2592967e..02dc5dbd 100644 --- a/Package.swift +++ b/Package.swift @@ -52,18 +52,6 @@ let package = Package( ], dependencies: [ - // Generate Swift code - .package( - url: "https://github.com/apple/swift-syntax.git", - "508.0.1"..<"510.0.0" - ), - - // Format Swift code - .package( - url: "https://github.com/apple/swift-format.git", - "508.0.1"..<"510.0.0" - ), - // General algorithms .package( url: "https://github.com/apple/swift-algorithms", @@ -105,10 +93,6 @@ let package = Package( .product(name: "OpenAPIKitCompat", package: "OpenAPIKit"), .product(name: "Algorithms", package: "swift-algorithms"), .product(name: "Yams", package: "Yams"), - .product(name: "SwiftSyntax", package: "swift-syntax"), - .product(name: "SwiftSyntaxBuilder", package: "swift-syntax"), - .product(name: "SwiftFormat", package: "swift-format"), - .product(name: "SwiftFormatConfiguration", package: "swift-format"), ], swiftSettings: swiftSettings ), @@ -126,9 +110,7 @@ let package = Package( .testTarget( name: "OpenAPIGeneratorReferenceTests", dependencies: [ - "_OpenAPIGeneratorCore", - .product(name: "SwiftFormat", package: "swift-format"), - .product(name: "SwiftFormatConfiguration", package: "swift-format"), + "_OpenAPIGeneratorCore" ], resources: [ .copy("Resources") diff --git a/Sources/_OpenAPIGeneratorCore/Extensions/Foundation.swift b/Sources/_OpenAPIGeneratorCore/Extensions/Foundation.swift index 8dbe00df..944473b4 100644 --- a/Sources/_OpenAPIGeneratorCore/Extensions/Foundation.swift +++ b/Sources/_OpenAPIGeneratorCore/Extensions/Foundation.swift @@ -13,20 +13,6 @@ //===----------------------------------------------------------------------===// import Foundation -extension Data { - /// A copy of the data formatted using swift-format. - /// - /// Data is assumed to contain Swift code encoded using UTF-8. - /// - /// - Throws: When data is not valid UTF-8. - var swiftFormatted: Data { - get throws { - let string = String(decoding: self, as: UTF8.self) - return try Self(string.swiftFormatted.utf8) - } - } -} - extension InMemoryInputFile { /// Creates a new in-memory file by reading the contents at the specified path. /// - Parameter url: The path to the file to read. @@ -36,17 +22,6 @@ extension InMemoryInputFile { } } -extension InMemoryOutputFile { - /// A copy of the file formatted using swift-format. - public var swiftFormatted: InMemoryOutputFile { - get throws { - var new = self - new.contents = try contents.swiftFormatted - return new - } - } -} - /// File handle to stderr. let stdErrHandle = FileHandle.standardError diff --git a/Sources/_OpenAPIGeneratorCore/Extensions/SwiftFormat.swift b/Sources/_OpenAPIGeneratorCore/Extensions/SwiftFormat.swift deleted file mode 100644 index 49d8c317..00000000 --- a/Sources/_OpenAPIGeneratorCore/Extensions/SwiftFormat.swift +++ /dev/null @@ -1,63 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftOpenAPIGenerator open source project -// -// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -import SwiftFormat -import SwiftFormatConfiguration - -extension String { - /// A copy of the string formatted using swift-format. - var swiftFormatted: Self { - get throws { - var formattedString = "" - // TODO: Should be loaded from a swift-format file that we also use to format our own code. - var configuration = Configuration() - configuration.rules["OrderedImports"] = false - configuration.rules["NoAccessLevelOnExtensionDeclaration"] = false - configuration.rules["UseLetInEveryBoundCaseVariable"] = false - configuration.indentation = .spaces(4) - configuration.respectsExistingLineBreaks = false - configuration.lineBreakBeforeEachArgument = true - configuration.lineBreakBeforeControlFlowKeywords = false - configuration.lineBreakBeforeEachGenericRequirement = true - configuration.lineBreakAroundMultilineExpressionChainComponents = true - configuration.indentConditionalCompilationBlocks = false - configuration.maximumBlankLines = 0 - configuration.lineLength = 120 - let formatter = SwiftFormatter(configuration: configuration) - try formatter.format( - source: self, - assumingFileURL: nil, - to: &formattedString - ) { diagnostic, sourceLocation in - #if canImport(SwiftSyntax509) - let location = "\(sourceLocation.line):\(sourceLocation.column)" - #else - let location = "\(sourceLocation.debugDescription)" - #endif - print( - """ - === - Formatting the following code produced diagnostic at location \(location) (see end): - --- - \(self.withLineNumberPrefixes) - --- - \(diagnostic.debugDescription) - === - """ - ) - print(diagnostic) - } - return formattedString - } - } -} diff --git a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift index 0a0fba5c..03e6978a 100644 --- a/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift +++ b/Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift @@ -101,7 +101,6 @@ public func runGenerator( /// - validator: A validator for parsed OpenAPI documents. /// - translator: A translator from OpenAPI to Swift. /// - renderer: A Swift code renderer. -/// - formatter: A Swift code formatter. /// - config: A set of configuration values for the generator. /// - diagnostics: A collector to which the generator emits diagnostics. /// - Returns: A configured generator pipeline that can be executed with @@ -110,8 +109,7 @@ func makeGeneratorPipeline( parser: any ParserProtocol = YamsParser(), validator: @escaping (ParsedOpenAPIRepresentation, Config) throws -> [Diagnostic] = validateDoc, translator: any TranslatorProtocol = MultiplexTranslator(), - renderer: any RendererProtocol = TextBasedRenderer(), - formatter: @escaping (InMemoryOutputFile) throws -> InMemoryOutputFile = { try $0.swiftFormatted }, + renderer: any RendererProtocol = TextBasedRenderer.default, config: Config, diagnostics: any DiagnosticCollector ) -> GeneratorPipeline { @@ -161,9 +159,7 @@ func makeGeneratorPipeline( diagnostics: diagnostics ) }, - postTransitionHooks: [ - formatter - ] + postTransitionHooks: [] ) ) } diff --git a/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift b/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift index e5b268ff..20b7aa73 100644 --- a/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift +++ b/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift @@ -13,6 +13,86 @@ //===----------------------------------------------------------------------===// import Foundation +/// An object for building up a generated file line-by-line. +/// +/// After creation, make calls such as `writeLine` to build up the file, +/// and call `rendered` at the end to get the full file contents. +final class StringCodeWriter { + + /// The stored lines of code. + private var lines: [String] + + /// The current nesting level. + private var level: Int + + /// Whether the next call to `writeLine` will continue writing to the last + /// stored line. Otherwise a new line is appended. + private var nextWriteAppendsToLastLine: Bool = false + + /// Creates a new empty writer. + init() { + self.level = 0 + self.lines = [] + } + + /// Concatenates the stored lines of code into a single string. + /// - Returns: The contents of the full file in a single string. + func rendered() -> String { + lines.joined(separator: "\n") + } + + /// Writes a line of code. + /// + /// By default, a new line is appended to the file. + /// + /// To continue the last line, make a call to `nextLineAppendsToLastLine` + /// before calling `writeLine`. + /// - Parameter line: The contents of the line to write. + func writeLine(_ line: String) { + let newLine: String + if nextWriteAppendsToLastLine && !lines.isEmpty { + let existingLine = lines.removeLast() + newLine = existingLine + line + } else { + let indentation = Array(repeating: " ", count: 4 * level).joined() + newLine = indentation + line + } + lines.append(newLine) + nextWriteAppendsToLastLine = false + } + + /// Increases the indentation level by 1. + func push() { + level += 1 + } + + /// Decreases the indentation level by 1. + /// - Precondition: Current level must be greater than 0. + func pop() { + precondition(level > 0, "Cannot pop below 0") + level -= 1 + } + + /// Executes the provided closure with one level deeper indentation. + /// - Parameter work: The closure to execute. + /// - Returns: The result of the closure execution. + func withNestedLevel(_ work: () -> R) -> R { + push() + defer { + pop() + } + return work() + } + + /// Sets a flag on the writer so that the next call to `writeLine` continues + /// the last stored line instead of starting a new line. + /// + /// Safe to call repeatedly, it gets reset by `writeLine`. + func nextLineAppendsToLastLine() { + nextWriteAppendsToLastLine = true + } +} + /// A renderer that uses string interpolation and concatenation /// to convert the provided structure code into raw string form. struct TextBasedRenderer: RendererProtocol { @@ -23,21 +103,45 @@ struct TextBasedRenderer: RendererProtocol { diagnostics: any DiagnosticCollector ) throws -> InMemoryOutputFile { let namedFile = structured.file + renderFile(namedFile.contents) + let string = writer.rendered() return InMemoryOutputFile( baseName: namedFile.name, - contents: renderFile(namedFile.contents) + contents: Data(string.utf8) ) } + /// The underlying writer. + private let writer: StringCodeWriter + + /// Creates a new empty renderer. + static var `default`: TextBasedRenderer { + .init(writer: StringCodeWriter()) + } + // MARK: - Internals + /// Returns the current contents of the writer as a string. + func renderedContents() -> String { + writer.rendered() + } + /// Renders the specified Swift file. - func renderFile(_ description: FileDescription) -> Data { - Data(renderedFile(description).utf8) + func renderFile(_ description: FileDescription) { + if let topComment = description.topComment { + renderComment(topComment) + } + if let imports = description.imports { + renderImports(imports) + } + for codeBlock in description.codeBlocks { + renderCodeBlock(codeBlock) + writer.writeLine("") + } } /// Renders the specified comment. - func renderedComment(_ comment: Comment) -> String { + func renderComment(_ comment: Comment) { let prefix: String let commentString: String switch comment { @@ -54,7 +158,7 @@ struct TextBasedRenderer: RendererProtocol { prefix = "// MARK:" commentString = string } - return + let lines = commentString .transformingLines { line in if line.isEmpty { @@ -62,43 +166,39 @@ struct TextBasedRenderer: RendererProtocol { } return "\(prefix) \(line)" } + lines.forEach(writer.writeLine) } /// Renders the specified import statements. - func renderedImports(_ imports: [ImportDescription]?) -> String { - (imports ?? []) - .map(renderImport(_:)) - .joinedLines() + func renderImports(_ imports: [ImportDescription]?) { + (imports ?? []).forEach(renderImport) } /// Renders a single import statement. - func renderImport(_ description: ImportDescription) -> String { - func render(preconcurrency: Bool) -> String { + func renderImport(_ description: ImportDescription) { + func render(preconcurrency: Bool) { let spiPrefix = description.spi.map { "@_spi(\($0)) " } ?? "" let preconcurrencyPrefix = preconcurrency ? "@preconcurrency " : "" - var types = [String]() if let moduleTypes = description.moduleTypes { - types = moduleTypes.map { - "\(preconcurrencyPrefix)\(spiPrefix)import \($0)" + for type in moduleTypes { + writer.writeLine("\(preconcurrencyPrefix)\(spiPrefix)import \(type)") } - return types.joinedLines() + } else { + writer.writeLine("\(preconcurrencyPrefix)\(spiPrefix)import \(description.moduleName)") } - return "\(preconcurrencyPrefix)\(spiPrefix)import \(description.moduleName)" } switch description.preconcurrency { case .always: - return render(preconcurrency: true) + render(preconcurrency: true) case .never: - return render(preconcurrency: false) + render(preconcurrency: false) case .onOS(let operatingSystems): - var lines = [String]() - lines.append("#if \(operatingSystems.map { "os(\($0))" }.joined(separator: " || "))") - lines.append(render(preconcurrency: true)) - lines.append("#else") - lines.append(render(preconcurrency: false)) - lines.append("#endif") - return lines.joinedLines() + writer.writeLine("#if \(operatingSystems.map { "os(\($0))" }.joined(separator: " || "))") + render(preconcurrency: true) + writer.writeLine("#else") + render(preconcurrency: false) + writer.writeLine("#endif") } } @@ -127,38 +227,65 @@ struct TextBasedRenderer: RendererProtocol { } /// Renders the specified member access expression. - func renderedMemberAccess(_ memberAccess: MemberAccessDescription) -> String { - let left = memberAccess.left.flatMap { renderedExpression($0) } ?? "" - return "\(left).\(memberAccess.right)" + func renderMemberAccess(_ memberAccess: MemberAccessDescription) { + if let left = memberAccess.left { + renderExpression(left) + writer.nextLineAppendsToLastLine() + } + writer.writeLine(".\(memberAccess.right)") } /// Renders the specified function call argument. - func renderedFunctionCallArgument(_ arg: FunctionArgumentDescription) -> String { - let left = arg.label.flatMap { "\($0): " } ?? "" - return left + renderedExpression(arg.expression) + func renderFunctionCallArgument(_ arg: FunctionArgumentDescription) { + if let left = arg.label { + writer.writeLine("\(left): ") + writer.nextLineAppendsToLastLine() + } + renderExpression(arg.expression) } /// Renders the specified function call. - func renderedFunctionCall(_ functionCall: FunctionCallDescription) -> String { + func renderFunctionCall(_ functionCall: FunctionCallDescription) { + renderExpression(functionCall.calledExpression) + writer.nextLineAppendsToLastLine() + writer.writeLine("(") let arguments = functionCall.arguments - let trailingClosureString: String - if let trailingClosure = functionCall.trailingClosure { - trailingClosureString = renderedClosureInvocation(trailingClosure) + if arguments.count > 1 { + writer.withNestedLevel { + for (argument, isLast) in arguments.enumeratedWithLastMarker() { + renderFunctionCallArgument(argument) + if !isLast { + writer.nextLineAppendsToLastLine() + writer.writeLine(",") + } + } + } } else { - trailingClosureString = "" + writer.nextLineAppendsToLastLine() + if let argument = arguments.first { + renderFunctionCallArgument(argument) + } + writer.nextLineAppendsToLastLine() + } + writer.writeLine(")") + if let trailingClosure = functionCall.trailingClosure { + writer.nextLineAppendsToLastLine() + writer.writeLine(" ") + renderClosureInvocation(trailingClosure) } - return - "\(renderedExpression(functionCall.calledExpression))(\(arguments.map(renderedFunctionCallArgument).joined(separator: ", ")))" - + trailingClosureString } /// Renders the specified assignment expression. - func renderedAssignment(_ assignment: AssignmentDescription) -> String { - return "\(renderedExpression(assignment.left)) = \(renderedExpression(assignment.right))" + func renderAssignment(_ assignment: AssignmentDescription) { + renderExpression(assignment.left) + writer.nextLineAppendsToLastLine() + writer.writeLine(" = ") + writer.nextLineAppendsToLastLine() + renderExpression(assignment.right) } /// Renders the specified switch case kind. - func renderedSwitchCaseKind(_ kind: SwitchCaseKind) -> String { + func renderSwitchCaseKind(_ kind: SwitchCaseKind) { switch kind { case let .`case`(expression, associatedValueNames): let associatedValues: String @@ -170,68 +297,108 @@ struct TextBasedRenderer: RendererProtocol { associatedValues = "" maybeLet = "" } - return "case \(maybeLet)\(renderedExpression(expression))\(associatedValues)" + writer.writeLine("case \(maybeLet)") + writer.nextLineAppendsToLastLine() + renderExpression(expression) + writer.nextLineAppendsToLastLine() + writer.writeLine(associatedValues) case .multiCase(let expressions): - let expressions = expressions.map(renderedExpression).joined(separator: ", ") - return "case \(expressions)" + writer.writeLine("case ") + writer.nextLineAppendsToLastLine() + for (expression, isLast) in expressions.enumeratedWithLastMarker() { + renderExpression(expression) + writer.nextLineAppendsToLastLine() + if !isLast { + writer.writeLine(", ") + } + writer.nextLineAppendsToLastLine() + } case .`default`: - return "default" + writer.writeLine("default") } } /// Renders the specified switch case. - func renderedSwitchCase(_ switchCase: SwitchCaseDescription) -> String { - var lines: [String] = [] - lines.append(renderedSwitchCaseKind(switchCase.kind) + ":") - lines.append(renderedCodeBlocks(switchCase.body)) - return lines.joinedLines() + func renderSwitchCase(_ switchCase: SwitchCaseDescription) { + renderSwitchCaseKind(switchCase.kind) + writer.nextLineAppendsToLastLine() + writer.writeLine(":") + writer.withNestedLevel { + renderCodeBlocks(switchCase.body) + } } /// Renders the specified switch expression. - func renderedSwitch(_ switchDesc: SwitchDescription) -> String { - var lines: [String] = ["switch \(renderedExpression(switchDesc.switchedExpression)) {"] + func renderSwitch(_ switchDesc: SwitchDescription) { + writer.writeLine("switch ") + writer.nextLineAppendsToLastLine() + renderExpression(switchDesc.switchedExpression) + writer.nextLineAppendsToLastLine() + writer.writeLine(" {") for caseDesc in switchDesc.cases { - lines.append(renderedSwitchCase(caseDesc)) + renderSwitchCase(caseDesc) } - lines.append("}") - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified if statement. - func renderedIf(_ ifDesc: IfStatementDescription) -> String { - var lines: [String] = [] + func renderIf(_ ifDesc: IfStatementDescription) { let ifBranch = ifDesc.ifBranch - lines.append("if \(renderedExpression(ifBranch.condition)) {") - lines.append(renderedCodeBlocks(ifBranch.body)) - lines.append("}") + writer.writeLine("if ") + writer.nextLineAppendsToLastLine() + renderExpression(ifBranch.condition) + writer.nextLineAppendsToLastLine() + writer.writeLine(" {") + writer.withNestedLevel { + renderCodeBlocks(ifBranch.body) + } + writer.writeLine("}") for branch in ifDesc.elseIfBranches { - lines.append("else if \(renderedExpression(branch.condition)) {") - lines.append(renderedCodeBlocks(branch.body)) - lines.append("}") + writer.nextLineAppendsToLastLine() + writer.writeLine(" else if ") + writer.nextLineAppendsToLastLine() + renderExpression(branch.condition) + writer.nextLineAppendsToLastLine() + writer.writeLine(" {") + writer.withNestedLevel { + renderCodeBlocks(branch.body) + } + writer.writeLine("}") } if let elseBody = ifDesc.elseBody { - lines.append("else {") - lines.append(renderedCodeBlocks(elseBody)) - lines.append("}") + writer.nextLineAppendsToLastLine() + writer.writeLine(" else {") + writer.withNestedLevel { + renderCodeBlocks(elseBody) + } + writer.writeLine("}") } - return lines.joinedLines() } /// Renders the specified switch expression. - func renderedDoStatement(_ description: DoStatementDescription) -> String { - var lines: [String] = ["do {"] - lines.append(renderedCodeBlocks(description.doStatement)) + func renderDoStatement(_ description: DoStatementDescription) { + writer.writeLine("do {") + writer.withNestedLevel { + renderCodeBlocks(description.doStatement) + } if let catchBody = description.catchBody { - lines.append("} catch {") - lines.append(renderedCodeBlocks(catchBody)) + writer.writeLine("} catch {") + if !catchBody.isEmpty { + writer.withNestedLevel { + renderCodeBlocks(catchBody) + } + } else { + writer.nextLineAppendsToLastLine() + } } - lines.append("}") - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified value binding expression. - func renderedValueBinding(_ valueBinding: ValueBindingDescription) -> String { - return "\(renderedBindingKind(valueBinding.kind)) \(renderedFunctionCall(valueBinding.value))" + func renderValueBinding(_ valueBinding: ValueBindingDescription) { + writer.writeLine("\(renderedBindingKind(valueBinding.kind)) ") + writer.nextLineAppendsToLastLine() + renderFunctionCall(valueBinding.value) } /// Renders the specified keyword. @@ -251,28 +418,30 @@ struct TextBasedRenderer: RendererProtocol { } /// Renders the specified unary keyword expression. - func renderedUnaryKeywordExpression(_ expression: UnaryKeywordDescription) -> String { - let keyword = renderedKeywordKind(expression.kind) + func renderUnaryKeywordExpression(_ expression: UnaryKeywordDescription) { + writer.writeLine(renderedKeywordKind(expression.kind)) guard let expr = expression.expression else { - return keyword + return } - return "\(keyword) \(renderedExpression(expr))" + writer.nextLineAppendsToLastLine() + writer.writeLine(" ") + writer.nextLineAppendsToLastLine() + renderExpression(expr) } /// Renders the specified closure invocation. - func renderedClosureInvocation(_ invocation: ClosureInvocationDescription) -> String { - var lines: [String] = [] - var signatureWords: [String] = ["{"] + func renderClosureInvocation(_ invocation: ClosureInvocationDescription) { + writer.writeLine("{") if !invocation.argumentNames.isEmpty { - signatureWords.append(invocation.argumentNames.joined(separator: ", ")) - signatureWords.append("in") + writer.nextLineAppendsToLastLine() + writer.writeLine(" \(invocation.argumentNames.joined(separator: ", ")) in") } - lines.append(signatureWords.joinedWords()) if let body = invocation.body { - lines.append(renderedCodeBlocks(body)) + writer.withNestedLevel { + renderCodeBlocks(body) + } } - lines.append("}") - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified binary operator. @@ -281,85 +450,111 @@ struct TextBasedRenderer: RendererProtocol { } /// Renders the specified binary operation. - func renderedBinaryOperation(_ operation: BinaryOperationDescription) -> String { - renderedExpression(operation.left) + " " - + renderedBinaryOperator(operation.operation) + " " - + renderedExpression(operation.right) + func renderBinaryOperation(_ operation: BinaryOperationDescription) { + renderExpression(operation.left) + writer.nextLineAppendsToLastLine() + writer.writeLine(" \(renderedBinaryOperator(operation.operation)) ") + writer.nextLineAppendsToLastLine() + renderExpression(operation.right) } /// Renders the specified inout expression. - func renderedInOutDescription(_ description: InOutDescription) -> String { - "&" + renderedExpression(description.referencedExpr) + func renderInOutDescription(_ description: InOutDescription) { + writer.writeLine("&") + writer.nextLineAppendsToLastLine() + renderExpression(description.referencedExpr) } /// Renders the specified optional chaining expression. - func renderedOptionalChainingDescription( - _ description: OptionalChainingDescription - ) -> String { - renderedExpression(description.referencedExpr) + "?" + func renderOptionalChainingDescription(_ description: OptionalChainingDescription) { + renderExpression(description.referencedExpr) + writer.nextLineAppendsToLastLine() + writer.writeLine("?") } /// Renders the specified tuple expression. - func renderedTupleDescription( - _ description: TupleDescription - ) -> String { - "(" + description.members.map(renderedExpression).joined(separator: ", ") + ")" + func renderTupleDescription(_ description: TupleDescription) { + writer.writeLine("(") + writer.nextLineAppendsToLastLine() + let members = description.members + for (member, isLast) in members.enumeratedWithLastMarker() { + renderExpression(member) + if !isLast { + writer.nextLineAppendsToLastLine() + writer.writeLine(", ") + } + writer.nextLineAppendsToLastLine() + } + writer.writeLine(")") } /// Renders the specified expression. - func renderedExpression(_ expression: Expression) -> String { + func renderExpression(_ expression: Expression) { switch expression { case .literal(let literalDescription): - return renderedLiteral(literalDescription) + renderLiteral(literalDescription) case .identifier(let identifierDescription): - return renderedIdentifier(identifierDescription) + writer.writeLine(renderedIdentifier(identifierDescription)) case .memberAccess(let memberAccessDescription): - return renderedMemberAccess(memberAccessDescription) + renderMemberAccess(memberAccessDescription) case .functionCall(let functionCallDescription): - return renderedFunctionCall(functionCallDescription) + renderFunctionCall(functionCallDescription) case .assignment(let assignment): - return renderedAssignment(assignment) + renderAssignment(assignment) case .switch(let switchDesc): - return renderedSwitch(switchDesc) + renderSwitch(switchDesc) case .ifStatement(let ifDesc): - return renderedIf(ifDesc) + renderIf(ifDesc) case .doStatement(let doStmt): - return renderedDoStatement(doStmt) + renderDoStatement(doStmt) case .valueBinding(let valueBinding): - return renderedValueBinding(valueBinding) + renderValueBinding(valueBinding) case .unaryKeyword(let unaryKeyword): - return renderedUnaryKeywordExpression(unaryKeyword) + renderUnaryKeywordExpression(unaryKeyword) case .closureInvocation(let closureInvocation): - return renderedClosureInvocation(closureInvocation) + renderClosureInvocation(closureInvocation) case .binaryOperation(let binaryOperation): - return renderedBinaryOperation(binaryOperation) + renderBinaryOperation(binaryOperation) case .inOut(let inOut): - return renderedInOutDescription(inOut) + renderInOutDescription(inOut) case .optionalChaining(let optionalChaining): - return renderedOptionalChainingDescription(optionalChaining) + renderOptionalChainingDescription(optionalChaining) case .tuple(let tuple): - return renderedTupleDescription(tuple) + renderTupleDescription(tuple) } } /// Renders the specified literal expression. - func renderedLiteral(_ literal: LiteralDescription) -> String { + func renderLiteral(_ literal: LiteralDescription) { + func write(_ string: String) { + writer.writeLine(string) + } switch literal { case let .string(string): // Use a raw literal if the string contains a quote/backslash. if string.contains("\"") || string.contains("\\") { - return "#\"\(string)\"#" + write("#\"\(string)\"#") } else { - return "\"\(string)\"" + write("\"\(string)\"") } case let .int(int): - return "\(int)" + write("\(int)") case let .bool(bool): - return bool ? "true" : "false" + write(bool ? "true" : "false") case .nil: - return "nil" + write("nil") case .array(let items): - return "[\(items.map { renderedExpression($0) }.joined(separator: ", "))]" + writer.writeLine("[") + writer.nextLineAppendsToLastLine() + for (item, isLast) in items.enumeratedWithLastMarker() { + renderExpression(item) + if !isLast { + writer.nextLineAppendsToLastLine() + writer.writeLine(", ") + } + writer.nextLineAppendsToLastLine() + } + writer.writeLine("]") } } @@ -378,27 +573,28 @@ struct TextBasedRenderer: RendererProtocol { } /// Renders the specified extension declaration. - func renderedExtension(_ extensionDescription: ExtensionDescription) -> String { - var signatureWords: [String] = [] + func renderExtension(_ extensionDescription: ExtensionDescription) { if let accessModifier = extensionDescription.accessModifier { - signatureWords.append(renderedAccessModifier(accessModifier)) + writer.writeLine(renderedAccessModifier(accessModifier) + " ") + writer.nextLineAppendsToLastLine() } - signatureWords.append("extension") - signatureWords.append(extensionDescription.onType) + writer.writeLine("extension \(extensionDescription.onType)") + writer.nextLineAppendsToLastLine() if !extensionDescription.conformances.isEmpty { - signatureWords.append(":") - signatureWords.append(extensionDescription.conformances.joined(separator: ", ")) + writer.writeLine(": \(extensionDescription.conformances.joined(separator: ", "))") + writer.nextLineAppendsToLastLine() } if let whereClause = extensionDescription.whereClause { - signatureWords.append(renderedWhereClause(whereClause)) + writer.writeLine(" " + renderedWhereClause(whereClause)) + writer.nextLineAppendsToLastLine() } - var lines: [String] = [] - lines.append("\(signatureWords.joinedWords()) {") + writer.writeLine(" {") for declaration in extensionDescription.declarations { - lines.append(renderedDeclaration(declaration)) + writer.withNestedLevel { + renderDeclaration(declaration) + } } - lines.append("}") - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified type reference to an existing type. @@ -420,7 +616,7 @@ struct TextBasedRenderer: RendererProtocol { } /// Renders the specified typealias declaration. - func renderedTypealias(_ alias: TypealiasDescription) -> String { + func renderTypealias(_ alias: TypealiasDescription) { var words: [String] = [] if let accessModifier = alias.accessModifier { words.append(renderedAccessModifier(accessModifier)) @@ -431,7 +627,7 @@ struct TextBasedRenderer: RendererProtocol { "=", renderedExistingTypeDescription(alias.existingType), ]) - return words.joinedWords() + writer.writeLine(words.joinedWords()) } /// Renders the specified binding kind. @@ -445,195 +641,214 @@ struct TextBasedRenderer: RendererProtocol { } /// Renders the specified variable declaration. - func renderedVariable(_ variable: VariableDescription) -> String { - var words: [String] = [] - if let accessModifier = variable.accessModifier { - words.append(renderedAccessModifier(accessModifier)) - } - if variable.isStatic { - words.append("static") - } - words.append(renderedBindingKind(variable.kind)) - let labelWithOptionalType: String - if let type = variable.type { - labelWithOptionalType = "\(variable.left): \(renderedExistingTypeDescription(type))" - } else { - labelWithOptionalType = variable.left + func renderVariable(_ variable: VariableDescription) { + do { + var words: [String] = [] + if let accessModifier = variable.accessModifier { + words.append(renderedAccessModifier(accessModifier)) + } + if variable.isStatic { + words.append("static") + } + words.append(renderedBindingKind(variable.kind)) + let labelWithOptionalType: String + if let type = variable.type { + labelWithOptionalType = "\(variable.left): \(renderedExistingTypeDescription(type))" + } else { + labelWithOptionalType = variable.left + } + words.append(labelWithOptionalType) + writer.writeLine(words.joinedWords()) } - words.append(labelWithOptionalType) if let right = variable.right { - words.append("= \(renderedExpression(right))") + writer.nextLineAppendsToLastLine() + writer.writeLine(" = ") + writer.nextLineAppendsToLastLine() + renderExpression(right) } - var lines: [String] = [words.joinedWords()] if let body = variable.getter { - lines.append("{") - let hasExplicitGetter = !variable.getterEffects.isEmpty || variable.setter != nil || variable.modify != nil - if hasExplicitGetter { - lines.append("get \(variable.getterEffects.map(renderedFunctionKeyword).joined(separator: " ")) {") - } - lines.append(renderedCodeBlocks(body)) - if hasExplicitGetter { - lines.append("}") - } - if let modify = variable.modify { - lines.append("_modify {") - lines.append(renderedCodeBlocks(modify)) - lines.append("}") - } - if let setter = variable.setter { - lines.append("set {") - lines.append(renderedCodeBlocks(setter)) - lines.append("}") + writer.nextLineAppendsToLastLine() + writer.writeLine(" {") + writer.withNestedLevel { + let hasExplicitGetter = + !variable.getterEffects.isEmpty + || variable.setter != nil || variable.modify != nil + if hasExplicitGetter { + let keywords = variable + .getterEffects + .map(renderedFunctionKeyword) + .joined(separator: " ") + let line = "get \(keywords) {" + writer.writeLine(line) + writer.push() + } + renderCodeBlocks(body) + if hasExplicitGetter { + writer.pop() + writer.writeLine("}") + } + if let modify = variable.modify { + writer.writeLine("_modify {") + writer.withNestedLevel { + renderCodeBlocks(modify) + } + writer.writeLine("}") + } + if let setter = variable.setter { + writer.writeLine("set {") + writer.withNestedLevel { + renderCodeBlocks(setter) + } + writer.writeLine("}") + } } - lines.append("}") + writer.writeLine("}") } - return lines.joinedLines() } /// Renders the specified struct declaration. - func renderedStruct(_ structDesc: StructDescription) -> String { - var words: [String] = [] + func renderStruct(_ structDesc: StructDescription) { if let accessModifier = structDesc.accessModifier { - words.append(renderedAccessModifier(accessModifier)) + writer.writeLine(renderedAccessModifier(accessModifier) + " ") + writer.nextLineAppendsToLastLine() } - words.append("struct") - words.append(structDesc.name) + writer.writeLine("struct \(structDesc.name)") + writer.nextLineAppendsToLastLine() if !structDesc.conformances.isEmpty { - words.append(":") - words.append(structDesc.conformances.joined(separator: ", ")) + writer.writeLine(": \(structDesc.conformances.joined(separator: ", "))") + writer.nextLineAppendsToLastLine() } - words.append("{") - let declarationLine = words.joinedWords() - - var lines: [String] = [] - lines.append(declarationLine) - - for member in structDesc.members { - lines.append(contentsOf: renderedDeclaration(member).asLines()) + writer.writeLine(" {") + if !structDesc.members.isEmpty { + writer.withNestedLevel { + for member in structDesc.members { + renderDeclaration(member) + } + } + } else { + writer.nextLineAppendsToLastLine() } - - lines.append("}") - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified protocol declaration. - func renderedProtocol(_ protocolDesc: ProtocolDescription) -> String { - var words: [String] = [] + func renderProtocol(_ protocolDesc: ProtocolDescription) { if let accessModifier = protocolDesc.accessModifier { - words.append(renderedAccessModifier(accessModifier)) + writer.writeLine("\(renderedAccessModifier(accessModifier)) ") + writer.nextLineAppendsToLastLine() } - words.append("protocol") - words.append(protocolDesc.name) + writer.writeLine("protocol \(protocolDesc.name)") + writer.nextLineAppendsToLastLine() if !protocolDesc.conformances.isEmpty { - words.append(":") - words.append(protocolDesc.conformances.joined(separator: ", ")) + let conformances = protocolDesc.conformances.joined(separator: ", ") + writer.writeLine(": \(conformances)") + writer.nextLineAppendsToLastLine() } - words.append("{") - let declarationLine = words.joinedWords() - - var lines: [String] = [] - lines.append(declarationLine) - - for member in protocolDesc.members { - lines.append(contentsOf: renderedDeclaration(member).asLines()) + writer.writeLine(" {") + if !protocolDesc.members.isEmpty { + writer.withNestedLevel { + for member in protocolDesc.members { + renderDeclaration(member) + } + } + } else { + writer.nextLineAppendsToLastLine() } - - lines.append("}") - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified enum declaration. - func renderedEnum(_ enumDesc: EnumDescription) -> String { - var words: [String] = [] + func renderEnum(_ enumDesc: EnumDescription) { if enumDesc.isFrozen { - words.append("@frozen") + writer.writeLine("@frozen ") + writer.nextLineAppendsToLastLine() } if let accessModifier = enumDesc.accessModifier { - words.append(renderedAccessModifier(accessModifier)) + writer.writeLine("\(renderedAccessModifier(accessModifier)) ") + writer.nextLineAppendsToLastLine() } if enumDesc.isIndirect { - words.append("indirect") + writer.writeLine("indirect ") + writer.nextLineAppendsToLastLine() } - words.append("enum") - words.append(enumDesc.name) + writer.writeLine("enum \(enumDesc.name)") + writer.nextLineAppendsToLastLine() if !enumDesc.conformances.isEmpty { - words.append(":") - words.append(enumDesc.conformances.joined(separator: ", ")) + writer.writeLine(": \(enumDesc.conformances.joined(separator: ", "))") + writer.nextLineAppendsToLastLine() } - words.append("{") - let declarationLine = words.joinedWords() - - var lines: [String] = [] - lines.append(declarationLine) - - for member in enumDesc.members { - lines.append(contentsOf: renderedDeclaration(member).asLines()) + writer.writeLine(" {") + if !enumDesc.members.isEmpty { + writer.withNestedLevel { + for member in enumDesc.members { + renderDeclaration(member) + } + } + } else { + writer.nextLineAppendsToLastLine() } - - lines.append("}") - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified enum case associated value. func renderedEnumCaseAssociatedValue(_ value: EnumCaseAssociatedValueDescription) -> String { var words: [String] = [] if let label = value.label { - words.append(label) - words.append(":") + words.append(label + ":") } words.append(renderedExistingTypeDescription(value.type)) return words.joinedWords() } - /// Renders the specified enum case kind. - func renderedEnumCaseKind(_ kind: EnumCaseKind) -> String { - switch kind { + /// Renders the specified enum case declaration. + func renderEnumCase(_ enumCase: EnumCaseDescription) { + writer.writeLine("case \(enumCase.name)") + switch enumCase.kind { case .nameOnly: - return "" + break case .nameWithRawValue(let rawValue): - return " = \(renderedLiteral(rawValue))" + writer.nextLineAppendsToLastLine() + writer.writeLine(" = ") + writer.nextLineAppendsToLastLine() + renderLiteral(rawValue) case .nameWithAssociatedValues(let values): if values.isEmpty { - return "" + break } let associatedValues = values .map(renderedEnumCaseAssociatedValue) .joined(separator: ", ") - return "(\(associatedValues))" + writer.nextLineAppendsToLastLine() + writer.writeLine("(\(associatedValues))") } } - /// Renders the specified enum case declaration. - func renderedEnumCase(_ enumCase: EnumCaseDescription) -> String { - return "case \(enumCase.name)\(renderedEnumCaseKind(enumCase.kind))" - } - /// Renders the specified declaration. - func renderedDeclaration(_ declaration: Declaration) -> String { + func renderDeclaration(_ declaration: Declaration) { switch declaration { case let .commentable(comment, nestedDeclaration): - return renderedCommentableDeclaration(comment: comment, declaration: nestedDeclaration) + renderCommentableDeclaration(comment: comment, declaration: nestedDeclaration) case let .deprecated(deprecation, nestedDeclaration): - return renderedDeprecatedDeclaration(deprecation: deprecation, declaration: nestedDeclaration) + renderDeprecatedDeclaration(deprecation: deprecation, declaration: nestedDeclaration) case .variable(let variableDescription): - return renderedVariable(variableDescription) + renderVariable(variableDescription) case .extension(let extensionDescription): - return renderedExtension(extensionDescription) + renderExtension(extensionDescription) case .struct(let structDescription): - return renderedStruct(structDescription) + renderStruct(structDescription) case .protocol(let protocolDescription): - return renderedProtocol(protocolDescription) + renderProtocol(protocolDescription) case .enum(let enumDescription): - return renderedEnum(enumDescription) + renderEnum(enumDescription) case .typealias(let typealiasDescription): - return renderedTypealias(typealiasDescription) + renderTypealias(typealiasDescription) case .function(let functionDescription): - return renderedFunction(functionDescription) + renderFunction(functionDescription) case .enumCase(let enumCase): - return renderedEnumCase(enumCase) + renderEnumCase(enumCase) } } @@ -658,89 +873,112 @@ struct TextBasedRenderer: RendererProtocol { } /// Renders the specified function signature. - func renderedFunctionSignature(_ signature: FunctionSignatureDescription) -> String { - var words: [String] = [] - if let accessModifier = signature.accessModifier { - words.append(renderedAccessModifier(accessModifier)) + func renderFunctionSignature(_ signature: FunctionSignatureDescription) { + do { + if let accessModifier = signature.accessModifier { + writer.writeLine(renderedAccessModifier(accessModifier) + " ") + writer.nextLineAppendsToLastLine() + } + writer.writeLine(renderedFunctionKind(signature.kind) + "(") + let parameters = signature.parameters + let separateLines = parameters.count > 1 + if separateLines { + writer.withNestedLevel { + for (parameter, isLast) in signature.parameters.enumeratedWithLastMarker() { + renderParameter(parameter) + if !isLast { + writer.nextLineAppendsToLastLine() + writer.writeLine(",") + } + } + } + } else { + writer.nextLineAppendsToLastLine() + if let parameter = parameters.first { + renderParameter(parameter) + } + writer.nextLineAppendsToLastLine() + } + writer.writeLine(")") } - words.append(renderedFunctionKind(signature.kind)) - words.append("(") - words.append(signature.parameters.map(renderedParameter).joined(separator: ", ")) - words.append(")") - for keyword in signature.keywords { - words.append(renderedFunctionKeyword(keyword)) + + do { + let keywords = signature.keywords + if !keywords.isEmpty { + for keyword in keywords { + writer.nextLineAppendsToLastLine() + writer.writeLine(" " + renderedFunctionKeyword(keyword)) + } + } } + if let returnType = signature.returnType { - words.append("->") - words.append(renderedExpression(returnType)) + writer.nextLineAppendsToLastLine() + writer.writeLine(" -> ") + writer.nextLineAppendsToLastLine() + renderExpression(returnType) } - return words.joinedWords() } /// Renders the specified function declaration. - func renderedFunction(_ functionDescription: FunctionDescription) -> String { - var lines: [String] = [] - var words: [String] = [ - renderedFunctionSignature(functionDescription.signature) - ] - if functionDescription.body != nil { - words.append("{") - } - lines.append(words.joinedWords()) - - if let body = functionDescription.body { - lines.append(contentsOf: body.map(renderedCodeBlock)) + func renderFunction(_ functionDescription: FunctionDescription) { + renderFunctionSignature(functionDescription.signature) + guard let body = functionDescription.body else { + return } - - if functionDescription.body != nil { - lines.append("}") + writer.nextLineAppendsToLastLine() + writer.writeLine(" {") + if !body.isEmpty { + writer.withNestedLevel { + renderCodeBlocks(body) + } + } else { + writer.nextLineAppendsToLastLine() } - return lines.joinedLines() + writer.writeLine("}") } /// Renders the specified parameter declaration. - func renderedParameter(_ parameterDescription: ParameterDescription) -> String { - var words: [String] = [] + func renderParameter(_ parameterDescription: ParameterDescription) { if let label = parameterDescription.label { - words.append(label) + writer.writeLine(label) } else { - words.append("_") + writer.writeLine("_") } - if let name = parameterDescription.name { - // If the label and name are the same value, don't repeat it, otherwise - // swift-format emits a warning. - if name != parameterDescription.label { - words.append(name) - } + writer.nextLineAppendsToLastLine() + if let name = parameterDescription.name, name != parameterDescription.label { + // If the label and name are the same value, don't repeat it. + writer.writeLine(" ") + writer.nextLineAppendsToLastLine() + writer.writeLine(name) + writer.nextLineAppendsToLastLine() } - words.append(":") - words.append(renderedExistingTypeDescription(parameterDescription.type)) + writer.writeLine(": ") + writer.nextLineAppendsToLastLine() + writer.writeLine(renderedExistingTypeDescription(parameterDescription.type)) if let defaultValue = parameterDescription.defaultValue { - words.append("=") - words.append(renderedExpression(defaultValue)) + writer.nextLineAppendsToLastLine() + writer.writeLine(" = ") + writer.nextLineAppendsToLastLine() + renderExpression(defaultValue) } - return words.joinedWords() } /// Renders the specified declaration with a comment. - func renderedCommentableDeclaration(comment: Comment?, declaration: Declaration) -> String { - return [ - comment.map(renderedComment), - renderedDeclaration(declaration), - ] - .compactMap({ $0 }).joinedLines() + func renderCommentableDeclaration(comment: Comment?, declaration: Declaration) { + if let comment { + renderComment(comment) + } + renderDeclaration(declaration) } /// Renders the specified declaration with a deprecation annotation. - func renderedDeprecatedDeclaration(deprecation: DeprecationDescription, declaration: Declaration) -> String { - return [ - renderedDeprecation(deprecation), - renderedDeclaration(declaration), - ] - .joinedLines() + func renderDeprecatedDeclaration(deprecation: DeprecationDescription, declaration: Declaration) { + renderDeprecation(deprecation) + renderDeclaration(declaration) } - func renderedDeprecation(_ deprecation: DeprecationDescription) -> String { + func renderDeprecation(_ deprecation: DeprecationDescription) { let things: [String] = [ "*", "deprecated", @@ -748,72 +986,51 @@ struct TextBasedRenderer: RendererProtocol { deprecation.renamed.map { "renamed: \"\($0)\"" }, ] .compactMap({ $0 }) - return "@available(\(things.joined(separator: ", ")))" + let line = "@available(\(things.joined(separator: ", ")))" + writer.writeLine(line) } /// Renders the specified code block item. - func renderedCodeBlockItem(_ description: CodeBlockItem) -> String { + func renderCodeBlockItem(_ description: CodeBlockItem) { switch description { case .declaration(let declaration): - return renderedDeclaration(declaration) + renderDeclaration(declaration) case .expression(let expression): - return renderedExpression(expression) + renderExpression(expression) } } /// Renders the specified code block. - func renderedCodeBlock(_ description: CodeBlock) -> String { - var lines: [String] = [] + func renderCodeBlock(_ description: CodeBlock) { if let comment = description.comment { - lines.append(contentsOf: renderedComment(comment).asLines()) + renderComment(comment) } let item = description.item - lines.append(contentsOf: renderedCodeBlockItem(item).asLines()) - return lines.joinedLines() + renderCodeBlockItem(item) } /// Renders the specified code blocks. - func renderedCodeBlocks(_ blocks: [CodeBlock]) -> String { - blocks.map(renderedCodeBlock).joinedLines() + func renderCodeBlocks(_ blocks: [CodeBlock]) { + blocks.forEach(renderCodeBlock) } +} - /// Renders the specified file. - func renderedFile(_ description: FileDescription) -> String { - var lines: [String] = [] - if let topComment = description.topComment { - lines.appendLines(from: renderedComment(topComment)) - } - if let imports = description.imports { - lines.appendLines(from: renderedImports(imports)) - } - let renderedCodeBlocks = description.codeBlocks.map(renderedCodeBlock) - for block in renderedCodeBlocks { - lines.append(block) - lines.append("") - } - return lines.joinedLines() +fileprivate extension Array { + + /// Returns a collection of tuples, where the first element is + /// the collection element and the second is a Boolean value indicating + /// whether it is the last element in the collection. + /// - Returns: A collection of tuples. + func enumeratedWithLastMarker() -> [(Element, isLast: Bool)] { + let count = count + return enumerated() + .map { index, element in + (element, index == count - 1) + } } } fileprivate extension Array where Element == String { - - /// Appends the lines from the specified string. - /// - Parameter string: The string whose lines to append. - mutating func appendLines(from string: String) { - append(contentsOf: string.asLines()) - } - - /// Returns a string where the elements of the array are - /// joined by a newline character, with optionally omitting - /// empty lines. - /// - Parameter omittingEmptyLines: If `true`, omits empty lines in the - /// output. Otherwise, all lines are included in the output. - /// - Returns: A string with the elements of the array joined by newline characters. - func joinedLines(omittingEmptyLines: Bool = true) -> String { - filter { !omittingEmptyLines || !$0.isEmpty } - .joined(separator: "\n") - } - /// Returns a string where the elements of the array are joined /// by a space character. /// - Returns: A string with the elements of the array joined by space characters. @@ -836,7 +1053,7 @@ fileprivate extension String { /// The closure takes a string representing one line as a parameter. /// - Parameter work: The closure that transforms each line. /// - Returns: A new string where each line has been transformed using the given closure. - func transformingLines(_ work: (String) -> String) -> String { - asLines().map(work).joinedLines() + func transformingLines(_ work: (String) -> String) -> [String] { + asLines().map(work) } } diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStructBlueprint.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStructBlueprint.swift index 30f22424..bdde2ee5 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStructBlueprint.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateStructBlueprint.swift @@ -187,7 +187,7 @@ fileprivate extension Array where Element == PropertyBlueprint { parameterComponents.append("- Parameters:") for parameter in self { parameterComponents.append( - " - \(parameter.swiftSafeName): \(parameter.comment?.firstLineOfContent ?? "")" + " - \(parameter.swiftSafeName):\(parameter.comment?.firstLineOfContent.map { " \($0)" } ?? "")" ) } components.append("") diff --git a/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift b/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift index e0c9d72b..ccf1ee72 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift @@ -16,8 +16,6 @@ import XCTest final class Test_TextBasedRenderer: XCTestCase { - var renderer = TextBasedRenderer() - func testComment() throws { try _test( .inline( @@ -27,7 +25,7 @@ final class Test_TextBasedRenderer: XCTestCase { Also, bar """# ), - renderedBy: renderer.renderedComment, + renderedBy: TextBasedRenderer.renderComment, rendersAs: #""" // Generated by foo @@ -43,7 +41,7 @@ final class Test_TextBasedRenderer: XCTestCase { Also, bar """# ), - renderedBy: renderer.renderedComment, + renderedBy: TextBasedRenderer.renderComment, rendersAs: #""" /// Generated by foo @@ -53,7 +51,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .mark("Lorem ipsum", sectionBreak: false), - renderedBy: renderer.renderedComment, + renderedBy: TextBasedRenderer.renderComment, rendersAs: #""" // MARK: Lorem ipsum @@ -61,7 +59,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .mark("Lorem ipsum", sectionBreak: true), - renderedBy: renderer.renderedComment, + renderedBy: TextBasedRenderer.renderComment, rendersAs: #""" // MARK: - Lorem ipsum @@ -73,7 +71,7 @@ final class Test_TextBasedRenderer: XCTestCase { Generated by foo\r\nAlso, bar """ ), - renderedBy: renderer.renderedComment, + renderedBy: TextBasedRenderer.renderComment, rendersAs: #""" // Generated by foo @@ -85,7 +83,7 @@ final class Test_TextBasedRenderer: XCTestCase { func testImports() throws { try _test( nil, - renderedBy: renderer.renderedImports, + renderedBy: TextBasedRenderer.renderImports, rendersAs: "" ) @@ -94,7 +92,7 @@ final class Test_TextBasedRenderer: XCTestCase { ImportDescription(moduleName: "Foo"), ImportDescription(moduleName: "Bar"), ], - renderedBy: renderer.renderedImports, + renderedBy: TextBasedRenderer.renderImports, rendersAs: #""" import Foo @@ -105,7 +103,7 @@ final class Test_TextBasedRenderer: XCTestCase { [ ImportDescription(moduleName: "Foo", spi: "Secret") ], - renderedBy: renderer.renderedImports, + renderedBy: TextBasedRenderer.renderImports, rendersAs: #""" @_spi(Secret) import Foo @@ -115,7 +113,7 @@ final class Test_TextBasedRenderer: XCTestCase { [ ImportDescription(moduleName: "Foo", preconcurrency: .onOS(["Bar", "Baz"])) ], - renderedBy: renderer.renderedImports, + renderedBy: TextBasedRenderer.renderImports, rendersAs: #""" #if os(Bar) || os(Baz) @@ -130,7 +128,7 @@ final class Test_TextBasedRenderer: XCTestCase { ImportDescription(moduleName: "Foo", preconcurrency: .always), ImportDescription(moduleName: "Bar", spi: "Secret", preconcurrency: .always), ], - renderedBy: renderer.renderedImports, + renderedBy: TextBasedRenderer.renderImports, rendersAs: #""" @preconcurrency import Foo @@ -142,46 +140,42 @@ final class Test_TextBasedRenderer: XCTestCase { func testAccessModifiers() throws { try _test( .public, - renderedBy: renderer.renderedAccessModifier, + renderedBy: TextBasedRenderer.renderedAccessModifier, rendersAs: #""" public - """#, - normalizing: false + """# ) try _test( .internal, - renderedBy: renderer.renderedAccessModifier, + renderedBy: TextBasedRenderer.renderedAccessModifier, rendersAs: #""" internal - """#, - normalizing: false + """# ) try _test( .fileprivate, - renderedBy: renderer.renderedAccessModifier, + renderedBy: TextBasedRenderer.renderedAccessModifier, rendersAs: #""" fileprivate - """#, - normalizing: false + """# ) try _test( .private, - renderedBy: renderer.renderedAccessModifier, + renderedBy: TextBasedRenderer.renderedAccessModifier, rendersAs: #""" private - """#, - normalizing: false + """# ) } func testLiterals() throws { try _test( .string("hi"), - renderedBy: renderer.renderedLiteral, + renderedBy: TextBasedRenderer.renderLiteral, rendersAs: #""" "hi" @@ -189,7 +183,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .string("this string: \"foo\""), - renderedBy: renderer.renderedLiteral, + renderedBy: TextBasedRenderer.renderLiteral, rendersAs: #""" #"this string: "foo""# @@ -197,7 +191,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .nil, - renderedBy: renderer.renderedLiteral, + renderedBy: TextBasedRenderer.renderLiteral, rendersAs: #""" nil @@ -205,7 +199,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .array([]), - renderedBy: renderer.renderedLiteral, + renderedBy: TextBasedRenderer.renderLiteral, rendersAs: #""" [] @@ -215,7 +209,7 @@ final class Test_TextBasedRenderer: XCTestCase { .array([ .literal(.nil) ]), - renderedBy: renderer.renderedLiteral, + renderedBy: TextBasedRenderer.renderLiteral, rendersAs: #""" [nil] @@ -226,7 +220,7 @@ final class Test_TextBasedRenderer: XCTestCase { .literal(.nil), .literal(.nil), ]), - renderedBy: renderer.renderedLiteral, + renderedBy: TextBasedRenderer.renderLiteral, rendersAs: #""" [nil, nil] @@ -237,7 +231,7 @@ final class Test_TextBasedRenderer: XCTestCase { func testExpression() throws { try _test( .literal(.nil), - renderedBy: renderer.renderedExpression, + renderedBy: TextBasedRenderer.renderExpression, rendersAs: #""" nil @@ -245,7 +239,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .identifierPattern("foo"), - renderedBy: renderer.renderedExpression, + renderedBy: TextBasedRenderer.renderExpression, rendersAs: #""" foo @@ -258,7 +252,7 @@ final class Test_TextBasedRenderer: XCTestCase { right: "bar" ) ), - renderedBy: renderer.renderedExpression, + renderedBy: TextBasedRenderer.renderExpression, rendersAs: #""" foo.bar @@ -276,7 +270,7 @@ final class Test_TextBasedRenderer: XCTestCase { ] ) ), - renderedBy: renderer.renderedExpression, + renderedBy: TextBasedRenderer.renderExpression, rendersAs: #""" callee(foo) @@ -287,7 +281,7 @@ final class Test_TextBasedRenderer: XCTestCase { func testDeclaration() throws { try _test( .variable(.init(kind: .let, left: "foo")), - renderedBy: renderer.renderedDeclaration, + renderedBy: TextBasedRenderer.renderDeclaration, rendersAs: #""" let foo @@ -300,7 +294,7 @@ final class Test_TextBasedRenderer: XCTestCase { declarations: [] ) ), - renderedBy: renderer.renderedDeclaration, + renderedBy: TextBasedRenderer.renderDeclaration, rendersAs: #""" extension String { @@ -309,23 +303,23 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .struct(.init(name: "Foo")), - renderedBy: renderer.renderedDeclaration, + renderedBy: TextBasedRenderer.renderDeclaration, rendersAs: #""" - struct Foo { } + struct Foo {} """# ) try _test( .protocol(.init(name: "Foo")), - renderedBy: renderer.renderedDeclaration, + renderedBy: TextBasedRenderer.renderDeclaration, rendersAs: #""" - protocol Foo { } + protocol Foo {} """# ) try _test( .enum(.init(name: "Foo")), - renderedBy: renderer.renderedDeclaration, + renderedBy: TextBasedRenderer.renderDeclaration, rendersAs: #""" enum Foo {} @@ -333,7 +327,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .typealias(.init(name: "foo", existingType: .member(["Foo", "Bar"]))), - renderedBy: renderer.renderedDeclaration, + renderedBy: TextBasedRenderer.renderDeclaration, rendersAs: #""" typealias foo = Foo.Bar @@ -346,7 +340,7 @@ final class Test_TextBasedRenderer: XCTestCase { body: [] ) ), - renderedBy: renderer.renderedDeclaration, + renderedBy: TextBasedRenderer.renderDeclaration, rendersAs: #""" func foo() {} @@ -357,51 +351,46 @@ final class Test_TextBasedRenderer: XCTestCase { func testFunctionKind() throws { try _test( .initializer, - renderedBy: renderer.renderedFunctionKind, + renderedBy: TextBasedRenderer.renderedFunctionKind, rendersAs: #""" init - """#, - normalizing: false + """# ) try _test( .function(name: "funky"), - renderedBy: renderer.renderedFunctionKind, + renderedBy: TextBasedRenderer.renderedFunctionKind, rendersAs: #""" func funky - """#, - normalizing: false + """# ) try _test( .function(name: "funky", isStatic: true), - renderedBy: renderer.renderedFunctionKind, + renderedBy: TextBasedRenderer.renderedFunctionKind, rendersAs: #""" static func funky - """#, - normalizing: false + """# ) } func testFunctionKeyword() throws { try _test( .throws, - renderedBy: renderer.renderedFunctionKeyword, + renderedBy: TextBasedRenderer.renderedFunctionKeyword, rendersAs: #""" throws - """#, - normalizing: false + """# ) try _test( .async, - renderedBy: renderer.renderedFunctionKeyword, + renderedBy: TextBasedRenderer.renderedFunctionKeyword, rendersAs: #""" async - """#, - normalizing: false + """# ) } @@ -413,12 +402,11 @@ final class Test_TextBasedRenderer: XCTestCase { type: .member("T"), defaultValue: .literal(.nil) ), - renderedBy: renderer.renderedParameter, + renderedBy: TextBasedRenderer.renderParameter, rendersAs: #""" - l n : T = nil - """#, - normalizing: false + l n: T = nil + """# ) try _test( .init( @@ -427,12 +415,11 @@ final class Test_TextBasedRenderer: XCTestCase { type: .member("T"), defaultValue: .literal(.nil) ), - renderedBy: renderer.renderedParameter, + renderedBy: TextBasedRenderer.renderParameter, rendersAs: #""" - _ n : T = nil - """#, - normalizing: false + _ n: T = nil + """# ) try _test( .init( @@ -441,12 +428,11 @@ final class Test_TextBasedRenderer: XCTestCase { type: .member("T"), defaultValue: .literal(.nil) ), - renderedBy: renderer.renderedParameter, + renderedBy: TextBasedRenderer.renderParameter, rendersAs: #""" - l : T = nil - """#, - normalizing: false + l: T = nil + """# ) try _test( .init( @@ -455,12 +441,11 @@ final class Test_TextBasedRenderer: XCTestCase { type: .member("T"), defaultValue: .literal(.nil) ), - renderedBy: renderer.renderedParameter, + renderedBy: TextBasedRenderer.renderParameter, rendersAs: #""" - _ : T = nil - """#, - normalizing: false + _: T = nil + """# ) try _test( .init( @@ -469,12 +454,11 @@ final class Test_TextBasedRenderer: XCTestCase { type: .member("T"), defaultValue: nil ), - renderedBy: renderer.renderedParameter, + renderedBy: TextBasedRenderer.renderParameter, rendersAs: #""" - _ : T - """#, - normalizing: false + _: T + """# ) } @@ -486,10 +470,10 @@ final class Test_TextBasedRenderer: XCTestCase { parameters: [], body: [] ), - renderedBy: renderer.renderedFunction, + renderedBy: TextBasedRenderer.renderFunction, rendersAs: #""" - public func f() { } + public func f() {} """# ) try _test( @@ -506,10 +490,10 @@ final class Test_TextBasedRenderer: XCTestCase { ], body: [] ), - renderedBy: renderer.renderedFunction, + renderedBy: TextBasedRenderer.renderFunction, rendersAs: #""" - public func f(a b: C) { } + public func f(a b: C) {} """# ) try _test( @@ -532,10 +516,13 @@ final class Test_TextBasedRenderer: XCTestCase { ], body: [] ), - renderedBy: renderer.renderedFunction, + renderedBy: TextBasedRenderer.renderFunction, rendersAs: #""" - public func f(a b: C, _ d: E = "f") { } + public func f( + a b: C, + _ d: E = "f" + ) {} """# ) try _test( @@ -545,7 +532,7 @@ final class Test_TextBasedRenderer: XCTestCase { keywords: [.async, .throws], returnType: .identifierType(TypeName.string) ), - renderedBy: renderer.renderedFunction, + renderedBy: TextBasedRenderer.renderFunction, rendersAs: #""" func f() async throws -> Swift.String @@ -556,7 +543,7 @@ final class Test_TextBasedRenderer: XCTestCase { func testIdentifiers() throws { try _test( .pattern("foo"), - renderedBy: renderer.renderedIdentifier, + renderedBy: TextBasedRenderer.renderedIdentifier, rendersAs: #""" foo @@ -567,7 +554,7 @@ final class Test_TextBasedRenderer: XCTestCase { func testMemberAccess() throws { try _test( .init(left: .identifierPattern("foo"), right: "bar"), - renderedBy: renderer.renderedMemberAccess, + renderedBy: TextBasedRenderer.renderMemberAccess, rendersAs: #""" foo.bar @@ -575,7 +562,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .init(left: nil, right: "bar"), - renderedBy: renderer.renderedMemberAccess, + renderedBy: TextBasedRenderer.renderMemberAccess, rendersAs: #""" .bar @@ -589,19 +576,18 @@ final class Test_TextBasedRenderer: XCTestCase { label: "foo", expression: .identifierPattern("bar") ), - renderedBy: renderer.renderedFunctionCallArgument, + renderedBy: TextBasedRenderer.renderFunctionCallArgument, rendersAs: #""" foo: bar - """#, - normalizing: false + """# ) try _test( .init( label: nil, expression: .identifierPattern("bar") ), - renderedBy: renderer.renderedFunctionCallArgument, + renderedBy: TextBasedRenderer.renderFunctionCallArgument, rendersAs: #""" bar @@ -616,7 +602,7 @@ final class Test_TextBasedRenderer: XCTestCase { calledExpression: .identifierPattern("callee") ) ), - renderedBy: renderer.renderedExpression, + renderedBy: TextBasedRenderer.renderExpression, rendersAs: #""" callee() @@ -634,7 +620,7 @@ final class Test_TextBasedRenderer: XCTestCase { ] ) ), - renderedBy: renderer.renderedExpression, + renderedBy: TextBasedRenderer.renderExpression, rendersAs: #""" callee(foo: bar) @@ -656,10 +642,13 @@ final class Test_TextBasedRenderer: XCTestCase { ] ) ), - renderedBy: renderer.renderedExpression, + renderedBy: TextBasedRenderer.renderExpression, rendersAs: #""" - callee(foo: bar, baz: boo) + callee( + foo: bar, + baz: boo + ) """# ) } @@ -675,11 +664,11 @@ final class Test_TextBasedRenderer: XCTestCase { ) ] ), - renderedBy: renderer.renderedExtension, + renderedBy: TextBasedRenderer.renderExtension, rendersAs: #""" public extension Info { - let foo: Int + let foo: Int } """# ) @@ -688,60 +677,54 @@ final class Test_TextBasedRenderer: XCTestCase { func testDeprecation() throws { try _test( .init(), - renderedBy: renderer.renderedDeprecation, + renderedBy: TextBasedRenderer.renderDeprecation, rendersAs: #""" @available(*, deprecated) - """#, - normalizing: false + """# ) try _test( .init(message: "some message"), - renderedBy: renderer.renderedDeprecation, + renderedBy: TextBasedRenderer.renderDeprecation, rendersAs: #""" @available(*, deprecated, message: "some message") - """#, - normalizing: false + """# ) try _test( .init(renamed: "newSymbol(param:)"), - renderedBy: renderer.renderedDeprecation, + renderedBy: TextBasedRenderer.renderDeprecation, rendersAs: #""" @available(*, deprecated, renamed: "newSymbol(param:)") - """#, - normalizing: false + """# ) try _test( .init(message: "some message", renamed: "newSymbol(param:)"), - renderedBy: renderer.renderedDeprecation, + renderedBy: TextBasedRenderer.renderDeprecation, rendersAs: #""" @available(*, deprecated, message: "some message", renamed: "newSymbol(param:)") - """#, - normalizing: false + """# ) } func testBindingKind() throws { try _test( .var, - renderedBy: renderer.renderedBindingKind, + renderedBy: TextBasedRenderer.renderedBindingKind, rendersAs: #""" var - """#, - normalizing: false + """# ) try _test( .let, - renderedBy: renderer.renderedBindingKind, + renderedBy: TextBasedRenderer.renderedBindingKind, rendersAs: #""" let - """#, - normalizing: false + """# ) } @@ -755,12 +738,11 @@ final class Test_TextBasedRenderer: XCTestCase { type: .init(TypeName.string), right: .literal(.string("bar")) ), - renderedBy: renderer.renderedVariable, + renderedBy: TextBasedRenderer.renderVariable, rendersAs: #""" public static let foo: Swift.String = "bar" - """#, - normalizing: false + """# ) try _test( .init( @@ -771,12 +753,11 @@ final class Test_TextBasedRenderer: XCTestCase { type: nil, right: nil ), - renderedBy: renderer.renderedVariable, + renderedBy: TextBasedRenderer.renderVariable, rendersAs: #""" internal var foo - """#, - normalizing: false + """# ) try _test( .init( @@ -785,12 +766,13 @@ final class Test_TextBasedRenderer: XCTestCase { type: .init(TypeName.int), getter: [CodeBlock.expression(.literal(.int(42)))] ), - renderedBy: renderer.renderedVariable, + renderedBy: TextBasedRenderer.renderVariable, rendersAs: #""" - var foo: Swift.Int { 42 } - """#, - normalizing: true + var foo: Swift.Int { + 42 + } + """# ) try _test( .init( @@ -800,12 +782,15 @@ final class Test_TextBasedRenderer: XCTestCase { getter: [CodeBlock.expression(.literal(.int(42)))], getterEffects: [.throws] ), - renderedBy: renderer.renderedVariable, + renderedBy: TextBasedRenderer.renderVariable, rendersAs: #""" - var foo: Swift.Int { get throws { 42 } } - """#, - normalizing: true + var foo: Swift.Int { + get throws { + 42 + } + } + """# ) } @@ -814,11 +799,10 @@ final class Test_TextBasedRenderer: XCTestCase { .init( name: "Structy" ), - renderedBy: renderer.renderedStruct, + renderedBy: TextBasedRenderer.renderStruct, rendersAs: #""" - struct Structy { - } + struct Structy {} """# ) } @@ -828,11 +812,10 @@ final class Test_TextBasedRenderer: XCTestCase { .init( name: "Protocoly" ), - renderedBy: renderer.renderedProtocol, + renderedBy: TextBasedRenderer.renderProtocol, rendersAs: #""" - protocol Protocoly { - } + protocol Protocoly {} """# ) } @@ -842,7 +825,7 @@ final class Test_TextBasedRenderer: XCTestCase { .init( name: "Enumy" ), - renderedBy: renderer.renderedEnum, + renderedBy: TextBasedRenderer.renderEnum, rendersAs: #""" enum Enumy {} @@ -860,7 +843,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) ) ), - renderedBy: renderer.renderedCodeBlockItem, + renderedBy: TextBasedRenderer.renderCodeBlockItem, rendersAs: #""" let foo @@ -868,7 +851,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) try _test( .expression(.literal(.nil)), - renderedBy: renderer.renderedCodeBlockItem, + renderedBy: TextBasedRenderer.renderCodeBlockItem, rendersAs: #""" nil @@ -889,7 +872,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) ) ), - renderedBy: renderer.renderedCodeBlock, + renderedBy: TextBasedRenderer.renderCodeBlock, rendersAs: #""" // - MARK: Section @@ -908,7 +891,7 @@ final class Test_TextBasedRenderer: XCTestCase { ) ) ), - renderedBy: renderer.renderedCodeBlock, + renderedBy: TextBasedRenderer.renderCodeBlock, rendersAs: #""" let foo @@ -922,7 +905,7 @@ final class Test_TextBasedRenderer: XCTestCase { name: "inty", existingType: .member("Int") ), - renderedBy: renderer.renderedTypealias, + renderedBy: TextBasedRenderer.renderTypealias, rendersAs: #""" typealias inty = Int @@ -934,7 +917,7 @@ final class Test_TextBasedRenderer: XCTestCase { name: "inty", existingType: .member("Int") ), - renderedBy: renderer.renderedTypealias, + renderedBy: TextBasedRenderer.renderTypealias, rendersAs: #""" private typealias inty = Int @@ -952,46 +935,59 @@ final class Test_TextBasedRenderer: XCTestCase { codeBlocks: [ .init( comment: nil, - item: .expression( - .literal(.nil) + item: .declaration( + .struct(.init(name: "Bar")) ) ) ] ), - renderedBy: renderer.renderedFile, + renderedBy: TextBasedRenderer.renderFile, rendersAs: #""" // hi import Foo - nil + struct Bar {} + """# ) } } extension Test_TextBasedRenderer { + func _test( _ input: Input, - renderedBy renderer: (Input) -> String, + renderedBy renderClosure: (TextBasedRenderer) -> ((Input) -> String), rendersAs output: String, - normalizing: Bool = true, file: StaticString = #file, line: UInt = #line ) throws { - if normalizing { - XCTAssertEqual( - try renderer(input).swiftFormatted, - try output.swiftFormatted, - file: file, - line: line - ) - } else { - XCTAssertEqual( - renderer(input), - output, - file: file, - line: line - ) - } + let renderer = TextBasedRenderer.default + XCTAssertEqual( + renderClosure(renderer)(input), + output, + file: file, + line: line + ) + } + + func _test( + _ input: Input, + renderedBy renderClosure: (TextBasedRenderer) -> ((Input) -> Void), + rendersAs output: String, + file: StaticString = #file, + line: UInt = #line + ) throws { + try _test( + input, + renderedBy: { renderer in + let closure = renderClosure(renderer) + return { input in + closure(input) + return renderer.renderedContents() + } + }, + rendersAs: output + ) } } diff --git a/Tests/OpenAPIGeneratorCoreTests/StructureHelpers.swift b/Tests/OpenAPIGeneratorCoreTests/StructureHelpers.swift index d7e524e7..9ba14a7f 100644 --- a/Tests/OpenAPIGeneratorCoreTests/StructureHelpers.swift +++ b/Tests/OpenAPIGeneratorCoreTests/StructureHelpers.swift @@ -203,7 +203,7 @@ extension Expression { case .pattern(let pattern): name = pattern case .type(let type): - name = TextBasedRenderer().renderedExistingTypeDescription(type) + name = TextBasedRenderer.default.renderedExistingTypeDescription(type) } return .init(name: name, kind: .identifier) case .memberAccess(let value): diff --git a/Tests/OpenAPIGeneratorReferenceTests/CompatabilityTest.swift b/Tests/OpenAPIGeneratorReferenceTests/CompatabilityTest.swift index d875bd0f..0349543e 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/CompatabilityTest.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/CompatabilityTest.swift @@ -231,7 +231,6 @@ fileprivate extension CompatibilityTest { for mode in GeneratorMode.allCases { group.addTask { let generator = makeGeneratorPipeline( - formatter: { $0 }, config: Config(mode: mode), diagnostics: diagnosticsCollector ) @@ -243,7 +242,6 @@ fileprivate extension CompatibilityTest { } else { outputs = try GeneratorMode.allCases.map { mode in let generator = makeGeneratorPipeline( - formatter: { $0 }, config: Config(mode: mode), diagnostics: diagnosticsCollector ) diff --git a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift index 12e2cee9..5c4ec586 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/FileBasedReferenceTests.swift @@ -47,11 +47,7 @@ class FileBasedReferenceTests: XCTestCase { } func testPetstore() throws { - #if canImport(SwiftSyntax509) try _test(referenceProject: .init(name: .petstore)) - #else - XCTFail("Update SwiftFormat to at least 509 to run this test.") - #endif } // MARK: - Private @@ -178,17 +174,12 @@ extension FileBasedReferenceTests { ) -> GeneratorPipeline { let parser = YamsParser() let translator = MultiplexTranslator() - let renderer = TextBasedRenderer() + let renderer = TextBasedRenderer.default return _OpenAPIGeneratorCore.makeGeneratorPipeline( parser: parser, translator: translator, renderer: renderer, - formatter: { file in - var newFile = file - newFile.contents = try newFile.contents.swiftFormatted - return newFile - }, config: config, diagnostics: XCTestDiagnosticCollector( test: self, @@ -276,9 +267,10 @@ extension FileBasedReferenceTests { let pipe = Pipe() process.standardOutput = pipe try process.run() + let stdoutData = try pipe.fileHandleForReading.readToEnd() process.waitUntilExit() let pipeData = try XCTUnwrap( - pipe.fileHandleForReading.readToEnd(), + stdoutData, """ No output from command: \(process.executableURL!.path) \(process.arguments!.joined(separator: " ")) diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift index f69cdc0e..1928b30c 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift @@ -37,7 +37,9 @@ public struct Client: APIProtocol { middlewares: middlewares ) } - private var converter: Converter { client.converter } + private var converter: Converter { + client.converter + } /// List all pets /// /// You can fetch @@ -50,8 +52,14 @@ public struct Client: APIProtocol { input: input, forOperation: Operations.listPets.id, serializer: { input in - let path = try converter.renderedPath(template: "/pets", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + let path = try converter.renderedPath( + template: "/pets", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) suppressMutabilityWarning(&request) try converter.setQueryItemAsURI( in: &request, @@ -86,7 +94,10 @@ public struct Client: APIProtocol { name: "since", value: input.query.since ) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) return (request, nil) }, deserializer: { response, responseBody in @@ -106,33 +117,45 @@ public struct Client: APIProtocol { ) let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.listPets.Output.Ok.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getResponseBodyAsJSON( Components.Schemas.Pets.self, from: responseBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } - return .ok(.init(headers: headers, body: body)) + return .ok(.init( + headers: headers, + body: body + )) default: let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.listPets.Output.Default.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getResponseBodyAsJSON( Components.Schemas._Error.self, from: responseBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } - return .`default`(statusCode: response.status.code, .init(body: body)) + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) } } ) @@ -146,15 +169,24 @@ public struct Client: APIProtocol { input: input, forOperation: Operations.createPet.id, serializer: { input in - let path = try converter.renderedPath(template: "/pets", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .post) + let path = try converter.renderedPath( + template: "/pets", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) suppressMutabilityWarning(&request) try converter.setHeaderFieldAsJSON( in: &request.headerFields, name: "X-Extra-Arguments", value: input.headers.X_hyphen_Extra_hyphen_Arguments ) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) let body: OpenAPIRuntime.HTTPBody? switch input.body { case let .json(value): @@ -169,50 +201,65 @@ public struct Client: APIProtocol { deserializer: { response, responseBody in switch response.status.code { case 201: - let headers: Operations.createPet.Output.Created.Headers = .init( - X_hyphen_Extra_hyphen_Arguments: try converter.getOptionalHeaderFieldAsJSON( - in: response.headerFields, - name: "X-Extra-Arguments", - as: Components.Schemas.CodeError.self - ) - ) + let headers: Operations.createPet.Output.Created.Headers = .init(X_hyphen_Extra_hyphen_Arguments: try converter.getOptionalHeaderFieldAsJSON( + in: response.headerFields, + name: "X-Extra-Arguments", + as: Components.Schemas.CodeError.self + )) let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.createPet.Output.Created.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getResponseBodyAsJSON( Components.Schemas.Pet.self, from: responseBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } - return .created(.init(headers: headers, body: body)) - case 400...499: - let headers: Components.Responses.ErrorBadRequest.Headers = .init( - X_hyphen_Reason: try converter.getOptionalHeaderFieldAsURI( - in: response.headerFields, - name: "X-Reason", - as: Swift.String.self - ) - ) + return .created(.init( + headers: headers, + body: body + )) + case 400 ... 499: + let headers: Components.Responses.ErrorBadRequest.Headers = .init(X_hyphen_Reason: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "X-Reason", + as: Swift.String.self + )) let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Components.Responses.ErrorBadRequest.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getResponseBodyAsJSON( Components.Responses.ErrorBadRequest.Body.jsonPayload.self, from: responseBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } - return .clientError(statusCode: response.status.code, .init(headers: headers, body: body)) - default: return .undocumented(statusCode: response.status.code, .init()) + return .clientError( + statusCode: response.status.code, + .init( + headers: headers, + body: body + ) + ) + default: + return .undocumented( + statusCode: response.status.code, + .init() + ) } } ) @@ -221,15 +268,19 @@ public struct Client: APIProtocol { /// /// - Remark: HTTP `POST /pets/create`. /// - Remark: Generated from `#/paths//pets/create/post(createPetWithForm)`. - public func createPetWithForm(_ input: Operations.createPetWithForm.Input) async throws - -> Operations.createPetWithForm.Output - { + public func createPetWithForm(_ input: Operations.createPetWithForm.Input) async throws -> Operations.createPetWithForm.Output { try await client.send( input: input, forOperation: Operations.createPetWithForm.id, serializer: { input in - let path = try converter.renderedPath(template: "/pets/create", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .post) + let path = try converter.renderedPath( + template: "/pets/create", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) suppressMutabilityWarning(&request) let body: OpenAPIRuntime.HTTPBody? switch input.body { @@ -244,8 +295,13 @@ public struct Client: APIProtocol { }, deserializer: { response, responseBody in switch response.status.code { - case 204: return .noContent(.init()) - default: return .undocumented(statusCode: response.status.code, .init()) + case 204: + return .noContent(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init() + ) } } ) @@ -257,10 +313,19 @@ public struct Client: APIProtocol { input: input, forOperation: Operations.getStats.id, serializer: { input in - let path = try converter.renderedPath(template: "/pets/stats", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + let path = try converter.renderedPath( + template: "/pets/stats", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) suppressMutabilityWarning(&request) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) return (request, nil) }, deserializer: { response, responseBody in @@ -268,19 +333,27 @@ public struct Client: APIProtocol { case 200: let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.getStats.Output.Ok.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getResponseBodyAsJSON( Components.Schemas.PetStats.self, from: responseBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) - } else if try converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") { + } else if try converter.isMatchingContentType( + received: contentType, + expectedRaw: "text/plain" + ) { body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, - transforming: { value in .plainText(value) } + transforming: { value in + .plainText(value) + } ) } else if try converter.isMatchingContentType( received: contentType, @@ -289,13 +362,19 @@ public struct Client: APIProtocol { body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, - transforming: { value in .binary(value) } + transforming: { value in + .binary(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } return .ok(.init(body: body)) - default: return .undocumented(statusCode: response.status.code, .init()) + default: + return .undocumented( + statusCode: response.status.code, + .init() + ) } } ) @@ -307,8 +386,14 @@ public struct Client: APIProtocol { input: input, forOperation: Operations.postStats.id, serializer: { input in - let path = try converter.renderedPath(template: "/pets/stats", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .post) + let path = try converter.renderedPath( + template: "/pets/stats", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) suppressMutabilityWarning(&request) let body: OpenAPIRuntime.HTTPBody? switch input.body { @@ -335,8 +420,13 @@ public struct Client: APIProtocol { }, deserializer: { response, responseBody in switch response.status.code { - case 202: return .accepted(.init()) - default: return .undocumented(statusCode: response.status.code, .init()) + case 202: + return .accepted(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init() + ) } } ) @@ -348,15 +438,26 @@ public struct Client: APIProtocol { input: input, forOperation: Operations.probe.id, serializer: { input in - let path = try converter.renderedPath(template: "/probe/", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .post) + let path = try converter.renderedPath( + template: "/probe/", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) suppressMutabilityWarning(&request) return (request, nil) }, deserializer: { response, responseBody in switch response.status.code { - case 204: return .noContent(.init()) - default: return .undocumented(statusCode: response.status.code, .init()) + case 204: + return .noContent(.init()) + default: + return .undocumented( + statusCode: response.status.code, + .init() + ) } } ) @@ -370,13 +471,23 @@ public struct Client: APIProtocol { input: input, forOperation: Operations.updatePet.id, serializer: { input in - let path = try converter.renderedPath(template: "/pets/{}", parameters: [input.path.petId]) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .patch) + let path = try converter.renderedPath( + template: "/pets/{}", + parameters: [input.path.petId] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .patch + ) suppressMutabilityWarning(&request) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case .none: body = nil + case .none: + body = nil case let .json(value): body = try converter.setOptionalRequestBodyAsJSON( value, @@ -388,23 +499,31 @@ public struct Client: APIProtocol { }, deserializer: { response, responseBody in switch response.status.code { - case 204: return .noContent(.init()) + case 204: + return .noContent(.init()) case 400: let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.updatePet.Output.BadRequest.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getResponseBodyAsJSON( Operations.updatePet.Output.BadRequest.Body.jsonPayload.self, from: responseBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } return .badRequest(.init(body: body)) - default: return .undocumented(statusCode: response.status.code, .init()) + default: + return .undocumented( + statusCode: response.status.code, + .init() + ) } } ) @@ -413,17 +532,24 @@ public struct Client: APIProtocol { /// /// - Remark: HTTP `PUT /pets/{petId}/avatar`. /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. - public func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws - -> Operations.uploadAvatarForPet.Output - { + public func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws -> Operations.uploadAvatarForPet.Output { try await client.send( input: input, forOperation: Operations.uploadAvatarForPet.id, serializer: { input in - let path = try converter.renderedPath(template: "/pets/{}/avatar", parameters: [input.path.petId]) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .put) + let path = try converter.renderedPath( + template: "/pets/{}/avatar", + parameters: [input.path.petId] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) suppressMutabilityWarning(&request) - converter.setAcceptHeader(in: &request.headerFields, contentTypes: input.headers.accept) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) let body: OpenAPIRuntime.HTTPBody? switch input.body { case let .binary(value): @@ -440,16 +566,16 @@ public struct Client: APIProtocol { case 200: let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.uploadAvatarForPet.Output.Ok.Body - if try contentType == nil - || converter.isMatchingContentType( - received: contentType, - expectedRaw: "application/octet-stream" - ) - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/octet-stream" + ) { body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, - transforming: { value in .binary(value) } + transforming: { value in + .binary(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -458,13 +584,16 @@ public struct Client: APIProtocol { case 412: let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.uploadAvatarForPet.Output.PreconditionFailed.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getResponseBodyAsJSON( Swift.String.self, from: responseBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -473,19 +602,26 @@ public struct Client: APIProtocol { case 500: let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.uploadAvatarForPet.Output.InternalServerError.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "text/plain" + ) { body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, - transforming: { value in .plainText(value) } + transforming: { value in + .plainText(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } return .internalServerError(.init(body: body)) - default: return .undocumented(statusCode: response.status.code, .init()) + default: + return .undocumented( + statusCode: response.status.code, + .init() + ) } } ) diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift index 599383ef..d33ed532 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift @@ -31,47 +31,96 @@ extension APIProtocol { middlewares: middlewares ) try transport.register( - { try await server.listPets(request: $0, body: $1, metadata: $2) }, + { + try await server.listPets( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .get, path: server.apiPathComponentsWithServerPrefix("/pets") ) try transport.register( - { try await server.createPet(request: $0, body: $1, metadata: $2) }, + { + try await server.createPet( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .post, path: server.apiPathComponentsWithServerPrefix("/pets") ) try transport.register( - { try await server.createPetWithForm(request: $0, body: $1, metadata: $2) }, + { + try await server.createPetWithForm( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .post, path: server.apiPathComponentsWithServerPrefix("/pets/create") ) try transport.register( - { try await server.getStats(request: $0, body: $1, metadata: $2) }, + { + try await server.getStats( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .get, path: server.apiPathComponentsWithServerPrefix("/pets/stats") ) try transport.register( - { try await server.postStats(request: $0, body: $1, metadata: $2) }, + { + try await server.postStats( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .post, path: server.apiPathComponentsWithServerPrefix("/pets/stats") ) try transport.register( - { try await server.probe(request: $0, body: $1, metadata: $2) }, + { + try await server.probe( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .post, path: server.apiPathComponentsWithServerPrefix("/probe/") ) try transport.register( - { try await server.updatePet(request: $0, body: $1, metadata: $2) }, + { + try await server.updatePet( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .patch, path: server.apiPathComponentsWithServerPrefix("/pets/{petId}") ) try transport.register( - { try await server.uploadAvatarForPet(request: $0, body: $1, metadata: $2) }, + { + try await server.uploadAvatarForPet( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .put, path: server.apiPathComponentsWithServerPrefix("/pets/{petId}/avatar") ) } } + fileprivate extension UniversalServer where APIHandler: APIProtocol { /// List all pets /// @@ -90,7 +139,9 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.listPets.id, - using: { APIHandler.listPets($0) }, + using: { + APIHandler.listPets($0) + }, deserializer: { request, requestBody, metadata in let query: Operations.listPets.Input.Query = .init( limit: try converter.getOptionalQueryItemAsURI( @@ -130,7 +181,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { ), accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) ) - return Operations.listPets.Input(query: query, headers: headers) + return Operations.listPets.Input( + query: query, + headers: headers + ) }, serializer: { output, request in switch output { @@ -151,7 +205,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) body = try converter.setResponseBodyAsJSON( value, headerFields: &response.headerFields, @@ -166,7 +223,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) body = try converter.setResponseBodyAsJSON( value, headerFields: &response.headerFields, @@ -192,7 +252,9 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.createPet.id, - using: { APIHandler.createPet($0) }, + using: { + APIHandler.createPet($0) + }, deserializer: { request, requestBody, metadata in let headers: Operations.createPet.Input.Headers = .init( X_hyphen_Extra_hyphen_Arguments: try converter.getOptionalHeaderFieldAsJSON( @@ -204,18 +266,24 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { ) let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.createPet.Input.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getRequiredRequestBodyAsJSON( Components.Schemas.CreatePetRequest.self, from: requestBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } - return Operations.createPet.Input(headers: headers, body: body) + return Operations.createPet.Input( + headers: headers, + body: body + ) }, serializer: { output, request in switch output { @@ -231,7 +299,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) body = try converter.setResponseBodyAsJSON( value, headerFields: &response.headerFields, @@ -251,7 +322,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) body = try converter.setResponseBodyAsJSON( value, headerFields: &response.headerFields, @@ -259,7 +333,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { ) } return (response, body) - case let .undocumented(statusCode, _): return (.init(soar_statusCode: statusCode), nil) + case let .undocumented(statusCode, _): + return (.init(soar_statusCode: statusCode), nil) } } ) @@ -278,20 +353,22 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.createPetWithForm.id, - using: { APIHandler.createPetWithForm($0) }, + using: { + APIHandler.createPetWithForm($0) + }, deserializer: { request, requestBody, metadata in let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.createPetWithForm.Input.Body - if try contentType == nil - || converter.isMatchingContentType( - received: contentType, - expectedRaw: "application/x-www-form-urlencoded" - ) - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/x-www-form-urlencoded" + ) { body = try await converter.getRequiredRequestBodyAsURLEncodedForm( Components.Schemas.CreatePetRequest.self, from: requestBody, - transforming: { value in .urlEncodedForm(value) } + transforming: { value in + .urlEncodedForm(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -305,7 +382,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { var response = HTTPTypes.HTTPResponse(soar_statusCode: 204) suppressMutabilityWarning(&response) return (response, nil) - case let .undocumented(statusCode, _): return (.init(soar_statusCode: statusCode), nil) + case let .undocumented(statusCode, _): + return (.init(soar_statusCode: statusCode), nil) } } ) @@ -322,11 +400,11 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.getStats.id, - using: { APIHandler.getStats($0) }, + using: { + APIHandler.getStats($0) + }, deserializer: { request, requestBody, metadata in - let headers: Operations.getStats.Input.Headers = .init( - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) + let headers: Operations.getStats.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) return Operations.getStats.Input(headers: headers) }, serializer: { output, request in @@ -338,21 +416,30 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) body = try converter.setResponseBodyAsJSON( value, headerFields: &response.headerFields, contentType: "application/json; charset=utf-8" ) case let .plainText(value): - try converter.validateAcceptIfPresent("text/plain", in: request.headerFields) + try converter.validateAcceptIfPresent( + "text/plain", + in: request.headerFields + ) body = try converter.setResponseBodyAsBinary( value, headerFields: &response.headerFields, contentType: "text/plain" ) case let .binary(value): - try converter.validateAcceptIfPresent("application/octet-stream", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/octet-stream", + in: request.headerFields + ) body = try converter.setResponseBodyAsBinary( value, headerFields: &response.headerFields, @@ -360,7 +447,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { ) } return (response, body) - case let .undocumented(statusCode, _): return (.init(soar_statusCode: statusCode), nil) + case let .undocumented(statusCode, _): + return (.init(soar_statusCode: statusCode), nil) } } ) @@ -377,23 +465,33 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.postStats.id, - using: { APIHandler.postStats($0) }, + using: { + APIHandler.postStats($0) + }, deserializer: { request, requestBody, metadata in let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.postStats.Input.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getRequiredRequestBodyAsJSON( Components.Schemas.PetStats.self, from: requestBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) - } else if try converter.isMatchingContentType(received: contentType, expectedRaw: "text/plain") { + } else if try converter.isMatchingContentType( + received: contentType, + expectedRaw: "text/plain" + ) { body = try converter.getRequiredRequestBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: requestBody, - transforming: { value in .plainText(value) } + transforming: { value in + .plainText(value) + } ) } else if try converter.isMatchingContentType( received: contentType, @@ -402,7 +500,9 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { body = try converter.getRequiredRequestBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: requestBody, - transforming: { value in .binary(value) } + transforming: { value in + .binary(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -416,7 +516,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { var response = HTTPTypes.HTTPResponse(soar_statusCode: 202) suppressMutabilityWarning(&response) return (response, nil) - case let .undocumented(statusCode, _): return (.init(soar_statusCode: statusCode), nil) + case let .undocumented(statusCode, _): + return (.init(soar_statusCode: statusCode), nil) } } ) @@ -433,8 +534,12 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.probe.id, - using: { APIHandler.probe($0) }, - deserializer: { request, requestBody, metadata in return Operations.probe.Input() }, + using: { + APIHandler.probe($0) + }, + deserializer: { request, requestBody, metadata in + return Operations.probe.Input() + }, serializer: { output, request in switch output { case let .noContent(value): @@ -442,7 +547,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { var response = HTTPTypes.HTTPResponse(soar_statusCode: 204) suppressMutabilityWarning(&response) return (response, nil) - case let .undocumented(statusCode, _): return (.init(soar_statusCode: statusCode), nil) + case let .undocumented(statusCode, _): + return (.init(soar_statusCode: statusCode), nil) } } ) @@ -461,32 +567,37 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.updatePet.id, - using: { APIHandler.updatePet($0) }, + using: { + APIHandler.updatePet($0) + }, deserializer: { request, requestBody, metadata in - let path: Operations.updatePet.Input.Path = .init( - petId: try converter.getPathParameterAsURI( - in: metadata.pathParameters, - name: "petId", - as: Swift.Int64.self - ) - ) - let headers: Operations.updatePet.Input.Headers = .init( - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) + let path: Operations.updatePet.Input.Path = .init(petId: try converter.getPathParameterAsURI( + in: metadata.pathParameters, + name: "petId", + as: Swift.Int64.self + )) + let headers: Operations.updatePet.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Components.RequestBodies.UpdatePetRequest? - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getOptionalRequestBodyAsJSON( Components.RequestBodies.UpdatePetRequest.jsonPayload.self, from: requestBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } - return Operations.updatePet.Input(path: path, headers: headers, body: body) + return Operations.updatePet.Input( + path: path, + headers: headers, + body: body + ) }, serializer: { output, request in switch output { @@ -502,7 +613,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) body = try converter.setResponseBodyAsJSON( value, headerFields: &response.headerFields, @@ -510,7 +624,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { ) } return (response, body) - case let .undocumented(statusCode, _): return (.init(soar_statusCode: statusCode), nil) + case let .undocumented(statusCode, _): + return (.init(soar_statusCode: statusCode), nil) } } ) @@ -529,32 +644,37 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { requestBody: body, metadata: metadata, forOperation: Operations.uploadAvatarForPet.id, - using: { APIHandler.uploadAvatarForPet($0) }, + using: { + APIHandler.uploadAvatarForPet($0) + }, deserializer: { request, requestBody, metadata in - let path: Operations.uploadAvatarForPet.Input.Path = .init( - petId: try converter.getPathParameterAsURI( - in: metadata.pathParameters, - name: "petId", - as: Components.Parameters.path_period_petId.self - ) - ) - let headers: Operations.uploadAvatarForPet.Input.Headers = .init( - accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields) - ) + let path: Operations.uploadAvatarForPet.Input.Path = .init(petId: try converter.getPathParameterAsURI( + in: metadata.pathParameters, + name: "petId", + as: Components.Parameters.path_period_petId.self + )) + let headers: Operations.uploadAvatarForPet.Input.Headers = .init(accept: try converter.extractAcceptHeaderIfPresent(in: request.headerFields)) let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.uploadAvatarForPet.Input.Body - if try contentType == nil - || converter.isMatchingContentType(received: contentType, expectedRaw: "application/octet-stream") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/octet-stream" + ) { body = try converter.getRequiredRequestBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: requestBody, - transforming: { value in .binary(value) } + transforming: { value in + .binary(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) } - return Operations.uploadAvatarForPet.Input(path: path, headers: headers, body: body) + return Operations.uploadAvatarForPet.Input( + path: path, + headers: headers, + body: body + ) }, serializer: { output, request in switch output { @@ -565,7 +685,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .binary(value): - try converter.validateAcceptIfPresent("application/octet-stream", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/octet-stream", + in: request.headerFields + ) body = try converter.setResponseBodyAsBinary( value, headerFields: &response.headerFields, @@ -580,7 +703,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .json(value): - try converter.validateAcceptIfPresent("application/json", in: request.headerFields) + try converter.validateAcceptIfPresent( + "application/json", + in: request.headerFields + ) body = try converter.setResponseBodyAsJSON( value, headerFields: &response.headerFields, @@ -595,7 +721,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { let body: OpenAPIRuntime.HTTPBody switch value.body { case let .plainText(value): - try converter.validateAcceptIfPresent("text/plain", in: request.headerFields) + try converter.validateAcceptIfPresent( + "text/plain", + in: request.headerFields + ) body = try converter.setResponseBodyAsBinary( value, headerFields: &response.headerFields, @@ -603,7 +732,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { ) } return (response, body) - case let .undocumented(statusCode, _): return (.init(soar_statusCode: statusCode), nil) + case let .undocumented(statusCode, _): + return (.init(soar_statusCode: statusCode), nil) } } ) diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift index caa9fbb2..dabd6078 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift @@ -28,8 +28,7 @@ public protocol APIProtocol: Sendable { /// /// - Remark: HTTP `POST /pets/create`. /// - Remark: Generated from `#/paths//pets/create/post(createPetWithForm)`. - func createPetWithForm(_ input: Operations.createPetWithForm.Input) async throws - -> Operations.createPetWithForm.Output + func createPetWithForm(_ input: Operations.createPetWithForm.Input) async throws -> Operations.createPetWithForm.Output /// - Remark: HTTP `GET /pets/stats`. /// - Remark: Generated from `#/paths//pets/stats/get(getStats)`. func getStats(_ input: Operations.getStats.Input) async throws -> Operations.getStats.Output @@ -48,9 +47,9 @@ public protocol APIProtocol: Sendable { /// /// - Remark: HTTP `PUT /pets/{petId}/avatar`. /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. - func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws - -> Operations.uploadAvatarForPet.Output + func uploadAvatarForPet(_ input: Operations.uploadAvatarForPet.Input) async throws -> Operations.uploadAvatarForPet.Output } + /// Convenience overloads for operation inputs. extension APIProtocol { /// List all pets @@ -64,27 +63,36 @@ extension APIProtocol { query: Operations.listPets.Input.Query = .init(), headers: Operations.listPets.Input.Headers = .init() ) async throws -> Operations.listPets.Output { - try await listPets(Operations.listPets.Input(query: query, headers: headers)) + try await listPets(Operations.listPets.Input( + query: query, + headers: headers + )) } /// Create a pet /// /// - Remark: HTTP `POST /pets`. /// - Remark: Generated from `#/paths//pets/post(createPet)`. - public func createPet(headers: Operations.createPet.Input.Headers = .init(), body: Operations.createPet.Input.Body) - async throws -> Operations.createPet.Output - { try await createPet(Operations.createPet.Input(headers: headers, body: body)) } + public func createPet( + headers: Operations.createPet.Input.Headers = .init(), + body: Operations.createPet.Input.Body + ) async throws -> Operations.createPet.Output { + try await createPet(Operations.createPet.Input( + headers: headers, + body: body + )) + } /// Create a pet using a url form /// /// - Remark: HTTP `POST /pets/create`. /// - Remark: Generated from `#/paths//pets/create/post(createPetWithForm)`. - public func createPetWithForm(body: Operations.createPetWithForm.Input.Body) async throws - -> Operations.createPetWithForm.Output - { try await createPetWithForm(Operations.createPetWithForm.Input(body: body)) } + public func createPetWithForm(body: Operations.createPetWithForm.Input.Body) async throws -> Operations.createPetWithForm.Output { + try await createPetWithForm(Operations.createPetWithForm.Input(body: body)) + } /// - Remark: HTTP `GET /pets/stats`. /// - Remark: Generated from `#/paths//pets/stats/get(getStats)`. - public func getStats(headers: Operations.getStats.Input.Headers = .init()) async throws - -> Operations.getStats.Output - { try await getStats(Operations.getStats.Input(headers: headers)) } + public func getStats(headers: Operations.getStats.Input.Headers = .init()) async throws -> Operations.getStats.Output { + try await getStats(Operations.getStats.Input(headers: headers)) + } /// - Remark: HTTP `POST /pets/stats`. /// - Remark: Generated from `#/paths//pets/stats/post(postStats)`. public func postStats(body: Operations.postStats.Input.Body) async throws -> Operations.postStats.Output { @@ -92,7 +100,9 @@ extension APIProtocol { } /// - Remark: HTTP `POST /probe/`. /// - Remark: Generated from `#/paths//probe//post(probe)`. - public func probe() async throws -> Operations.probe.Output { try await probe(Operations.probe.Input()) } + public func probe() async throws -> Operations.probe.Output { + try await probe(Operations.probe.Input()) + } /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. /// /// - Remark: HTTP `PATCH /pets/{petId}`. @@ -102,7 +112,11 @@ extension APIProtocol { headers: Operations.updatePet.Input.Headers = .init(), body: Components.RequestBodies.UpdatePetRequest? = nil ) async throws -> Operations.updatePet.Output { - try await updatePet(Operations.updatePet.Input(path: path, headers: headers, body: body)) + try await updatePet(Operations.updatePet.Input( + path: path, + headers: headers, + body: body + )) } /// Upload an avatar /// @@ -113,17 +127,25 @@ extension APIProtocol { headers: Operations.uploadAvatarForPet.Input.Headers = .init(), body: Operations.uploadAvatarForPet.Input.Body ) async throws -> Operations.uploadAvatarForPet.Output { - try await uploadAvatarForPet(Operations.uploadAvatarForPet.Input(path: path, headers: headers, body: body)) + try await uploadAvatarForPet(Operations.uploadAvatarForPet.Input( + path: path, + headers: headers, + body: body + )) } } + /// Server URLs defined in the OpenAPI document. public enum Servers { /// Example Petstore implementation service public static func server1() throws -> Foundation.URL { try Foundation.URL(validatingOpenAPIServerURL: "https://example.com/api") } - public static func server2() throws -> Foundation.URL { try Foundation.URL(validatingOpenAPIServerURL: "/api") } + public static func server2() throws -> Foundation.URL { + try Foundation.URL(validatingOpenAPIServerURL: "/api") + } } + /// Types generated from the components section of the OpenAPI document. public enum Components { /// Types generated from the `#/components/schemas` section of the OpenAPI document. @@ -242,13 +264,19 @@ public enum Components { self = .Pet(try .init(from: decoder)) return } catch {} - throw Swift.DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath + ) } public func encode(to encoder: any Encoder) throws { switch self { - case let .case1(value): try encoder.encodeToSingleValueContainer(value) - case let .PetKind(value): try encoder.encodeToSingleValueContainer(value) - case let .Pet(value): try value.encode(to: encoder) + case let .case1(value): + try encoder.encodeToSingleValueContainer(value) + case let .PetKind(value): + try encoder.encodeToSingleValueContainer(value) + case let .Pet(value): + try value.encode(to: encoder) } } } @@ -263,7 +291,10 @@ public enum Components { /// - Parameters: /// - value1: /// - value2: - public init(value1: Foundation.Date, value2: Swift.String) { + public init( + value1: Foundation.Date, + value2: Swift.String + ) { self.value1 = value1 self.value2 = value2 } @@ -271,7 +302,9 @@ public enum Components { value1 = try decoder.decodeFromSingleValueContainer() value2 = try decoder.decodeFromSingleValueContainer() } - public func encode(to encoder: any Encoder) throws { try encoder.encodeToSingleValueContainer(value1) } + public func encode(to encoder: any Encoder) throws { + try encoder.encodeToSingleValueContainer(value1) + } } /// Kind of pet /// @@ -374,8 +407,12 @@ public enum Components { /// /// - Parameters: /// - schedule: - public init(schedule: Components.Schemas.PetFeeding.schedulePayload? = nil) { self.schedule = schedule } - public enum CodingKeys: String, CodingKey { case schedule } + public init(schedule: Components.Schemas.PetFeeding.schedulePayload? = nil) { + self.schedule = schedule + } + public enum CodingKeys: String, CodingKey { + case schedule + } } /// - Remark: Generated from `#/components/schemas/DOB`. public typealias DOB = Foundation.Date @@ -389,11 +426,18 @@ public enum Components { /// /// - Parameters: /// - foo: - public init(foo: Swift.String? = nil) { self.foo = foo } - public enum CodingKeys: String, CodingKey { case foo } + public init(foo: Swift.String? = nil) { + self.foo = foo + } + public enum CodingKeys: String, CodingKey { + case foo + } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - foo = try container.decodeIfPresent(Swift.String.self, forKey: .foo) + foo = try container.decodeIfPresent( + Swift.String.self, + forKey: .foo + ) try decoder.ensureNoAdditionalProperties(knownKeys: ["foo"]) } } @@ -408,20 +452,30 @@ public enum Components { /// - Parameters: /// - foo: /// - additionalProperties: A container of undocumented properties. - public init(foo: Swift.String? = nil, additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer = .init()) - { + public init( + foo: Swift.String? = nil, + additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer = .init() + ) { self.foo = foo self.additionalProperties = additionalProperties } - public enum CodingKeys: String, CodingKey { case foo } + public enum CodingKeys: String, CodingKey { + case foo + } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - foo = try container.decodeIfPresent(Swift.String.self, forKey: .foo) + foo = try container.decodeIfPresent( + Swift.String.self, + forKey: .foo + ) additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: ["foo"]) } public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - try container.encodeIfPresent(foo, forKey: .foo) + try container.encodeIfPresent( + foo, + forKey: .foo + ) try encoder.encodeAdditionalProperties(additionalProperties) } } @@ -436,19 +490,30 @@ public enum Components { /// - Parameters: /// - foo: /// - additionalProperties: A container of undocumented properties. - public init(foo: Swift.String? = nil, additionalProperties: [String: Swift.Int] = .init()) { + public init( + foo: Swift.String? = nil, + additionalProperties: [String: Swift.Int] = .init() + ) { self.foo = foo self.additionalProperties = additionalProperties } - public enum CodingKeys: String, CodingKey { case foo } + public enum CodingKeys: String, CodingKey { + case foo + } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - foo = try container.decodeIfPresent(Swift.String.self, forKey: .foo) + foo = try container.decodeIfPresent( + Swift.String.self, + forKey: .foo + ) additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: ["foo"]) } public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - try container.encodeIfPresent(foo, forKey: .foo) + try container.encodeIfPresent( + foo, + forKey: .foo + ) try encoder.encodeAdditionalProperties(additionalProperties) } } @@ -460,8 +525,12 @@ public enum Components { /// /// - Parameters: /// - code: - public init(code: Swift.Int) { self.code = code } - public enum CodingKeys: String, CodingKey { case code } + public init(code: Swift.Int) { + self.code = code + } + public enum CodingKeys: String, CodingKey { + case code + } } /// - Remark: Generated from `#/components/schemas/AllOfObjects`. public struct AllOfObjects: Codable, Hashable, Sendable { @@ -473,8 +542,12 @@ public enum Components { /// /// - Parameters: /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } + public init(message: Swift.String) { + self.message = message + } + public enum CodingKeys: String, CodingKey { + case message + } } /// - Remark: Generated from `#/components/schemas/AllOfObjects/value1`. public var value1: Components.Schemas.AllOfObjects.Value1Payload @@ -485,7 +558,10 @@ public enum Components { /// - Parameters: /// - value1: /// - value2: - public init(value1: Components.Schemas.AllOfObjects.Value1Payload, value2: Components.Schemas.CodeError) { + public init( + value1: Components.Schemas.AllOfObjects.Value1Payload, + value2: Components.Schemas.CodeError + ) { self.value1 = value1 self.value2 = value2 } @@ -508,8 +584,12 @@ public enum Components { /// /// - Parameters: /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } + public init(message: Swift.String) { + self.message = message + } + public enum CodingKeys: String, CodingKey { + case message + } } /// - Remark: Generated from `#/components/schemas/AnyOfObjects/value1`. public var value1: Components.Schemas.AnyOfObjects.Value1Payload? @@ -557,8 +637,12 @@ public enum Components { /// /// - Parameters: /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } + public init(message: Swift.String) { + self.message = message + } + public enum CodingKeys: String, CodingKey { + case message + } } /// - Remark: Generated from `#/components/schemas/OneOfAny/case4`. case case4(Components.Schemas.OneOfAny.Case4Payload) @@ -579,14 +663,21 @@ public enum Components { self = .case4(try .init(from: decoder)) return } catch {} - throw Swift.DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath + ) } public func encode(to encoder: any Encoder) throws { switch self { - case let .case1(value): try encoder.encodeToSingleValueContainer(value) - case let .case2(value): try encoder.encodeToSingleValueContainer(value) - case let .CodeError(value): try value.encode(to: encoder) - case let .case4(value): try value.encode(to: encoder) + case let .case1(value): + try encoder.encodeToSingleValueContainer(value) + case let .case2(value): + try encoder.encodeToSingleValueContainer(value) + case let .CodeError(value): + try value.encode(to: encoder) + case let .case4(value): + try value.encode(to: encoder) } } } @@ -598,8 +689,12 @@ public enum Components { /// /// - Parameters: /// - kind: - public init(kind: Swift.String) { self.kind = kind } - public enum CodingKeys: String, CodingKey { case kind } + public init(kind: Swift.String) { + self.kind = kind + } + public enum CodingKeys: String, CodingKey { + case kind + } } /// - Remark: Generated from `#/components/schemas/Walk`. public struct Walk: Codable, Hashable, Sendable { @@ -612,7 +707,10 @@ public enum Components { /// - Parameters: /// - kind: /// - length: - public init(kind: Swift.String, length: Swift.Int) { + public init( + kind: Swift.String, + length: Swift.Int + ) { self.kind = kind self.length = length } @@ -633,8 +731,12 @@ public enum Components { /// /// - Parameters: /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } + public init(message: Swift.String) { + self.message = message + } + public enum CodingKeys: String, CodingKey { + case message + } } /// - Remark: Generated from `#/components/schemas/MessagedExercise/value2`. public var value2: Components.Schemas.MessagedExercise.Value2Payload @@ -665,22 +767,33 @@ public enum Components { case Walk(Components.Schemas.Walk) /// - Remark: Generated from `#/components/schemas/OneOfObjectsWithDiscriminator/MessagedExercise`. case MessagedExercise(Components.Schemas.MessagedExercise) - public enum CodingKeys: String, CodingKey { case kind } + public enum CodingKeys: String, CodingKey { + case kind + } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminator = try container.decode(Swift.String.self, forKey: .kind) + let discriminator = try container.decode( + Swift.String.self, + forKey: .kind + ) switch discriminator { - case "Walk", "#/components/schemas/Walk": self = .Walk(try .init(from: decoder)) + case "Walk", "#/components/schemas/Walk": + self = .Walk(try .init(from: decoder)) case "MessagedExercise", "#/components/schemas/MessagedExercise": self = .MessagedExercise(try .init(from: decoder)) default: - throw Swift.DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath + ) } } public func encode(to encoder: any Encoder) throws { switch self { - case let .Walk(value): try value.encode(to: encoder) - case let .MessagedExercise(value): try value.encode(to: encoder) + case let .Walk(value): + try value.encode(to: encoder) + case let .MessagedExercise(value): + try value.encode(to: encoder) } } } @@ -692,35 +805,57 @@ public enum Components { /// /// - Parameters: /// - count: - public init(count: Swift.Int) { self.count = count } - public enum CodingKeys: String, CodingKey { case count } + public init(count: Swift.Int) { + self.count = count + } + public enum CodingKeys: String, CodingKey { + case count + } } /// - Remark: Generated from `#/components/schemas/RecursivePet`. public struct RecursivePet: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/RecursivePet/name`. public var name: Swift.String { - get { storage.value.name } - _modify { yield &storage.value.name } + get { + storage.value.name + } + _modify { + yield &storage.value.name + } } /// - Remark: Generated from `#/components/schemas/RecursivePet/parent`. public var parent: Components.Schemas.RecursivePet? { - get { storage.value.parent } - _modify { yield &storage.value.parent } + get { + storage.value.parent + } + _modify { + yield &storage.value.parent + } } /// Creates a new `RecursivePet`. /// /// - Parameters: /// - name: /// - parent: - public init(name: Swift.String, parent: Components.Schemas.RecursivePet? = nil) { - storage = .init(value: .init(name: name, parent: parent)) + public init( + name: Swift.String, + parent: Components.Schemas.RecursivePet? = nil + ) { + storage = .init(value: .init( + name: name, + parent: parent + )) } public enum CodingKeys: String, CodingKey { case name case parent } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) + } /// Internal reference storage to allow type recursion. private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { @@ -728,7 +863,10 @@ public enum Components { var name: Swift.String /// - Remark: Generated from `#/components/schemas/RecursivePet/parent`. var parent: Components.Schemas.RecursivePet? - init(name: Swift.String, parent: Components.Schemas.RecursivePet? = nil) { + init( + name: Swift.String, + parent: Components.Schemas.RecursivePet? = nil + ) { self.name = name self.parent = parent } @@ -739,8 +877,12 @@ public enum Components { public struct RecursivePetNested: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/RecursivePetNested/name`. public var name: Swift.String { - get { storage.value.name } - _modify { yield &storage.value.name } + get { + storage.value.name + } + _modify { + yield &storage.value.name + } } /// - Remark: Generated from `#/components/schemas/RecursivePetNested/parent`. public struct parentPayload: Codable, Hashable, Sendable { @@ -750,28 +892,46 @@ public enum Components { /// /// - Parameters: /// - nested: - public init(nested: Components.Schemas.RecursivePetNested) { self.nested = nested } - public enum CodingKeys: String, CodingKey { case nested } + public init(nested: Components.Schemas.RecursivePetNested) { + self.nested = nested + } + public enum CodingKeys: String, CodingKey { + case nested + } } /// - Remark: Generated from `#/components/schemas/RecursivePetNested/parent`. public var parent: Components.Schemas.RecursivePetNested.parentPayload? { - get { storage.value.parent } - _modify { yield &storage.value.parent } + get { + storage.value.parent + } + _modify { + yield &storage.value.parent + } } /// Creates a new `RecursivePetNested`. /// /// - Parameters: /// - name: /// - parent: - public init(name: Swift.String, parent: Components.Schemas.RecursivePetNested.parentPayload? = nil) { - storage = .init(value: .init(name: name, parent: parent)) + public init( + name: Swift.String, + parent: Components.Schemas.RecursivePetNested.parentPayload? = nil + ) { + storage = .init(value: .init( + name: name, + parent: parent + )) } public enum CodingKeys: String, CodingKey { case name case parent } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) + } /// Internal reference storage to allow type recursion. private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { @@ -785,12 +945,19 @@ public enum Components { /// /// - Parameters: /// - nested: - public init(nested: Components.Schemas.RecursivePetNested) { self.nested = nested } - public enum CodingKeys: String, CodingKey { case nested } + public init(nested: Components.Schemas.RecursivePetNested) { + self.nested = nested + } + public enum CodingKeys: String, CodingKey { + case nested + } } /// - Remark: Generated from `#/components/schemas/RecursivePetNested/parent`. var parent: Components.Schemas.RecursivePetNested.parentPayload? - init(name: Swift.String, parent: Components.Schemas.RecursivePetNested.parentPayload? = nil) { + init( + name: Swift.String, + parent: Components.Schemas.RecursivePetNested.parentPayload? = nil + ) { self.name = name self.parent = parent } @@ -801,8 +968,12 @@ public enum Components { public struct RecursivePetOneOfFirst: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/RecursivePetOneOfFirst/value1`. public var value1: Components.Schemas.RecursivePetOneOf { - get { storage.value.value1 } - _modify { yield &storage.value.value1 } + get { + storage.value.value1 + } + _modify { + yield &storage.value.value1 + } } /// - Remark: Generated from `#/components/schemas/RecursivePetOneOfFirst/value2`. public struct Value2Payload: Codable, Hashable, Sendable { @@ -812,13 +983,21 @@ public enum Components { /// /// - Parameters: /// - _type: - public init(_type: Swift.String) { self._type = _type } - public enum CodingKeys: String, CodingKey { case _type = "type" } + public init(_type: Swift.String) { + self._type = _type + } + public enum CodingKeys: String, CodingKey { + case _type = "type" + } } /// - Remark: Generated from `#/components/schemas/RecursivePetOneOfFirst/value2`. public var value2: Components.Schemas.RecursivePetOneOfFirst.Value2Payload { - get { storage.value.value2 } - _modify { yield &storage.value.value2 } + get { + storage.value.value2 + } + _modify { + yield &storage.value.value2 + } } /// Creates a new `RecursivePetOneOfFirst`. /// @@ -828,9 +1007,18 @@ public enum Components { public init( value1: Components.Schemas.RecursivePetOneOf, value2: Components.Schemas.RecursivePetOneOfFirst.Value2Payload - ) { storage = .init(value: .init(value1: value1, value2: value2)) } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } + ) { + storage = .init(value: .init( + value1: value1, + value2: value2 + )) + } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) + } /// Internal reference storage to allow type recursion. private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { @@ -844,8 +1032,12 @@ public enum Components { /// /// - Parameters: /// - _type: - public init(_type: Swift.String) { self._type = _type } - public enum CodingKeys: String, CodingKey { case _type = "type" } + public init(_type: Swift.String) { + self._type = _type + } + public enum CodingKeys: String, CodingKey { + case _type = "type" + } } /// - Remark: Generated from `#/components/schemas/RecursivePetOneOfFirst/value2`. var value2: Components.Schemas.RecursivePetOneOfFirst.Value2Payload @@ -878,8 +1070,12 @@ public enum Components { /// /// - Parameters: /// - _type: - public init(_type: Swift.String) { self._type = _type } - public enum CodingKeys: String, CodingKey { case _type = "type" } + public init(_type: Swift.String) { + self._type = _type + } + public enum CodingKeys: String, CodingKey { + case _type = "type" + } } /// - Remark: Generated from `#/components/schemas/RecursivePetOneOfSecond/value2`. public var value2: Components.Schemas.RecursivePetOneOfSecond.Value2Payload @@ -910,23 +1106,33 @@ public enum Components { case RecursivePetOneOfFirst(Components.Schemas.RecursivePetOneOfFirst) /// - Remark: Generated from `#/components/schemas/RecursivePetOneOf/RecursivePetOneOfSecond`. case RecursivePetOneOfSecond(Components.Schemas.RecursivePetOneOfSecond) - public enum CodingKeys: String, CodingKey { case _type = "type" } + public enum CodingKeys: String, CodingKey { + case _type = "type" + } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminator = try container.decode(Swift.String.self, forKey: ._type) + let discriminator = try container.decode( + Swift.String.self, + forKey: ._type + ) switch discriminator { case "RecursivePetOneOfFirst", "#/components/schemas/RecursivePetOneOfFirst": self = .RecursivePetOneOfFirst(try .init(from: decoder)) case "RecursivePetOneOfSecond", "#/components/schemas/RecursivePetOneOfSecond": self = .RecursivePetOneOfSecond(try .init(from: decoder)) default: - throw Swift.DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath + ) } } public func encode(to encoder: any Encoder) throws { switch self { - case let .RecursivePetOneOfFirst(value): try value.encode(to: encoder) - case let .RecursivePetOneOfSecond(value): try value.encode(to: encoder) + case let .RecursivePetOneOfFirst(value): + try value.encode(to: encoder) + case let .RecursivePetOneOfSecond(value): + try value.encode(to: encoder) } } } @@ -934,24 +1140,42 @@ public enum Components { public struct RecursivePetAnyOf: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/RecursivePetAnyOf/value1`. public var value1: Components.Schemas.RecursivePetAnyOf? { - get { storage.value.value1 } - _modify { yield &storage.value.value1 } + get { + storage.value.value1 + } + _modify { + yield &storage.value.value1 + } } /// - Remark: Generated from `#/components/schemas/RecursivePetAnyOf/value2`. public var value2: Swift.String? { - get { storage.value.value2 } - _modify { yield &storage.value.value2 } + get { + storage.value.value2 + } + _modify { + yield &storage.value.value2 + } } /// Creates a new `RecursivePetAnyOf`. /// /// - Parameters: /// - value1: /// - value2: - public init(value1: Components.Schemas.RecursivePetAnyOf? = nil, value2: Swift.String? = nil) { - storage = .init(value: .init(value1: value1, value2: value2)) + public init( + value1: Components.Schemas.RecursivePetAnyOf? = nil, + value2: Swift.String? = nil + ) { + storage = .init(value: .init( + value1: value1, + value2: value2 + )) + } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } /// Internal reference storage to allow type recursion. private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { @@ -959,7 +1183,10 @@ public enum Components { var value1: Components.Schemas.RecursivePetAnyOf? /// - Remark: Generated from `#/components/schemas/RecursivePetAnyOf/value2`. var value2: Swift.String? - init(value1: Components.Schemas.RecursivePetAnyOf? = nil, value2: Swift.String? = nil) { + init( + value1: Components.Schemas.RecursivePetAnyOf? = nil, + value2: Swift.String? = nil + ) { self.value1 = value1 self.value2 = value2 } @@ -988,13 +1215,21 @@ public enum Components { /// /// - Parameters: /// - parent: - public init(parent: Components.Schemas.RecursivePetAllOf? = nil) { self.parent = parent } - public enum CodingKeys: String, CodingKey { case parent } + public init(parent: Components.Schemas.RecursivePetAllOf? = nil) { + self.parent = parent + } + public enum CodingKeys: String, CodingKey { + case parent + } } /// - Remark: Generated from `#/components/schemas/RecursivePetAllOf/value1`. public var value1: Components.Schemas.RecursivePetAllOf.Value1Payload { - get { storage.value.value1 } - _modify { yield &storage.value.value1 } + get { + storage.value.value1 + } + _modify { + yield &storage.value.value1 + } } /// Creates a new `RecursivePetAllOf`. /// @@ -1003,8 +1238,12 @@ public enum Components { public init(value1: Components.Schemas.RecursivePetAllOf.Value1Payload) { storage = .init(value: .init(value1: value1)) } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) + } /// Internal reference storage to allow type recursion. private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { @@ -1016,14 +1255,24 @@ public enum Components { /// /// - Parameters: /// - parent: - public init(parent: Components.Schemas.RecursivePetAllOf? = nil) { self.parent = parent } - public enum CodingKeys: String, CodingKey { case parent } + public init(parent: Components.Schemas.RecursivePetAllOf? = nil) { + self.parent = parent + } + public enum CodingKeys: String, CodingKey { + case parent + } } /// - Remark: Generated from `#/components/schemas/RecursivePetAllOf/value1`. var value1: Components.Schemas.RecursivePetAllOf.Value1Payload - init(value1: Components.Schemas.RecursivePetAllOf.Value1Payload) { self.value1 = value1 } - init(from decoder: any Decoder) throws { value1 = try .init(from: decoder) } - func encode(to encoder: any Encoder) throws { try value1.encode(to: encoder) } + init(value1: Components.Schemas.RecursivePetAllOf.Value1Payload) { + self.value1 = value1 + } + init(from decoder: any Decoder) throws { + value1 = try .init(from: decoder) + } + func encode(to encoder: any Encoder) throws { + try value1.encode(to: encoder) + } } } } @@ -1090,7 +1339,9 @@ public enum Components { /// /// - Parameters: /// - X_hyphen_Reason: A description here. - public init(X_hyphen_Reason: Swift.String? = nil) { self.X_hyphen_Reason = X_hyphen_Reason } + public init(X_hyphen_Reason: Swift.String? = nil) { + self.X_hyphen_Reason = X_hyphen_Reason + } } /// Received HTTP response headers public var headers: Components.Responses.ErrorBadRequest.Headers @@ -1104,8 +1355,12 @@ public enum Components { /// /// - Parameters: /// - code: - public init(code: Swift.Int) { self.code = code } - public enum CodingKeys: String, CodingKey { case code } + public init(code: Swift.Int) { + self.code = code + } + public enum CodingKeys: String, CodingKey { + case code + } } /// - Remark: Generated from `#/components/responses/ErrorBadRequest/content/application\/json`. case json(Components.Responses.ErrorBadRequest.Body.jsonPayload) @@ -1116,7 +1371,8 @@ public enum Components { public var json: Components.Responses.ErrorBadRequest.Body.jsonPayload { get throws { switch self { - case let .json(body): return body + case let .json(body): + return body } } } @@ -1145,6 +1401,7 @@ public enum Components { public typealias TracingHeader = Swift.String } } + /// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. public enum Operations { /// List all pets @@ -1220,8 +1477,7 @@ public enum Operations { /// - accept: public init( My_hyphen_Request_hyphen_UUID: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() ) { self.My_hyphen_Request_hyphen_UUID = My_hyphen_Request_hyphen_UUID self.accept = accept @@ -1279,7 +1535,8 @@ public enum Operations { public var json: Components.Schemas.Pets { get throws { switch self { - case let .json(body): return body + case let .json(body): + return body } } } @@ -1291,7 +1548,10 @@ public enum Operations { /// - Parameters: /// - headers: Received HTTP response headers /// - body: Received HTTP response body - public init(headers: Operations.listPets.Output.Ok.Headers, body: Operations.listPets.Output.Ok.Body) { + public init( + headers: Operations.listPets.Output.Ok.Headers, + body: Operations.listPets.Output.Ok.Body + ) { self.headers = headers self.body = body } @@ -1309,8 +1569,13 @@ public enum Operations { public var ok: Operations.listPets.Output.Ok { get throws { switch self { - case let .ok(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "ok", response: self) + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) } } } @@ -1326,7 +1591,8 @@ public enum Operations { public var json: Components.Schemas._Error { get throws { switch self { - case let .json(body): return body + case let .json(body): + return body } } } @@ -1337,7 +1603,9 @@ public enum Operations { /// /// - Parameters: /// - body: Received HTTP response body - public init(body: Operations.listPets.Output.Default.Body) { self.body = body } + public init(body: Operations.listPets.Output.Default.Body) { + self.body = body + } } /// Unexpected error /// @@ -1352,8 +1620,13 @@ public enum Operations { public var `default`: Operations.listPets.Output.Default { get throws { switch self { - case let .`default`(_, response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "default", response: self) + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) } } } @@ -1363,17 +1636,23 @@ public enum Operations { case other(Swift.String) public init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/json": self = .json - default: self = .other(rawValue) + 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" + case let .other(string): + return string + case .json: + return "application/json" } } - public static var allCases: [Self] { [.json] } + public static var allCases: [Self] { + [.json] + } } } /// Create a pet @@ -1397,8 +1676,7 @@ public enum Operations { /// - accept: public init( X_hyphen_Extra_hyphen_Arguments: Components.Schemas.CodeError? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() ) { self.X_hyphen_Extra_hyphen_Arguments = X_hyphen_Extra_hyphen_Arguments self.accept = accept @@ -1416,7 +1694,10 @@ public enum Operations { /// - Parameters: /// - headers: /// - body: - public init(headers: Operations.createPet.Input.Headers = .init(), body: Operations.createPet.Input.Body) { + public init( + headers: Operations.createPet.Input.Headers = .init(), + body: Operations.createPet.Input.Body + ) { self.headers = headers self.body = body } @@ -1450,7 +1731,8 @@ public enum Operations { public var json: Components.Schemas.Pet { get throws { switch self { - case let .json(body): return body + case let .json(body): + return body } } } @@ -1483,8 +1765,13 @@ public enum Operations { public var created: Operations.createPet.Output.Created { get throws { switch self { - case let .created(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "created", response: self) + case let .created(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) } } } @@ -1501,8 +1788,13 @@ public enum Operations { public var clientError: Components.Responses.ErrorBadRequest { get throws { switch self { - case let .clientError(_, response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "clientError", response: self) + case let .clientError(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "clientError", + response: self + ) } } } @@ -1516,17 +1808,23 @@ public enum Operations { case other(Swift.String) public init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/json": self = .json - default: self = .other(rawValue) + 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" + case let .other(string): + return string + case .json: + return "application/json" } } - public static var allCases: [Self] { [.json] } + public static var allCases: [Self] { + [.json] + } } } /// Create a pet using a url form @@ -1546,7 +1844,9 @@ public enum Operations { /// /// - Parameters: /// - body: - public init(body: Operations.createPetWithForm.Input.Body) { self.body = body } + public init(body: Operations.createPetWithForm.Input.Body) { + self.body = body + } } @frozen public enum Output: Sendable, Hashable { public struct NoContent: Sendable, Hashable { @@ -1566,8 +1866,13 @@ public enum Operations { public var noContent: Operations.createPetWithForm.Output.NoContent { get throws { switch self { - case let .noContent(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "noContent", response: self) + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) } } } @@ -1589,17 +1894,18 @@ public enum Operations { /// /// - Parameters: /// - accept: - public init( - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() - ) { self.accept = accept } + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } } public var headers: Operations.getStats.Input.Headers /// Creates a new `Input`. /// /// - Parameters: /// - headers: - public init(headers: Operations.getStats.Input.Headers = .init()) { self.headers = headers } + public init(headers: Operations.getStats.Input.Headers = .init()) { + self.headers = headers + } } @frozen public enum Output: Sendable, Hashable { public struct Ok: Sendable, Hashable { @@ -1614,8 +1920,13 @@ public enum Operations { public var json: Components.Schemas.PetStats { get throws { switch self { - case let .json(body): return body - default: try throwUnexpectedResponseBody(expectedContent: "application/json", body: self) + case let .json(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) } } } @@ -1628,8 +1939,13 @@ public enum Operations { public var plainText: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .plainText(body): return body - default: try throwUnexpectedResponseBody(expectedContent: "text/plain", body: self) + case let .plainText(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "text/plain", + body: self + ) } } } @@ -1642,9 +1958,13 @@ public enum Operations { public var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .binary(body): return body + case let .binary(body): + return body default: - try throwUnexpectedResponseBody(expectedContent: "application/octet-stream", body: self) + try throwUnexpectedResponseBody( + expectedContent: "application/octet-stream", + body: self + ) } } } @@ -1655,7 +1975,9 @@ public enum Operations { /// /// - Parameters: /// - body: Received HTTP response body - public init(body: Operations.getStats.Output.Ok.Body) { self.body = body } + public init(body: Operations.getStats.Output.Ok.Body) { + self.body = body + } } /// A successful response. /// @@ -1670,8 +1992,13 @@ public enum Operations { public var ok: Operations.getStats.Output.Ok { get throws { switch self { - case let .ok(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "ok", response: self) + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) } } } @@ -1687,21 +2014,31 @@ public enum Operations { case other(Swift.String) public init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/json": self = .json - case "text/plain": self = .plainText - case "application/octet-stream": self = .binary - default: self = .other(rawValue) + case "application/json": + self = .json + case "text/plain": + self = .plainText + case "application/octet-stream": + self = .binary + default: + self = .other(rawValue) } } public var rawValue: Swift.String { switch self { - case let .other(string): return string - case .json: return "application/json" - case .plainText: return "text/plain" - case .binary: return "application/octet-stream" + case let .other(string): + return string + case .json: + return "application/json" + case .plainText: + return "text/plain" + case .binary: + return "application/octet-stream" } } - public static var allCases: [Self] { [.json, .plainText, .binary] } + public static var allCases: [Self] { + [.json, .plainText, .binary] + } } } /// - Remark: HTTP `POST /pets/stats`. @@ -1723,7 +2060,9 @@ public enum Operations { /// /// - Parameters: /// - body: - public init(body: Operations.postStats.Input.Body) { self.body = body } + public init(body: Operations.postStats.Input.Body) { + self.body = body + } } @frozen public enum Output: Sendable, Hashable { public struct Accepted: Sendable, Hashable { @@ -1743,8 +2082,13 @@ public enum Operations { public var accepted: Operations.postStats.Output.Accepted { get throws { switch self { - case let .accepted(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "accepted", response: self) + case let .accepted(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "accepted", + response: self + ) } } } @@ -1780,8 +2124,13 @@ public enum Operations { public var noContent: Operations.probe.Output.NoContent { get throws { switch self { - case let .noContent(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "noContent", response: self) + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) } } } @@ -1808,7 +2157,9 @@ public enum Operations { /// /// - Parameters: /// - petId: Id of the pet - public init(petId: Swift.Int64) { self.petId = petId } + public init(petId: Swift.Int64) { + self.petId = petId + } } public var path: Operations.updatePet.Input.Path /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/header`. @@ -1818,10 +2169,9 @@ public enum Operations { /// /// - Parameters: /// - accept: - public init( - accept: [OpenAPIRuntime.AcceptHeaderContentType] = - .defaultValues() - ) { self.accept = accept } + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } } public var headers: Operations.updatePet.Input.Headers public var body: Components.RequestBodies.UpdatePetRequest? @@ -1859,8 +2209,13 @@ public enum Operations { public var noContent: Operations.updatePet.Output.NoContent { get throws { switch self { - case let .noContent(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "noContent", response: self) + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) } } } @@ -1875,8 +2230,12 @@ public enum Operations { /// /// - Parameters: /// - message: - public init(message: Swift.String) { self.message = message } - public enum CodingKeys: String, CodingKey { case message } + public init(message: Swift.String) { + self.message = message + } + public enum CodingKeys: String, CodingKey { + case message + } } /// - Remark: Generated from `#/paths/pets/{petId}/PATCH/responses/400/content/application\/json`. case json(Operations.updatePet.Output.BadRequest.Body.jsonPayload) @@ -1887,7 +2246,8 @@ public enum Operations { public var json: Operations.updatePet.Output.BadRequest.Body.jsonPayload { get throws { switch self { - case let .json(body): return body + case let .json(body): + return body } } } @@ -1898,7 +2258,9 @@ public enum Operations { /// /// - Parameters: /// - body: Received HTTP response body - public init(body: Operations.updatePet.Output.BadRequest.Body) { self.body = body } + public init(body: Operations.updatePet.Output.BadRequest.Body) { + self.body = body + } } /// Update input error /// @@ -1913,8 +2275,13 @@ public enum Operations { public var badRequest: Operations.updatePet.Output.BadRequest { get throws { switch self { - case let .badRequest(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "badRequest", response: self) + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) } } } @@ -1928,17 +2295,23 @@ public enum Operations { case other(Swift.String) public init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/json": self = .json - default: self = .other(rawValue) + 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" + case let .other(string): + return string + case .json: + return "application/json" } } - public static var allCases: [Self] { [.json] } + public static var allCases: [Self] { + [.json] + } } } /// Upload an avatar @@ -1958,22 +2331,21 @@ public enum Operations { /// /// - Parameters: /// - petId: The id of the pet to retrieve - public init(petId: Components.Parameters.path_period_petId) { self.petId = petId } + public init(petId: Components.Parameters.path_period_petId) { + self.petId = petId + } } public var path: Operations.uploadAvatarForPet.Input.Path /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/header`. public struct Headers: Sendable, Hashable { - public var accept: - [OpenAPIRuntime.AcceptHeaderContentType] + public var accept: [OpenAPIRuntime.AcceptHeaderContentType] /// Creates a new `Headers`. /// /// - Parameters: /// - accept: - public init( - accept: [OpenAPIRuntime.AcceptHeaderContentType< - Operations.uploadAvatarForPet.AcceptableContentType - >] = .defaultValues() - ) { self.accept = accept } + public init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } } public var headers: Operations.uploadAvatarForPet.Input.Headers /// - Remark: Generated from `#/paths/pets/{petId}/avatar/PUT/requestBody`. @@ -2011,7 +2383,8 @@ public enum Operations { public var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .binary(body): return body + case let .binary(body): + return body } } } @@ -2022,7 +2395,9 @@ public enum Operations { /// /// - Parameters: /// - body: Received HTTP response body - public init(body: Operations.uploadAvatarForPet.Output.Ok.Body) { self.body = body } + public init(body: Operations.uploadAvatarForPet.Output.Ok.Body) { + self.body = body + } } /// Echoes avatar back /// @@ -2037,8 +2412,13 @@ public enum Operations { public var ok: Operations.uploadAvatarForPet.Output.Ok { get throws { switch self { - case let .ok(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "ok", response: self) + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) } } } @@ -2054,7 +2434,8 @@ public enum Operations { public var json: Swift.String { get throws { switch self { - case let .json(body): return body + case let .json(body): + return body } } } @@ -2065,7 +2446,9 @@ public enum Operations { /// /// - Parameters: /// - body: Received HTTP response body - public init(body: Operations.uploadAvatarForPet.Output.PreconditionFailed.Body) { self.body = body } + public init(body: Operations.uploadAvatarForPet.Output.PreconditionFailed.Body) { + self.body = body + } } /// Avatar is not acceptable /// @@ -2080,8 +2463,13 @@ public enum Operations { public var preconditionFailed: Operations.uploadAvatarForPet.Output.PreconditionFailed { get throws { switch self { - case let .preconditionFailed(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "preconditionFailed", response: self) + case let .preconditionFailed(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "preconditionFailed", + response: self + ) } } } @@ -2097,7 +2485,8 @@ public enum Operations { public var plainText: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .plainText(body): return body + case let .plainText(body): + return body } } } @@ -2108,7 +2497,9 @@ public enum Operations { /// /// - Parameters: /// - body: Received HTTP response body - public init(body: Operations.uploadAvatarForPet.Output.InternalServerError.Body) { self.body = body } + public init(body: Operations.uploadAvatarForPet.Output.InternalServerError.Body) { + self.body = body + } } /// Server error /// @@ -2123,8 +2514,13 @@ public enum Operations { public var internalServerError: Operations.uploadAvatarForPet.Output.InternalServerError { get throws { switch self { - case let .internalServerError(response): return response - default: try throwUnexpectedResponseStatus(expectedStatus: "internalServerError", response: self) + case let .internalServerError(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "internalServerError", + response: self + ) } } } @@ -2140,21 +2536,31 @@ public enum Operations { case other(Swift.String) public init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/octet-stream": self = .binary - case "application/json": self = .json - case "text/plain": self = .plainText - default: self = .other(rawValue) + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + case "text/plain": + self = .plainText + default: + self = .other(rawValue) } } public var rawValue: Swift.String { switch self { - case let .other(string): return string - case .binary: return "application/octet-stream" - case .json: return "application/json" - case .plainText: return "text/plain" + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + case .plainText: + return "text/plain" } } - public static var allCases: [Self] { [.binary, .json, .plainText] } + public static var allCases: [Self] { + [.binary, .json, .plainText] + } } } } diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift index 7ed5a268..2e31f7fc 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift @@ -28,7 +28,7 @@ final class SnippetBasedReferenceTests: XCTestCase { """, """ public enum Headers { - public typealias MyHeader = Swift.String + public typealias MyHeader = Swift.String } """ ) @@ -47,7 +47,7 @@ final class SnippetBasedReferenceTests: XCTestCase { """, """ public enum Headers { - public typealias MyHeader = Components.Schemas.MySchema + public typealias MyHeader = Components.Schemas.MySchema } """ ) @@ -65,7 +65,7 @@ final class SnippetBasedReferenceTests: XCTestCase { """, """ public enum Parameters { - public typealias MyParam = Swift.String + public typealias MyParam = Swift.String } """ ) @@ -86,7 +86,7 @@ final class SnippetBasedReferenceTests: XCTestCase { """, """ public enum Parameters { - public typealias MyParam = Components.Schemas.MySchema + public typealias MyParam = Components.Schemas.MySchema } """ ) @@ -261,10 +261,10 @@ final class SnippetBasedReferenceTests: XCTestCase { - nullableString """, """ - public enum Schemas { - public typealias MyRequiredString = Swift.String - public typealias MyNullableString = Swift.String - public struct MyObject: Codable, Hashable, Sendable { + public enum Schemas { + public typealias MyRequiredString = Swift.String + public typealias MyNullableString = Swift.String + public struct MyObject: Codable, Hashable, Sendable { public var id: Swift.Int64 public var alias: Swift.String? public var requiredString: Components.Schemas.MyRequiredString @@ -286,8 +286,8 @@ final class SnippetBasedReferenceTests: XCTestCase { case requiredString case nullableString } - } } + } """ ) } @@ -312,13 +312,17 @@ final class SnippetBasedReferenceTests: XCTestCase { - binaryProperty """, """ - public enum Schemas { - public struct MyObject: Codable, Hashable, Sendable { + public enum Schemas { + public struct MyObject: Codable, Hashable, Sendable { public var actualString: Swift.String - public init(actualString: Swift.String) { self.actualString = actualString } - public enum CodingKeys: String, CodingKey { case actualString } - } + public init(actualString: Swift.String) { + self.actualString = actualString + } + public enum CodingKeys: String, CodingKey { + case actualString + } } + } """ ) } @@ -364,7 +368,9 @@ final class SnippetBasedReferenceTests: XCTestCase { value3 = try decoder.decodeFromSingleValueContainer() value4 = try decoder.decodeFromSingleValueContainer() } - public func encode(to encoder: any Encoder) throws { try encoder.encodeToSingleValueContainer(value3) } + public func encode(to encoder: any Encoder) throws { + try encoder.encodeToSingleValueContainer(value3) + } } } """ @@ -458,24 +464,39 @@ final class SnippetBasedReferenceTests: XCTestCase { public enum Schemas { public struct A: Codable, Hashable, Sendable { public var which: Swift.String? - public init(which: Swift.String? = nil) { self.which = which } - public enum CodingKeys: String, CodingKey { case which } + public init(which: Swift.String? = nil) { + self.which = which + } + public enum CodingKeys: String, CodingKey { + case which + } } public struct B: Codable, Hashable, Sendable { public var which: Swift.String? - public init(which: Swift.String? = nil) { self.which = which } - public enum CodingKeys: String, CodingKey { case which } + public init(which: Swift.String? = nil) { + self.which = which + } + public enum CodingKeys: String, CodingKey { + case which + } } @frozen public enum MyOneOf: Codable, Hashable, Sendable { case A(Components.Schemas.A) case B(Components.Schemas.B) - public enum CodingKeys: String, CodingKey { case which } + public enum CodingKeys: String, CodingKey { + case which + } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminator = try container.decode(Swift.String.self, forKey: .which) + let discriminator = try container.decode( + Swift.String.self, + forKey: .which + ) switch discriminator { - case "A", "#/components/schemas/A": self = .A(try .init(from: decoder)) - case "B", "#/components/schemas/B": self = .B(try .init(from: decoder)) + case "A", "#/components/schemas/A": + self = .A(try .init(from: decoder)) + case "B", "#/components/schemas/B": + self = .B(try .init(from: decoder)) default: throw Swift.DecodingError.failedToDecodeOneOfSchema( type: Self.self, @@ -485,8 +506,10 @@ final class SnippetBasedReferenceTests: XCTestCase { } public func encode(to encoder: any Encoder) throws { switch self { - case let .A(value): try value.encode(to: encoder) - case let .B(value): try value.encode(to: encoder) + case let .A(value): + try value.encode(to: encoder) + case let .B(value): + try value.encode(to: encoder) } } } @@ -530,33 +553,54 @@ final class SnippetBasedReferenceTests: XCTestCase { public enum Schemas { public struct A: Codable, Hashable, Sendable { public var which: Swift.String? - public init(which: Swift.String? = nil) { self.which = which } - public enum CodingKeys: String, CodingKey { case which } + public init(which: Swift.String? = nil) { + self.which = which + } + public enum CodingKeys: String, CodingKey { + case which + } } public struct B: Codable, Hashable, Sendable { public var which: Swift.String? - public init(which: Swift.String? = nil) { self.which = which } - public enum CodingKeys: String, CodingKey { case which } + public init(which: Swift.String? = nil) { + self.which = which + } + public enum CodingKeys: String, CodingKey { + case which + } } public struct C: Codable, Hashable, Sendable { public var which: Swift.String? - public init(which: Swift.String? = nil) { self.which = which } - public enum CodingKeys: String, CodingKey { case which } + public init(which: Swift.String? = nil) { + self.which = which + } + public enum CodingKeys: String, CodingKey { + case which + } } @frozen public enum MyOneOf: Codable, Hashable, Sendable { case a(Components.Schemas.A) case a2(Components.Schemas.A) case b(Components.Schemas.B) case C(Components.Schemas.C) - public enum CodingKeys: String, CodingKey { case which } + public enum CodingKeys: String, CodingKey { + case which + } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminator = try container.decode(Swift.String.self, forKey: .which) + let discriminator = try container.decode( + Swift.String.self, + forKey: .which + ) switch discriminator { - case "a": self = .a(try .init(from: decoder)) - case "a2": self = .a2(try .init(from: decoder)) - case "b": self = .b(try .init(from: decoder)) - case "C", "#/components/schemas/C": self = .C(try .init(from: decoder)) + case "a": + self = .a(try .init(from: decoder)) + case "a2": + self = .a2(try .init(from: decoder)) + case "b": + self = .b(try .init(from: decoder)) + case "C", "#/components/schemas/C": + self = .C(try .init(from: decoder)) default: throw Swift.DecodingError.failedToDecodeOneOfSchema( type: Self.self, @@ -566,10 +610,14 @@ final class SnippetBasedReferenceTests: XCTestCase { } public func encode(to encoder: any Encoder) throws { switch self { - case let .a(value): try value.encode(to: encoder) - case let .a2(value): try value.encode(to: encoder) - case let .b(value): try value.encode(to: encoder) - case let .C(value): try value.encode(to: encoder) + case let .a(value): + try value.encode(to: encoder) + case let .a2(value): + try value.encode(to: encoder) + case let .b(value): + try value.encode(to: encoder) + case let .C(value): + try value.encode(to: encoder) } } } @@ -616,9 +664,12 @@ final class SnippetBasedReferenceTests: XCTestCase { } public func encode(to encoder: any Encoder) throws { switch self { - case let .case1(value): try encoder.encodeToSingleValueContainer(value) - case let .case2(value): try encoder.encodeToSingleValueContainer(value) - case let .A(value): try value.encode(to: encoder) + case let .case1(value): + try encoder.encodeToSingleValueContainer(value) + case let .case2(value): + try encoder.encodeToSingleValueContainer(value) + case let .A(value): + try value.encode(to: encoder) } } } @@ -675,9 +726,12 @@ final class SnippetBasedReferenceTests: XCTestCase { } public func encode(to encoder: any Encoder) throws { switch self { - case let .case1(value): try encoder.encodeToSingleValueContainer(value) - case let .case2(value): try encoder.encodeToSingleValueContainer(value) - case let .A(value): try value.encode(to: encoder) + case let .case1(value): + try encoder.encodeToSingleValueContainer(value) + case let .case2(value): + try encoder.encodeToSingleValueContainer(value) + case let .A(value): + try value.encode(to: encoder) } } } @@ -727,8 +781,12 @@ final class SnippetBasedReferenceTests: XCTestCase { public init(value1: Components.Schemas.A) { self.value1 = value1 } - public init(from decoder: any Decoder) throws { value1 = try decoder.decodeFromSingleValueContainer() } - public func encode(to encoder: any Encoder) throws { try encoder.encodeToSingleValueContainer(value1) } + public init(from decoder: any Decoder) throws { + value1 = try decoder.decodeFromSingleValueContainer() + } + public func encode(to encoder: any Encoder) throws { + try encoder.encodeToSingleValueContainer(value1) + } } } """ @@ -756,13 +814,23 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct B: Codable, Hashable, Sendable { public struct cPayload: Codable, Hashable, Sendable { public var value1: Components.Schemas.A - public init(value1: Components.Schemas.A) { self.value1 = value1 } - public init(from decoder: any Decoder) throws { value1 = try decoder.decodeFromSingleValueContainer() } - public func encode(to encoder: any Encoder) throws { try encoder.encodeToSingleValueContainer(value1) } + public init(value1: Components.Schemas.A) { + self.value1 = value1 + } + public init(from decoder: any Decoder) throws { + value1 = try decoder.decodeFromSingleValueContainer() + } + public func encode(to encoder: any Encoder) throws { + try encoder.encodeToSingleValueContainer(value1) + } } public var c: Components.Schemas.B.cPayload - public init(c: Components.Schemas.B.cPayload) { self.c = c } - public enum CodingKeys: String, CodingKey { case c } + public init(c: Components.Schemas.B.cPayload) { + self.c = c + } + public enum CodingKeys: String, CodingKey { + case c + } } } """ @@ -789,13 +857,23 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct B: Codable, Hashable, Sendable { public struct cPayload: Codable, Hashable, Sendable { public var value1: Components.Schemas.A - public init(value1: Components.Schemas.A) { self.value1 = value1 } - public init(from decoder: any Decoder) throws { value1 = try decoder.decodeFromSingleValueContainer() } - public func encode(to encoder: any Encoder) throws { try encoder.encodeToSingleValueContainer(value1) } + public init(value1: Components.Schemas.A) { + self.value1 = value1 + } + public init(from decoder: any Decoder) throws { + value1 = try decoder.decodeFromSingleValueContainer() + } + public func encode(to encoder: any Encoder) throws { + try encoder.encodeToSingleValueContainer(value1) + } } public var c: Components.Schemas.B.cPayload? - public init(c: Components.Schemas.B.cPayload? = nil) { self.c = c } - public enum CodingKeys: String, CodingKey { case c } + public init(c: Components.Schemas.B.cPayload? = nil) { + self.c = c + } + public enum CodingKeys: String, CodingKey { + case c + } } } """ @@ -865,8 +943,7 @@ final class SnippetBasedReferenceTests: XCTestCase { """ public enum Schemas { public struct MyOpenEnum: Codable, Hashable, Sendable { - @frozen - public enum Value1Payload: String, Codable, Hashable, Sendable { + @frozen public enum Value1Payload: String, Codable, Hashable, Sendable { case one = "one" case two = "two" } @@ -937,8 +1014,12 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct MyObject: Codable, Hashable, Sendable { @available(*, deprecated) public var id: Swift.String? - public init(id: Swift.String? = nil) { self.id = id } - public enum CodingKeys: String, CodingKey { case id } + public init(id: Swift.String? = nil) { + self.id = id + } + public enum CodingKeys: String, CodingKey { + case id + } } } """ @@ -993,9 +1074,11 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct MyObj: Codable, Hashable, Sendable { public var stuff: OpenAPIRuntime.Base64EncodedData? public init(stuff: OpenAPIRuntime.Base64EncodedData? = nil) { - self.stuff = stuff + self.stuff = stuff + } + public enum CodingKeys: String, CodingKey { + case stuff } - public enum CodingKeys: String, CodingKey { case stuff } } } """ @@ -1016,17 +1099,31 @@ final class SnippetBasedReferenceTests: XCTestCase { public enum Schemas { public struct Node: Codable, Hashable, Sendable { public var parent: Components.Schemas.Node? { - get { storage.value.parent } - _modify { yield &storage.value.parent } + get { + storage.value.parent + } + _modify { + yield &storage.value.parent + } + } + public init(parent: Components.Schemas.Node? = nil) { + storage = .init(value: .init(parent: parent)) + } + public enum CodingKeys: String, CodingKey { + case parent + } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) } - public init(parent: Components.Schemas.Node? = nil) { storage = .init(value: .init(parent: parent)) } - public enum CodingKeys: String, CodingKey { case parent } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { var parent: Components.Schemas.Node? - init(parent: Components.Schemas.Node? = nil) { self.parent = parent } + init(parent: Components.Schemas.Node? = nil) { + self.parent = parent + } typealias CodingKeys = Components.Schemas.Node.CodingKeys } } @@ -1058,37 +1155,66 @@ final class SnippetBasedReferenceTests: XCTestCase { public enum Schemas { public struct Node: Codable, Hashable, Sendable { public var name: Swift.String { - get { storage.value.name } - _modify { yield &storage.value.name } + get { + storage.value.name + } + _modify { + yield &storage.value.name + } } public struct parentPayload: Codable, Hashable, Sendable { public var nested: Components.Schemas.Node - public init(nested: Components.Schemas.Node) { self.nested = nested } - public enum CodingKeys: String, CodingKey { case nested } + public init(nested: Components.Schemas.Node) { + self.nested = nested + } + public enum CodingKeys: String, CodingKey { + case nested + } } public var parent: Components.Schemas.Node.parentPayload? { - get { storage.value.parent } - _modify { yield &storage.value.parent } + get { + storage.value.parent + } + _modify { + yield &storage.value.parent + } } - public init(name: Swift.String, parent: Components.Schemas.Node.parentPayload? = nil) { - storage = .init(value: .init(name: name, parent: parent)) + public init( + name: Swift.String, + parent: Components.Schemas.Node.parentPayload? = nil + ) { + storage = .init(value: .init( + name: name, + parent: parent + )) } public enum CodingKeys: String, CodingKey { case name case parent } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) + } private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { var name: Swift.String struct parentPayload: Codable, Hashable, Sendable { public var nested: Components.Schemas.Node - public init(nested: Components.Schemas.Node) { self.nested = nested } - public enum CodingKeys: String, CodingKey { case nested } + public init(nested: Components.Schemas.Node) { + self.nested = nested + } + public enum CodingKeys: String, CodingKey { + case nested + } } var parent: Components.Schemas.Node.parentPayload? - init(name: Swift.String, parent: Components.Schemas.Node.parentPayload? = nil) { + init( + name: Swift.String, + parent: Components.Schemas.Node.parentPayload? = nil + ) { self.name = name self.parent = parent } @@ -1116,27 +1242,51 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct Node: Codable, Hashable, Sendable { public struct Value1Payload: Codable, Hashable, Sendable { public var parent: Components.Schemas.Node? - public init(parent: Components.Schemas.Node? = nil) { self.parent = parent } - public enum CodingKeys: String, CodingKey { case parent } + public init(parent: Components.Schemas.Node? = nil) { + self.parent = parent + } + public enum CodingKeys: String, CodingKey { + case parent + } } public var value1: Components.Schemas.Node.Value1Payload { - get { storage.value.value1 } - _modify { yield &storage.value.value1 } + get { + storage.value.value1 + } + _modify { + yield &storage.value.value1 + } + } + public init(value1: Components.Schemas.Node.Value1Payload) { + storage = .init(value: .init(value1: value1)) + } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) + } + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) } - public init(value1: Components.Schemas.Node.Value1Payload) { storage = .init(value: .init(value1: value1)) } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { struct Value1Payload: Codable, Hashable, Sendable { public var parent: Components.Schemas.Node? - public init(parent: Components.Schemas.Node? = nil) { self.parent = parent } - public enum CodingKeys: String, CodingKey { case parent } + public init(parent: Components.Schemas.Node? = nil) { + self.parent = parent + } + public enum CodingKeys: String, CodingKey { + case parent + } } var value1: Components.Schemas.Node.Value1Payload - init(value1: Components.Schemas.Node.Value1Payload) { self.value1 = value1 } - init(from decoder: any Decoder) throws { value1 = try .init(from: decoder) } - func encode(to encoder: any Encoder) throws { try value1.encode(to: encoder) } + init(value1: Components.Schemas.Node.Value1Payload) { + self.value1 = value1 + } + init(from decoder: any Decoder) throws { + value1 = try .init(from: decoder) + } + func encode(to encoder: any Encoder) throws { + try value1.encode(to: encoder) + } } } } @@ -1157,23 +1307,44 @@ final class SnippetBasedReferenceTests: XCTestCase { public enum Schemas { public struct Node: Codable, Hashable, Sendable { public var value1: Components.Schemas.Node? { - get { storage.value.value1 } - _modify { yield &storage.value.value1 } + get { + storage.value.value1 + } + _modify { + yield &storage.value.value1 + } } public var value2: Swift.String? { - get { storage.value.value2 } - _modify { yield &storage.value.value2 } + get { + storage.value.value2 + } + _modify { + yield &storage.value.value2 + } + } + public init( + value1: Components.Schemas.Node? = nil, + value2: Swift.String? = nil + ) { + storage = .init(value: .init( + value1: value1, + value2: value2 + )) + } + public init(from decoder: any Decoder) throws { + storage = try .init(from: decoder) } - public init(value1: Components.Schemas.Node? = nil, value2: Swift.String? = nil) { - storage = .init(value: .init(value1: value1, value2: value2)) + public func encode(to encoder: any Encoder) throws { + try storage.encode(to: encoder) } - public init(from decoder: any Decoder) throws { storage = try .init(from: decoder) } - public func encode(to encoder: any Encoder) throws { try storage.encode(to: encoder) } private var storage: OpenAPIRuntime.CopyOnWriteBox private struct Storage: Codable, Hashable, Sendable { var value1: Components.Schemas.Node? var value2: Swift.String? - init(value1: Components.Schemas.Node? = nil, value2: Swift.String? = nil) { + init( + value1: Components.Schemas.Node? = nil, + value2: Swift.String? = nil + ) { self.value1 = value1 self.value2 = value2 } @@ -1220,12 +1391,17 @@ final class SnippetBasedReferenceTests: XCTestCase { self = .case2(try decoder.decodeFromSingleValueContainer()) return } catch {} - throw Swift.DecodingError.failedToDecodeOneOfSchema(type: Self.self, codingPath: decoder.codingPath) + throw Swift.DecodingError.failedToDecodeOneOfSchema( + type: Self.self, + codingPath: decoder.codingPath + ) } public func encode(to encoder: any Encoder) throws { switch self { - case let .Node(value): try value.encode(to: encoder) - case let .case2(value): try encoder.encodeToSingleValueContainer(value) + case let .Node(value): + try value.encode(to: encoder) + case let .case2(value): + try encoder.encodeToSingleValueContainer(value) } } } @@ -1270,15 +1446,14 @@ final class SnippetBasedReferenceTests: XCTestCase { public var json: Swift.String { get throws { switch self { - case let .json(body): return body + case let .json(body): + return body } } } } public var body: Components.Responses.BadRequest.Body - public init( - body: Components.Responses.BadRequest.Body - ) { + public init(body: Components.Responses.BadRequest.Body) { self.body = body } } @@ -1308,38 +1483,64 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct MultipleContentTypes: Sendable, Hashable { @frozen public enum Body: Sendable, Hashable { case json(Swift.Int) - public var json: Swift.Int { get throws { - switch self { - case let .json(body): return body - default: try throwUnexpectedResponseBody(expectedContent: "application/json", body: self) + public var json: Swift.Int { + get throws { + switch self { + case let .json(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) + } } - }} + } case application_json_foo_bar(Swift.Int) - public var application_json_foo_bar: Swift.Int { get throws { - switch self { - case let .application_json_foo_bar(body): return body - default: try throwUnexpectedResponseBody(expectedContent: "application/json", body: self) + public var application_json_foo_bar: Swift.Int { + get throws { + switch self { + case let .application_json_foo_bar(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) + } } - }} + } case plainText(OpenAPIRuntime.HTTPBody) - public var plainText: OpenAPIRuntime.HTTPBody { get throws { - switch self { - case let .plainText(body): return body - default: try throwUnexpectedResponseBody(expectedContent: "text/plain", body: self) + public var plainText: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .plainText(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "text/plain", + body: self + ) + } } - }} + } case binary(OpenAPIRuntime.HTTPBody) - public var binary: OpenAPIRuntime.HTTPBody { get throws { - switch self { - case let .binary(body): return body - default: try throwUnexpectedResponseBody(expectedContent: "application/octet-stream", body: self) + public var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/octet-stream", + body: self + ) + } } - }} + } } public var body: Components.Responses.MultipleContentTypes.Body - public init( - body: Components.Responses.MultipleContentTypes.Body - ) { + public init(body: Components.Responses.MultipleContentTypes.Body) { self.body = body } } @@ -1365,12 +1566,11 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct Headers: Sendable, Hashable { public var X_hyphen_Reason: Swift.String? public init(X_hyphen_Reason: Swift.String? = nil) { - self.X_hyphen_Reason = X_hyphen_Reason } + self.X_hyphen_Reason = X_hyphen_Reason + } } public var headers: Components.Responses.BadRequest.Headers - public init( - headers: Components.Responses.BadRequest.Headers = .init() - ) { + public init(headers: Components.Responses.BadRequest.Headers = .init()) { self.headers = headers } } @@ -1397,12 +1597,11 @@ final class SnippetBasedReferenceTests: XCTestCase { public struct Headers: Sendable, Hashable { public var X_hyphen_Reason: Swift.String public init(X_hyphen_Reason: Swift.String) { - self.X_hyphen_Reason = X_hyphen_Reason } + self.X_hyphen_Reason = X_hyphen_Reason + } } public var headers: Components.Responses.BadRequest.Headers - public init( - headers: Components.Responses.BadRequest.Headers - ) { + public init(headers: Components.Responses.BadRequest.Headers) { self.headers = headers } } @@ -1494,8 +1693,12 @@ final class SnippetBasedReferenceTests: XCTestCase { @frozen public enum MyRequestBody: Sendable, Hashable { public struct urlEncodedFormPayload: Codable, Hashable, Sendable { public var foo: Swift.String - public init(foo: Swift.String) { self.foo = foo } - public enum CodingKeys: String, CodingKey { case foo } + public init(foo: Swift.String) { + self.foo = foo + } + public enum CodingKeys: String, CodingKey { + case foo + } } case urlEncodedForm(Components.RequestBodies.MyRequestBody.urlEncodedFormPayload) } @@ -1578,7 +1781,13 @@ final class SnippetBasedReferenceTests: XCTestCase { middlewares: middlewares ) try transport.register( - { try await server.getHealth(request: $0, body: $1, metadata: $2) }, + { + try await server.getHealth( + request: $0, + body: $1, + metadata: $2 + ) + }, method: .get, path: server.apiPathComponentsWithServerPrefix("/health") ) @@ -1598,8 +1807,7 @@ final class SnippetBasedReferenceTests: XCTestCase { serverURL: Foundation.URL = .defaultOpenAPIServerURL, configuration: Configuration = .init(), middlewares: [any ServerMiddleware] = [] - ) throws { - } + ) throws {} """ ) } @@ -1649,13 +1857,16 @@ final class SnippetBasedReferenceTests: XCTestCase { @frozen public enum Body: Sendable, Hashable { case json(Swift.String) public var json: Swift.String { - get throws { switch self { case let .json(body): return body } } + get throws { + switch self { + case let .json(body): + return body + } + } } } public var body: Components.Responses.MyResponse.Body - public init( - body: Components.Responses.MyResponse.Body - ) { + public init(body: Components.Responses.MyResponse.Body) { self.body = body } } @@ -1684,13 +1895,16 @@ final class SnippetBasedReferenceTests: XCTestCase { @frozen public enum Body: Sendable, Hashable { case json(Swift.String) public var json: Swift.String { - get throws { switch self { case let .json(body): return body } } + get throws { + switch self { + case let .json(body): + return body + } + } } } public var body: Components.Responses.MyResponse.Body - public init( - body: Components.Responses.MyResponse.Body - ) { + public init(body: Components.Responses.MyResponse.Body) { self.body = body } } @@ -1750,8 +1964,15 @@ final class SnippetBasedReferenceTests: XCTestCase { } """, client: """ - { input in let path = try converter.renderedPath(template: "/foo", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + { input in + let path = try converter.renderedPath( + template: "/foo", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) suppressMutabilityWarning(&request) try converter.setQueryItemAsURI( in: &request, @@ -1825,14 +2046,25 @@ final class SnippetBasedReferenceTests: XCTestCase { """, types: """ public struct Input: Sendable, Hashable { - @frozen public enum Body: Sendable, Hashable { case json(Swift.String) } + @frozen public enum Body: Sendable, Hashable { + case json(Swift.String) + } public var body: Operations.get_sol_foo.Input.Body - public init(body: Operations.get_sol_foo.Input.Body) { self.body = body } + public init(body: Operations.get_sol_foo.Input.Body) { + self.body = body + } } """, client: """ - { input in let path = try converter.renderedPath(template: "/foo", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + { input in + let path = try converter.renderedPath( + template: "/foo", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) suppressMutabilityWarning(&request) let body: OpenAPIRuntime.HTTPBody? switch input.body { @@ -1847,14 +2079,19 @@ final class SnippetBasedReferenceTests: XCTestCase { } """, server: """ - { request, requestBody, metadata in let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) + { request, requestBody, metadata in + let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.get_sol_foo.Input.Body - if try contentType == nil || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getRequiredRequestBodyAsJSON( Swift.String.self, from: requestBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -1882,14 +2119,25 @@ final class SnippetBasedReferenceTests: XCTestCase { """, types: """ public struct Input: Sendable, Hashable { - @frozen public enum Body: Sendable, Hashable { case json(Swift.String) } + @frozen public enum Body: Sendable, Hashable { + case json(Swift.String) + } public var body: Operations.get_sol_foo.Input.Body - public init(body: Operations.get_sol_foo.Input.Body) { self.body = body } + public init(body: Operations.get_sol_foo.Input.Body) { + self.body = body + } } """, client: """ - { input in let path = try converter.renderedPath(template: "/foo", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + { input in + let path = try converter.renderedPath( + template: "/foo", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) suppressMutabilityWarning(&request) let body: OpenAPIRuntime.HTTPBody? switch input.body { @@ -1904,14 +2152,19 @@ final class SnippetBasedReferenceTests: XCTestCase { } """, server: """ - { request, requestBody, metadata in let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) + { request, requestBody, metadata in + let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.get_sol_foo.Input.Body - if try contentType == nil || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getRequiredRequestBodyAsJSON( Swift.String.self, from: requestBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -1939,18 +2192,30 @@ final class SnippetBasedReferenceTests: XCTestCase { """, types: """ public struct Input: Sendable, Hashable { - @frozen public enum Body: Sendable, Hashable { case json(Swift.String) } + @frozen public enum Body: Sendable, Hashable { + case json(Swift.String) + } public var body: Operations.get_sol_foo.Input.Body? - public init(body: Operations.get_sol_foo.Input.Body? = nil) { self.body = body } + public init(body: Operations.get_sol_foo.Input.Body? = nil) { + self.body = body + } } """, client: """ - { input in let path = try converter.renderedPath(template: "/foo", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + { input in + let path = try converter.renderedPath( + template: "/foo", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) suppressMutabilityWarning(&request) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case .none: body = nil + case .none: + body = nil case let .json(value): body = try converter.setOptionalRequestBodyAsJSON( value, @@ -1962,14 +2227,19 @@ final class SnippetBasedReferenceTests: XCTestCase { } """, server: """ - { request, requestBody, metadata in let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) + { request, requestBody, metadata in + let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.get_sol_foo.Input.Body? - if try contentType == nil || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getOptionalRequestBodyAsJSON( Swift.String.self, from: requestBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -1997,18 +2267,30 @@ final class SnippetBasedReferenceTests: XCTestCase { """, types: """ public struct Input: Sendable, Hashable { - @frozen public enum Body: Sendable, Hashable { case json(Swift.String) } + @frozen public enum Body: Sendable, Hashable { + case json(Swift.String) + } public var body: Operations.get_sol_foo.Input.Body? - public init(body: Operations.get_sol_foo.Input.Body? = nil) { self.body = body } + public init(body: Operations.get_sol_foo.Input.Body? = nil) { + self.body = body + } } """, client: """ - { input in let path = try converter.renderedPath(template: "/foo", parameters: []) - var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + { input in + let path = try converter.renderedPath( + template: "/foo", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) suppressMutabilityWarning(&request) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case .none: body = nil + case .none: + body = nil case let .json(value): body = try converter.setOptionalRequestBodyAsJSON( value, @@ -2020,14 +2302,19 @@ final class SnippetBasedReferenceTests: XCTestCase { } """, server: """ - { request, requestBody, metadata in let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) + { request, requestBody, metadata in + let contentType = converter.extractContentTypeIfPresent(in: request.headerFields) let body: Operations.get_sol_foo.Input.Body? - if try contentType == nil || converter.isMatchingContentType(received: contentType, expectedRaw: "application/json") - { + if try contentType == nil || converter.isMatchingContentType( + received: contentType, + expectedRaw: "application/json" + ) { body = try await converter.getOptionalRequestBodyAsJSON( Swift.String.self, from: requestBody, - transforming: { value in .json(value) } + transforming: { value in + .json(value) + } ) } else { throw converter.makeUnexpectedContentTypeError(contentType: contentType) @@ -2061,14 +2348,15 @@ final class SnippetBasedReferenceTests: XCTestCase { case json(OpenAPIRuntime.Base64EncodedData) public var json: OpenAPIRuntime.Base64EncodedData { get throws { - switch self { case let .json(body): return body } + switch self { + case let .json(body): + return body + } } } } public var body: Components.Responses.MyResponse.Body - public init( - body: Components.Responses.MyResponse.Body - ) { + public init(body: Components.Responses.MyResponse.Body) { self.body = body } } @@ -2306,9 +2594,12 @@ private func XCTAssertSwiftEquivalent( file: StaticString = #filePath, line: UInt = #line ) throws { + let renderer = TextBasedRenderer.default + renderer.renderDeclaration(declaration.strippingComments) + let contents = renderer.renderedContents() try XCTAssertEqualWithDiff( - TextBasedRenderer().renderedDeclaration(declaration.strippingComments).swiftFormatted, - expectedSwift.swiftFormatted, + contents, + expectedSwift, file: file, line: line ) @@ -2320,9 +2611,12 @@ private func XCTAssertSwiftEquivalent( file: StaticString = #filePath, line: UInt = #line ) throws { + let renderer = TextBasedRenderer.default + renderer.renderCodeBlock(codeBlock) + let contents = renderer.renderedContents() try XCTAssertEqualWithDiff( - TextBasedRenderer().renderedCodeBlock(codeBlock).swiftFormatted, - expectedSwift.swiftFormatted, + contents, + expectedSwift, file: file, line: line ) @@ -2334,9 +2628,12 @@ private func XCTAssertSwiftEquivalent( file: StaticString = #filePath, line: UInt = #line ) throws { + let renderer = TextBasedRenderer.default + renderer.renderExpression(expression) + let contents = renderer.renderedContents() try XCTAssertEqualWithDiff( - TextBasedRenderer().renderedExpression(expression).swiftFormatted, - expectedSwift.swiftFormatted, + contents, + expectedSwift, file: file, line: line ) diff --git a/scripts/run-swift-format.sh b/scripts/run-swift-format.sh index 878942e1..023d426d 100644 --- a/scripts/run-swift-format.sh +++ b/scripts/run-swift-format.sh @@ -34,7 +34,7 @@ if [ "${SWIFT_FORMAT_RC}" -ne 0 ]; then To fix, run the following command: - % git ls-files -z '*.swift' | xargs -0 swift-format --in-place --parallel + % git ls-files -z '*.swift' | grep -z -v -e 'Tests/OpenAPIGeneratorReferenceTests/Resources' -e 'Sources/swift-openapi-generator/Documentation.docc' | xargs -0 swift-format --in-place --parallel " exit "${SWIFT_FORMAT_RC}" fi