Skip to content

Commit 9727261

Browse files
authored
Generate a static property to create a responses without any parameters (#656)
1 parent ecdaa49 commit 9727261

File tree

3 files changed

+77
-13
lines changed

3 files changed

+77
-13
lines changed

Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponseOutcome.swift

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,18 @@ extension TypesFileTranslator {
2323
/// - operation: The OpenAPI operation.
2424
/// - operationJSONPath: The JSON path to the operation in the OpenAPI
2525
/// document.
26-
/// - Returns: A declaration of the enum case and a declaration of the
26+
/// - Returns: A tuple containing a declaration of the enum case, a declaration of the
2727
/// structure unique to the response that contains the response headers
28-
/// and a body payload.
28+
/// and a body payload, a declaration of a throwing getter and, an optional convenience static property.
2929
/// - Throws: An error if there's an issue generating the declarations, such
3030
/// as unsupported response types or invalid definitions.
3131
func translateResponseOutcomeInTypes(
3232
_ outcome: OpenAPI.Operation.ResponseOutcome,
3333
operation: OperationDescription,
3434
operationJSONPath: String
35-
) throws -> (payloadStruct: Declaration?, enumCase: Declaration, throwingGetter: Declaration) {
36-
35+
) throws -> (
36+
payloadStruct: Declaration?, enumCase: Declaration, staticMember: Declaration?, throwingGetter: Declaration
37+
) {
3738
let typedResponse = try typedResponse(from: outcome, operation: operation)
3839
let responseStructTypeName = typedResponse.typeUsage.typeName
3940
let responseKind = outcome.status.value.asKind
@@ -55,14 +56,36 @@ extension TypesFileTranslator {
5556
}
5657
associatedValues.append(.init(type: .init(responseStructTypeName)))
5758

58-
let enumCaseDesc = EnumCaseDescription(name: enumCaseName, kind: .nameWithAssociatedValues(associatedValues))
59-
let enumCaseDecl: Declaration = .commentable(
60-
responseKind.docComment(
61-
userDescription: typedResponse.response.description,
62-
jsonPath: operationJSONPath + "/responses/" + responseKind.jsonPathComponent
63-
),
64-
.enumCase(enumCaseDesc)
59+
let enumCaseDocComment = responseKind.docComment(
60+
userDescription: typedResponse.response.description,
61+
jsonPath: operationJSONPath + "/responses/" + responseKind.jsonPathComponent
6562
)
63+
let enumCaseDesc = EnumCaseDescription(name: enumCaseName, kind: .nameWithAssociatedValues(associatedValues))
64+
let enumCaseDecl: Declaration = .commentable(enumCaseDocComment, .enumCase(enumCaseDesc))
65+
66+
let staticMemberDecl: Declaration?
67+
let responseHasNoHeaders = typedResponse.response.headers?.isEmpty ?? true
68+
let responseHasNoContent = typedResponse.response.content.isEmpty
69+
if responseHasNoContent && responseHasNoHeaders && !responseKind.wantsStatusCode {
70+
let staticMemberDesc = VariableDescription(
71+
accessModifier: config.access,
72+
isStatic: true,
73+
kind: .var,
74+
left: .identifier(.pattern(enumCaseName)),
75+
type: .member(["Self"]),
76+
getter: [
77+
.expression(
78+
.functionCall(
79+
calledExpression: .dot(enumCaseName),
80+
arguments: [.functionCall(calledExpression: .dot("init"))]
81+
)
82+
)
83+
]
84+
)
85+
staticMemberDecl = .commentable(enumCaseDocComment, .variable(staticMemberDesc))
86+
} else {
87+
staticMemberDecl = nil
88+
}
6689

6790
let throwingGetterDesc = VariableDescription(
6891
accessModifier: config.access,
@@ -113,7 +136,7 @@ extension TypesFileTranslator {
113136
)
114137
let throwingGetterDecl = Declaration.commentable(throwingGetterComment, .variable(throwingGetterDesc))
115138

116-
return (responseStructDecl, enumCaseDecl, throwingGetterDecl)
139+
return (responseStructDecl, enumCaseDecl, staticMemberDecl, throwingGetterDecl)
117140
}
118141
}
119142

Sources/_OpenAPIGeneratorCore/Translator/TypesTranslator/translateOperations.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ extension TypesFileTranslator {
143143
let documentedMembers: [Declaration] = documentedOutcomes.flatMap {
144144
inlineResponseDecl,
145145
caseDecl,
146-
throwingGetter in [inlineResponseDecl, caseDecl, throwingGetter].compactMap { $0 }
146+
staticDecl,
147+
throwingGetter in [inlineResponseDecl, caseDecl, staticDecl, throwingGetter].compactMap { $0 }
147148
}
148149

149150
let allMembers: [Declaration]

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,6 +2279,14 @@ public enum Operations {
22792279
///
22802280
/// HTTP response code: `204 noContent`.
22812281
case noContent(Operations.createPetWithForm.Output.NoContent)
2282+
/// Successfully created pet using a url form
2283+
///
2284+
/// - Remark: Generated from `#/paths//pets/create/post(createPetWithForm)/responses/204`.
2285+
///
2286+
/// HTTP response code: `204 noContent`.
2287+
public static var noContent: Self {
2288+
.noContent(.init())
2289+
}
22822290
/// The associated value of the enum case if `self` is `.noContent`.
22832291
///
22842292
/// - Throws: An error if `self` is not `.noContent`.
@@ -2499,6 +2507,14 @@ public enum Operations {
24992507
///
25002508
/// HTTP response code: `202 accepted`.
25012509
case accepted(Operations.postStats.Output.Accepted)
2510+
/// Accepted data.
2511+
///
2512+
/// - Remark: Generated from `#/paths//pets/stats/post(postStats)/responses/202`.
2513+
///
2514+
/// HTTP response code: `202 accepted`.
2515+
public static var accepted: Self {
2516+
.accepted(.init())
2517+
}
25022518
/// The associated value of the enum case if `self` is `.accepted`.
25032519
///
25042520
/// - Throws: An error if `self` is not `.accepted`.
@@ -2541,6 +2557,14 @@ public enum Operations {
25412557
///
25422558
/// HTTP response code: `204 noContent`.
25432559
case noContent(Operations.probe.Output.NoContent)
2560+
/// Ack
2561+
///
2562+
/// - Remark: Generated from `#/paths//probe//post(probe)/responses/204`.
2563+
///
2564+
/// HTTP response code: `204 noContent`.
2565+
public static var noContent: Self {
2566+
.noContent(.init())
2567+
}
25442568
/// The associated value of the enum case if `self` is `.noContent`.
25452569
///
25462570
/// - Throws: An error if `self` is not `.noContent`.
@@ -2626,6 +2650,14 @@ public enum Operations {
26262650
///
26272651
/// HTTP response code: `204 noContent`.
26282652
case noContent(Operations.updatePet.Output.NoContent)
2653+
/// Successfully updated
2654+
///
2655+
/// - Remark: Generated from `#/paths//pets/{petId}/patch(updatePet)/responses/204`.
2656+
///
2657+
/// HTTP response code: `204 noContent`.
2658+
public static var noContent: Self {
2659+
.noContent(.init())
2660+
}
26292661
/// The associated value of the enum case if `self` is `.noContent`.
26302662
///
26312663
/// - Throws: An error if `self` is not `.noContent`.
@@ -3098,6 +3130,14 @@ public enum Operations {
30983130
///
30993131
/// HTTP response code: `202 accepted`.
31003132
case accepted(Operations.multipartUploadTyped.Output.Accepted)
3133+
/// Successfully accepted the data.
3134+
///
3135+
/// - Remark: Generated from `#/paths//pets/multipart-typed/post(multipartUploadTyped)/responses/202`.
3136+
///
3137+
/// HTTP response code: `202 accepted`.
3138+
public static var accepted: Self {
3139+
.accepted(.init())
3140+
}
31013141
/// The associated value of the enum case if `self` is `.accepted`.
31023142
///
31033143
/// - Throws: An error if `self` is not `.accepted`.

0 commit comments

Comments
 (0)