-
Notifications
You must be signed in to change notification settings - Fork 128
Calculate required response header parameters for initialize #150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calculate required response header parameters for initialize #150
Conversation
… least one required response header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @takeshi-1000, thanks for picking this up!
I think the fix can be achieved using a little more general method, which will be usable in more places than just response headers.
Step 1: Define a computed property on StructBlueprint
that tells you whether the struct has an empty initializer. For example:
extension StructBlueprint {
/// A Boolean value indicating whether the struct can be initialized using
/// an empty initializer.
///
/// For example, when all the properties of the struct have a default value,
/// the struct can be initialized using `Foo()`. This is important for
/// other types referencing this type.
var hasEmptyInit: Bool {
// If at least one property requires an explicit value, this struct
// cannot have an empty initializer.
!properties.contains(where: { $0.defaultValue == nil })
}
}
Step 2: Use this computed property instead of checking if headers property array is empty (like we do today).
I haven't tested this fully, but my local diff when I tried it looked something like:
diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/StructBlueprint.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/StructBlueprint.swift
index 244c269..55ffffa 100644
--- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/StructBlueprint.swift
+++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/StructBlueprint.swift
@@ -80,6 +80,21 @@ struct StructBlueprint {
var properties: [PropertyBlueprint]
}
+extension StructBlueprint {
+
+ /// A Boolean value indicating whether the struct can be initialized using
+ /// an empty initializer.
+ ///
+ /// For example, when all the properties of the struct have a default value,
+ /// the struct can be initialized using `Foo()`. This is important for
+ /// other types referencing this type.
+ var hasEmptyInit: Bool {
+ // If at least one property requires an explicit value, this struct
+ // cannot have an empty initializer.
+ !properties.contains(where: { $0.defaultValue == nil })
+ }
+}
+
/// A structure that contains the information about an OpenAPI object property
/// that is required to generate a matching Swift property.
struct PropertyBlueprint {
diff --git a/Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponse.swift b/Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponse.swift
index da2eada..60c7383 100644
--- a/Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponse.swift
+++ b/Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponse.swift
@@ -36,20 +36,21 @@ extension TypesFileTranslator {
let headerProperties: [PropertyBlueprint] = try headers.map { header in
try parseResponseHeaderAsProperty(for: header)
}
+ let headersStructBlueprint: StructBlueprint = .init(
+ comment: nil,
+ access: config.access,
+ typeName: headersTypeName,
+ conformances: Constants.Operation.Output.Payload.Headers.conformances,
+ properties: headerProperties
+ )
let headersStructDecl = translateStructBlueprint(
- .init(
- comment: nil,
- access: config.access,
- typeName: headersTypeName,
- conformances: Constants.Operation.Output.Payload.Headers.conformances,
- properties: headerProperties
- )
+ headersStructBlueprint
)
let headersProperty = PropertyBlueprint(
comment: .doc("Received HTTP response headers"),
originalName: Constants.Operation.Output.Payload.Headers.variableName,
typeUsage: headersTypeName.asUsage,
- default: headerProperties.isEmpty ? .emptyInit : nil,
+ default: headersStructBlueprint.hasEmptyInit ? .emptyInit : nil,
associatedDeclarations: [
headersStructDecl
],
See if the above actually works with your snippet-based tests (which are great, thanks for adding them!). The file-based reference tests can be reverted, I don't think we need to expand them here, the snippet tests cover this well.
Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml
Outdated
Show resolved
Hide resolved
Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift
Outdated
Show resolved
Hide resolved
Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift
Outdated
Show resolved
Hide resolved
…re is at least one required response header." This reverts commit f92eb0d.
@czechboy0 |
Awesome, thank you very much @takeshi-1000! Can you just update the PR description to reflect the changes now, and otherwise this should be ready to go? 🙏 |
@czechboy0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of minor nits from me, otherwise looks super—thank you!
Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/StructBlueprint.swift
Outdated
Show resolved
Hide resolved
Sources/_OpenAPIGeneratorCore/Translator/Responses/translateResponse.swift
Show resolved
Hide resolved
…eprint.swift Co-authored-by: Si Beaumont <[email protected]>
Motivation
Resolve #30
Modifications
Define a computed property on StructBlueprint that tells you whether the struct has an empty initializer, and it is used when response header struct blueprint is created.
Result
If one or more required response header parameters are present,
Generates code that needs to set request header parameters when create response.
For example you define the yaml below
Types.swift
is generated like below, and you can set the "headers" parameter if necessary ,if you set required true
Types.swift
is generated like below, and you should set reponse headers when initializeTest Plan
Add test optional response header in SnipetBasedReferenceTests, and modify ReferenceSource a little.