diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/CommentExtensions.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/CommentExtensions.swift index c7f6e116..305c45dd 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/CommentExtensions.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/CommentExtensions.swift @@ -133,31 +133,46 @@ extension ResponseKind { extension Comment { - /// Returns a documentation comment for an OpenAPI operation. + /// Returns a reference documentation string to attach to the generated function for an operation. + init(from operationDescription: OperationDescription) { + self.init( + summary: operationDescription.operation.summary, + description: operationDescription.operation.description, + httpMethod: operationDescription.httpMethod, + path: operationDescription.path, + openAPIDocumentPath: operationDescription.jsonPathComponent + ) + } + + /// Returns a reference documentation string to attach to the generated function for an operation. /// - /// For example: "Operation `getPet` performs `GET` on `/pets/{petId}`". /// - Parameters: - /// - operationID: The identifier of the OpenAPI operation. - /// - method: The HTTP method of the OpenAPI operation. - /// - path: The URL path of the OpenAPI operation. - static func operation( - operationID: String?, - method: OpenAPI.HttpMethod, - path: OpenAPI.Path - ) -> Self { - let operationName: String - if let operationID { - operationName = "`\(operationID)` " - } else { - operationName = "" - } + /// - summary: A short summary of what the operation does. + /// - description: A verbose explanation of the operation behavior. + /// - path: The path associated with this operation. + /// - httpMethod: The HTTP method associated with this operation. + /// - openAPIDocumentPath: JSONPath to the operation element in the OpenAPI document. + init( + summary: String?, + description: String?, + httpMethod: OpenAPI.HttpMethod, + path: OpenAPI.Path, + openAPIDocumentPath: String + ) { var lines: [String] = [] - lines.append("Operation \(operationName)performs `\(method.rawValue.uppercased())` on `\(path.rawValue)`") - if let operationID { + if let summary { + lines.append(summary) + lines.append("") + } + if let description { + lines.append(description) lines.append("") - lines.append("- Remark: Generated from the `\(operationID)` operation.") } - return .doc(lines.joined(separator: "\n")) + lines.append(contentsOf: [ + "- Remark: HTTP `\(httpMethod.rawValue.uppercased()) \(path.rawValue)`.", + "- Remark: Generated from `\(openAPIDocumentPath)`.", + ]) + self = .doc(lines.joined(separator: "\n")) } /// Returns a documentation comment for the Operations namespace. diff --git a/Sources/_OpenAPIGeneratorCore/Translator/Operations/OperationDescription.swift b/Sources/_OpenAPIGeneratorCore/Translator/Operations/OperationDescription.swift index c9b2be36..19d0ae9c 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/Operations/OperationDescription.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/Operations/OperationDescription.swift @@ -92,11 +92,7 @@ extension OperationDescription { /// Returns a documentation comment for the method implementing /// the OpenAPI operation. var comment: Comment { - .operation( - operationID: operation.operationId, - method: httpMethod, - path: path - ) + .init(from: self) } /// Returns the type name of the namespace unique to the operation. diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift index ff48c27d..990bf655 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift @@ -33,9 +33,12 @@ public struct Client: APIProtocol { ) } private var converter: Converter { client.converter } - /// Operation `listPets` performs `GET` on `/pets` + /// List all pets /// - /// - Remark: Generated from the `listPets` operation. + /// You can fetch all the pets here + /// + /// - Remark: HTTP `GET /pets`. + /// - Remark: Generated from `#/paths//pets/get(listPets)`. public func listPets(_ input: Operations.listPets.Input) async throws -> Operations.listPets.Output { @@ -124,9 +127,10 @@ public struct Client: APIProtocol { } ) } - /// Operation `createPet` performs `POST` on `/pets` + /// Create a pet /// - /// - Remark: Generated from the `createPet` operation. + /// - Remark: HTTP `POST /pets`. + /// - Remark: Generated from `#/paths//pets/post(createPet)`. public func createPet(_ input: Operations.createPet.Input) async throws -> Operations.createPet.Output { @@ -207,9 +211,8 @@ public struct Client: APIProtocol { } ) } - /// Operation `probe` performs `POST` on `/probe` - /// - /// - Remark: Generated from the `probe` operation. + /// - Remark: HTTP `POST /probe`. + /// - Remark: Generated from `#/paths//probe/post(probe)`. public func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output { try await client.send( input: input, @@ -230,9 +233,10 @@ public struct Client: APIProtocol { } ) } - /// Operation `updatePet` performs `PATCH` on `/pets/{petId}` + /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. /// - /// - Remark: Generated from the `updatePet` operation. + /// - Remark: HTTP `PATCH /pets/{petId}`. + /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. public func updatePet(_ input: Operations.updatePet.Input) async throws -> Operations.updatePet.Output { @@ -289,9 +293,10 @@ public struct Client: APIProtocol { } ) } - /// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar` + /// Upload an avatar /// - /// - Remark: Generated from the `uploadAvatarForPet` operation. + /// - 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 { diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift index d1edcd47..4e8de0b2 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift @@ -58,9 +58,12 @@ extension APIProtocol { } } fileprivate extension UniversalServer where APIHandler: APIProtocol { - /// Operation `listPets` performs `GET` on `/pets` + /// List all pets /// - /// - Remark: Generated from the `listPets` operation. + /// You can fetch all the pets here + /// + /// - Remark: HTTP `GET /pets`. + /// - Remark: Generated from `#/paths//pets/get(listPets)`. func listPets(request: Request, metadata: ServerRequestMetadata) async throws -> Response { try await handle( request: request, @@ -167,9 +170,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { } ) } - /// Operation `createPet` performs `POST` on `/pets` + /// Create a pet /// - /// - Remark: Generated from the `createPet` operation. + /// - Remark: HTTP `POST /pets`. + /// - Remark: Generated from `#/paths//pets/post(createPet)`. func createPet(request: Request, metadata: ServerRequestMetadata) async throws -> Response { try await handle( request: request, @@ -261,9 +265,8 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { } ) } - /// Operation `probe` performs `POST` on `/probe` - /// - /// - Remark: Generated from the `probe` operation. + /// - Remark: HTTP `POST /probe`. + /// - Remark: Generated from `#/paths//probe/post(probe)`. func probe(request: Request, metadata: ServerRequestMetadata) async throws -> Response { try await handle( request: request, @@ -295,9 +298,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { } ) } - /// Operation `updatePet` performs `PATCH` on `/pets/{petId}` + /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. /// - /// - Remark: Generated from the `updatePet` operation. + /// - Remark: HTTP `PATCH /pets/{petId}`. + /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. func updatePet(request: Request, metadata: ServerRequestMetadata) async throws -> Response { try await handle( request: request, @@ -363,9 +367,10 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol { } ) } - /// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar` + /// Upload an avatar /// - /// - Remark: Generated from the `uploadAvatarForPet` operation. + /// - Remark: HTTP `PUT /pets/{petId}/avatar`. + /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. func uploadAvatarForPet(request: Request, metadata: ServerRequestMetadata) async throws -> Response { diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift index 3a2f694f..45c74cc9 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift @@ -7,25 +7,30 @@ import Foundation #endif /// A type that performs HTTP operations defined by the OpenAPI document. public protocol APIProtocol: Sendable { - /// Operation `listPets` performs `GET` on `/pets` + /// List all pets /// - /// - Remark: Generated from the `listPets` operation. + /// You can fetch all the pets here + /// + /// - Remark: HTTP `GET /pets`. + /// - Remark: Generated from `#/paths//pets/get(listPets)`. func listPets(_ input: Operations.listPets.Input) async throws -> Operations.listPets.Output - /// Operation `createPet` performs `POST` on `/pets` + /// Create a pet /// - /// - Remark: Generated from the `createPet` operation. + /// - Remark: HTTP `POST /pets`. + /// - Remark: Generated from `#/paths//pets/post(createPet)`. func createPet(_ input: Operations.createPet.Input) async throws -> Operations.createPet.Output - /// Operation `probe` performs `POST` on `/probe` - /// - /// - Remark: Generated from the `probe` operation. + /// - Remark: HTTP `POST /probe`. + /// - Remark: Generated from `#/paths//probe/post(probe)`. func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output - /// Operation `updatePet` performs `PATCH` on `/pets/{petId}` + /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. /// - /// - Remark: Generated from the `updatePet` operation. + /// - Remark: HTTP `PATCH /pets/{petId}`. + /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. func updatePet(_ input: Operations.updatePet.Input) async throws -> Operations.updatePet.Output - /// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar` + /// Upload an avatar /// - /// - Remark: Generated from the `uploadAvatarForPet` operation. + /// - 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 } @@ -670,9 +675,12 @@ public enum Components { } /// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. public enum Operations { - /// Operation `listPets` performs `GET` on `/pets` + /// List all pets /// - /// - Remark: Generated from the `listPets` operation. + /// You can fetch all the pets here + /// + /// - Remark: HTTP `GET /pets`. + /// - Remark: Generated from `#/paths//pets/get(listPets)`. public enum listPets { public static let id: String = "listPets" public struct Input: Sendable, Equatable, Hashable { @@ -887,9 +895,10 @@ public enum Operations { case `default`(statusCode: Int, Operations.listPets.Output.Default) } } - /// Operation `createPet` performs `POST` on `/pets` + /// Create a pet /// - /// - Remark: Generated from the `createPet` operation. + /// - Remark: HTTP `POST /pets`. + /// - Remark: Generated from `#/paths//pets/post(createPet)`. public enum createPet { public static let id: String = "createPet" public struct Input: Sendable, Equatable, Hashable { @@ -995,9 +1004,8 @@ public enum Operations { case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) } } - /// Operation `probe` performs `POST` on `/probe` - /// - /// - Remark: Generated from the `probe` operation. + /// - Remark: HTTP `POST /probe`. + /// - Remark: Generated from `#/paths//probe/post(probe)`. public enum probe { public static let id: String = "probe" public struct Input: Sendable, Equatable, Hashable { @@ -1081,9 +1089,10 @@ public enum Operations { case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) } } - /// Operation `updatePet` performs `PATCH` on `/pets/{petId}` + /// Update just a specific property of an existing pet. Nothing is updated if no request body is provided. /// - /// - Remark: Generated from the `updatePet` operation. + /// - Remark: HTTP `PATCH /pets/{petId}`. + /// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)`. public enum updatePet { public static let id: String = "updatePet" public struct Input: Sendable, Equatable, Hashable { @@ -1212,9 +1221,10 @@ public enum Operations { case undocumented(statusCode: Int, OpenAPIRuntime.UndocumentedPayload) } } - /// Operation `uploadAvatarForPet` performs `PUT` on `/pets/{petId}/avatar` + /// Upload an avatar /// - /// - Remark: Generated from the `uploadAvatarForPet` operation. + /// - Remark: HTTP `PUT /pets/{petId}/avatar`. + /// - Remark: Generated from `#/paths//pets/{petId}/avatar/put(uploadAvatarForPet)`. public enum uploadAvatarForPet { public static let id: String = "uploadAvatarForPet" public struct Input: Sendable, Equatable, Hashable {