diff --git a/docs/generators/rust.md b/docs/generators/rust.md index 221c61145612..cea418667447 100644 --- a/docs/generators/rust.md +++ b/docs/generators/rust.md @@ -9,6 +9,7 @@ sidebar_label: rust |library|library template (sub-template) to use.|
**hyper**
HTTP client: Hyper.
**reqwest**
HTTP client: Reqwest.
|hyper| |packageName|Rust package name (convention: lowercase).| |openapi| |packageVersion|Rust package version.| |1.0.0| +|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false| ## IMPORT MAPPING diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java index 63ba78364309..1bda56c26945 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java @@ -356,4 +356,7 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case, public static final String LEGACY_DISCRIMINATOR_BEHAVIOR_DESC = "This flag is used by OpenAPITools codegen to influence the processing of the discriminator attribute in OpenAPI documents. This flag has no impact if the OAS document does not use the discriminator attribute. The default value of this flag is set in each language-specific code generator (e.g. Python, Java, go...)using the method toModelName. " + "Note to developers supporting a language generator in OpenAPITools; to fully support the discriminator attribute as defined in the OAS specification 3.x, language generators should set this flag to true by default; however this requires updating the mustache templates to generate a language-specific discriminator lookup function that iterates over {{#mappedModels}} and does not iterate over {{children}}, {{#anyOf}}, or {{#oneOf}}."; + public static final String USE_SINGLE_REQUEST_PARAMETER = "useSingleRequestParameter"; + public static final String USE_SINGLE_REQUEST_PARAMETER_DESC = "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter."; + } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustClientCodegen.java index 1f81ba8133be..706083b50dc4 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustClientCodegen.java @@ -21,6 +21,7 @@ import io.swagger.v3.oas.models.media.ArraySchema; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.StringSchema; +import io.swagger.v3.parser.util.SchemaTypeUtil; import org.openapitools.codegen.*; import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.utils.ModelUtils; @@ -37,6 +38,8 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig { private static final Logger LOGGER = LoggerFactory.getLogger(RustClientCodegen.class); + private boolean useSingleRequestParameter = false; + public static final String PACKAGE_NAME = "packageName"; public static final String PACKAGE_VERSION = "packageVersion"; @@ -167,6 +170,8 @@ public RustClientCodegen() { .defaultValue("1.0.0")); cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC) .defaultValue(Boolean.TRUE.toString())); + cliOptions.add(new CliOption(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, CodegenConstants.USE_SINGLE_REQUEST_PARAMETER_DESC, SchemaTypeUtil.BOOLEAN_TYPE) + .defaultValue(Boolean.FALSE.toString())); supportedLibraries.put(HYPER_LIBRARY, "HTTP client: Hyper."); supportedLibraries.put(REQWEST_LIBRARY, "HTTP client: Reqwest."); @@ -209,7 +214,7 @@ public Map postProcessAllModels(Map objs) { CodegenModel cm = (CodegenModel) mo.get("model"); if (cm.discriminator != null) { List discriminatorVars = new ArrayList<>(); - for(CodegenDiscriminator.MappedModel mappedModel: cm.discriminator.getMappedModels()) { + for (CodegenDiscriminator.MappedModel mappedModel : cm.discriminator.getMappedModels()) { CodegenModel model = allModels.get(mappedModel.getModelName()); Map mas = new HashMap<>(); mas.put("modelName", camelize(mappedModel.getModelName())); @@ -247,13 +252,18 @@ public void processOpts() { setPackageVersion("1.0.0"); } + if (additionalProperties.containsKey(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER)) { + this.setUseSingleRequestParameter(convertPropertyToBoolean(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER)); + } + writePropertyBack(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, getUseSingleRequestParameter()); + additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion); additionalProperties.put("apiDocPath", apiDocPath); additionalProperties.put("modelDocPath", modelDocPath); - if ( HYPER_LIBRARY.equals(getLibrary())){ + if (HYPER_LIBRARY.equals(getLibrary())) { additionalProperties.put(HYPER_LIBRARY, "true"); } else if (REQWEST_LIBRARY.equals(getLibrary())) { additionalProperties.put(REQWEST_LIBRARY, "true"); @@ -283,6 +293,14 @@ public void processOpts() { supportingFiles.add(new SupportingFile(getLibrary() + "/api_mod.mustache", apiFolder, "mod.rs")); } + private boolean getUseSingleRequestParameter() { + return useSingleRequestParameter; + } + + private void setUseSingleRequestParameter(boolean useSingleRequestParameter) { + this.useSingleRequestParameter = useSingleRequestParameter; + } + @Override public String escapeReservedWord(String name) { if (this.reservedWordsMappings().containsKey(name)) { @@ -471,6 +489,11 @@ public Map postProcessOperationsWithModels(Map o operation.httpMethod = operation.httpMethod.toLowerCase(Locale.ROOT); } + // add support for single request parameter using x-group-parameters + if (!operation.vendorExtensions.containsKey("x-group-parameters") && useSingleRequestParameter) { + operation.vendorExtensions.put("x-group-parameters", Boolean.TRUE); + } + // update return type to conform to rust standard /* if (operation.returnType != null) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java index 208d42834eb7..990c206fca5d 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java @@ -70,7 +70,7 @@ public TypeScriptFetchClientCodegen() { supportModelPropertyNaming(CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.camelCase); this.cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json")); this.cliOptions.add(new CliOption(WITH_INTERFACES, "Setting this property to true will generate interfaces next to the default class implementations.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); - this.cliOptions.add(new CliOption(USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.TRUE.toString())); + this.cliOptions.add(new CliOption(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, CodegenConstants.USE_SINGLE_REQUEST_PARAMETER_DESC, SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.TRUE.toString())); this.cliOptions.add(new CliOption(PREFIX_PARAMETER_INTERFACES, "Setting this property to true will generate parameter interface declarations prefixed with API class name to avoid name conflicts.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); this.cliOptions.add(new CliOption(TYPESCRIPT_THREE_PLUS, "Setting this property to true will generate TypeScript 3.6+ compatible code.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); } @@ -118,10 +118,10 @@ public void processOpts() { supportingFiles.add(new SupportingFile("index.mustache", sourceDir, "index.ts")); supportingFiles.add(new SupportingFile("runtime.mustache", sourceDir, "runtime.ts")); - if (additionalProperties.containsKey(USE_SINGLE_REQUEST_PARAMETER)) { - this.setUseSingleRequestParameter(convertPropertyToBoolean(USE_SINGLE_REQUEST_PARAMETER)); + if (additionalProperties.containsKey(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER)) { + this.setUseSingleRequestParameter(convertPropertyToBoolean(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER)); } - writePropertyBack(USE_SINGLE_REQUEST_PARAMETER, getUseSingleRequestParameter()); + writePropertyBack(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, getUseSingleRequestParameter()); if (additionalProperties.containsKey(PREFIX_PARAMETER_INTERFACES)) { this.setPrefixParameterInterfaces(convertPropertyToBoolean(PREFIX_PARAMETER_INTERFACES)); diff --git a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache index dc2a9edb488e..18602ce77abf 100644 --- a/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache +++ b/modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache @@ -20,10 +20,37 @@ impl {{{classname}}}Client { } } +{{#operations}} +{{#operation}} + {{#vendorExtensions.x-group-parameters}} + {{#allParams}} + {{#-first}} + /// struct for passing parameters to the method `{{operationId}}` + #[derive(Clone, Debug)] + struct {{{operationIdCamelCase}}}Params { + {{/-first}} + {{#description}} + /// {{{.}}} + {{/description}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}String{{/isString}}{{#isUuid}}String{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{#hasMore}}, {{/hasMore}} + {{#-last}} + } + + {{/-last}} + {{/allParams}} + {{/vendorExtensions.x-group-parameters}} +{{/operation}} +{{/operations}} + pub trait {{{classname}}} { {{#operations}} {{#operation}} + {{#vendorExtensions.x-group-parameters}} + fn {{{operationId}}}(&self{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error>; + {{/vendorExtensions.x-group-parameters}} + {{^vendorExtensions.x-group-parameters}} fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}&str{{/isString}}{{#isUuid}}&str{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error>; + {{/vendorExtensions.x-group-parameters}} {{/operation}} {{/operations}} } @@ -31,7 +58,17 @@ pub trait {{{classname}}} { impl {{{classname}}} for {{{classname}}}Client { {{#operations}} {{#operation}} + {{#vendorExtensions.x-group-parameters}} + fn {{{operationId}}}(&self{{#allParams}}{{#-first}}, params: {{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error> { + // unbox the parameters + {{#allParams}} + let {{paramName}} = params.{{paramName}}; + {{/allParams}} + + {{/vendorExtensions.x-group-parameters}} + {{^vendorExtensions.x-group-parameters}} fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}&str{{/isString}}{{#isUuid}}&str{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error> { + {{/vendorExtensions.x-group-parameters}} let configuration: &configuration::Configuration = self.configuration.borrow(); let client = &configuration.client; diff --git a/samples/client/petstore/rust/hyper/fileResponseTest/.openapi-generator/VERSION b/samples/client/petstore/rust/hyper/fileResponseTest/.openapi-generator/VERSION index c3a2c7076fa8..d99e7162d01f 100644 --- a/samples/client/petstore/rust/hyper/fileResponseTest/.openapi-generator/VERSION +++ b/samples/client/petstore/rust/hyper/fileResponseTest/.openapi-generator/VERSION @@ -1 +1 @@ -4.2.0-SNAPSHOT \ No newline at end of file +5.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/rust/hyper/petstore/.openapi-generator/VERSION b/samples/client/petstore/rust/hyper/petstore/.openapi-generator/VERSION index c3a2c7076fa8..d99e7162d01f 100644 --- a/samples/client/petstore/rust/hyper/petstore/.openapi-generator/VERSION +++ b/samples/client/petstore/rust/hyper/petstore/.openapi-generator/VERSION @@ -1 +1 @@ -4.2.0-SNAPSHOT \ No newline at end of file +5.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/rust/hyper/rust-test/.openapi-generator/VERSION b/samples/client/petstore/rust/hyper/rust-test/.openapi-generator/VERSION index c3a2c7076fa8..d99e7162d01f 100644 --- a/samples/client/petstore/rust/hyper/rust-test/.openapi-generator/VERSION +++ b/samples/client/petstore/rust/hyper/rust-test/.openapi-generator/VERSION @@ -1 +1 @@ -4.2.0-SNAPSHOT \ No newline at end of file +5.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/rust/reqwest/fileResponseTest/.openapi-generator/VERSION b/samples/client/petstore/rust/reqwest/fileResponseTest/.openapi-generator/VERSION index c3a2c7076fa8..d99e7162d01f 100644 --- a/samples/client/petstore/rust/reqwest/fileResponseTest/.openapi-generator/VERSION +++ b/samples/client/petstore/rust/reqwest/fileResponseTest/.openapi-generator/VERSION @@ -1 +1 @@ -4.2.0-SNAPSHOT \ No newline at end of file +5.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/rust/reqwest/fileResponseTest/src/apis/default_api.rs b/samples/client/petstore/rust/reqwest/fileResponseTest/src/apis/default_api.rs index b12bf1e49857..407215f0c7b1 100644 --- a/samples/client/petstore/rust/reqwest/fileResponseTest/src/apis/default_api.rs +++ b/samples/client/petstore/rust/reqwest/fileResponseTest/src/apis/default_api.rs @@ -29,6 +29,7 @@ impl DefaultApiClient { } } + pub trait DefaultApi { fn fileresponsetest(&self, ) -> Result; } diff --git a/samples/client/petstore/rust/reqwest/petstore/.openapi-generator/VERSION b/samples/client/petstore/rust/reqwest/petstore/.openapi-generator/VERSION index c3a2c7076fa8..d99e7162d01f 100644 --- a/samples/client/petstore/rust/reqwest/petstore/.openapi-generator/VERSION +++ b/samples/client/petstore/rust/reqwest/petstore/.openapi-generator/VERSION @@ -1 +1 @@ -4.2.0-SNAPSHOT \ No newline at end of file +5.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs b/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs index 2412f13002e7..be122c14b7ec 100644 --- a/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs +++ b/samples/client/petstore/rust/reqwest/petstore/src/apis/pet_api.rs @@ -29,6 +29,7 @@ impl PetApiClient { } } + pub trait PetApi { fn add_pet(&self, body: crate::models::Pet) -> Result<(), Error>; fn delete_pet(&self, pet_id: i64, api_key: Option<&str>) -> Result<(), Error>; diff --git a/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs b/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs index 11b427c47f56..8856e2d9f05a 100644 --- a/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs +++ b/samples/client/petstore/rust/reqwest/petstore/src/apis/store_api.rs @@ -29,6 +29,7 @@ impl StoreApiClient { } } + pub trait StoreApi { fn delete_order(&self, order_id: &str) -> Result<(), Error>; fn get_inventory(&self, ) -> Result<::std::collections::HashMap, Error>; diff --git a/samples/client/petstore/rust/reqwest/petstore/src/apis/user_api.rs b/samples/client/petstore/rust/reqwest/petstore/src/apis/user_api.rs index f0d39ed235ae..0ae109852975 100644 --- a/samples/client/petstore/rust/reqwest/petstore/src/apis/user_api.rs +++ b/samples/client/petstore/rust/reqwest/petstore/src/apis/user_api.rs @@ -29,6 +29,7 @@ impl UserApiClient { } } + pub trait UserApi { fn create_user(&self, body: crate::models::User) -> Result<(), Error>; fn create_users_with_array_input(&self, body: Vec) -> Result<(), Error>; diff --git a/samples/client/petstore/rust/reqwest/rust-test/.openapi-generator/VERSION b/samples/client/petstore/rust/reqwest/rust-test/.openapi-generator/VERSION index c3a2c7076fa8..d99e7162d01f 100644 --- a/samples/client/petstore/rust/reqwest/rust-test/.openapi-generator/VERSION +++ b/samples/client/petstore/rust/reqwest/rust-test/.openapi-generator/VERSION @@ -1 +1 @@ -4.2.0-SNAPSHOT \ No newline at end of file +5.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/rust/reqwest/rust-test/src/apis/default_api.rs b/samples/client/petstore/rust/reqwest/rust-test/src/apis/default_api.rs index f154a6998c33..697d250b5401 100644 --- a/samples/client/petstore/rust/reqwest/rust-test/src/apis/default_api.rs +++ b/samples/client/petstore/rust/reqwest/rust-test/src/apis/default_api.rs @@ -29,6 +29,7 @@ impl DefaultApiClient { } } + pub trait DefaultApi { fn dummy_get(&self, ) -> Result<(), Error>; }