Skip to content

Commit 4b04e17

Browse files
authored
feat(rust): support ability to disable boxed models in client (#17931)
* feat(client): support ability to disable boxed models Add new additional property `avoidBoxedModels` which can be configured to avoid `Box<..>` of models. It's very nice to have such config, because it doesn't make a lot of sense for really simple models. * test: rollback config of existed test
1 parent 2a4e60c commit 4b04e17

File tree

78 files changed

+3604
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3604
-31
lines changed

bin/configs/rust-hyper-oneOf.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ library: hyper
44
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneof_polymorphism_and_inheritance.yaml
55
templateDir: modules/openapi-generator/src/main/resources/rust
66
additionalProperties:
7-
supportAsync: "false"
7+
supportAsync: false
88
packageName: oneof-hyper
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
generatorName: rust
2+
outputDir: samples/client/petstore/rust/reqwest/petstore-avoid-box
3+
library: reqwest
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/rust
6+
additionalProperties:
7+
supportAsync: true
8+
supportMultipleResponses: true
9+
avoidBoxedModels: true
10+
packageName: petstore-reqwest-avoid-box
11+
useSingleRequestParameter: true

docs/generators/rust.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
1818

1919
| Option | Description | Values | Default |
2020
| ------ | ----------- | ------ | ------- |
21+
|avoidBoxedModels|If set, `Box&lt;T&gt;` will not be used for models| |false|
2122
|bestFitInt|Use best fitting integer type where minimum or maximum is set| |false|
2223
|enumNameSuffix|Suffix that will be appended to all enum names.| ||
2324
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustClientCodegen.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
5050
private boolean withAWSV4Signature = false;
5151
private boolean preferUnsignedInt = false;
5252
private boolean bestFitInt = false;
53+
private boolean avoidBoxedModels = false;
5354

5455
public static final String PACKAGE_NAME = "packageName";
5556
public static final String PACKAGE_VERSION = "packageVersion";
@@ -60,6 +61,7 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
6061
public static final String SUPPORT_MULTIPLE_RESPONSES = "supportMultipleResponses";
6162
public static final String PREFER_UNSIGNED_INT = "preferUnsignedInt";
6263
public static final String BEST_FIT_INT = "bestFitInt";
64+
public static final String AVOID_BOXED_MODELS = "avoidBoxedModels";
6365

6466
protected String packageName = "openapi";
6567
protected String packageVersion = "1.0.0";
@@ -192,6 +194,8 @@ public RustClientCodegen() {
192194
.defaultValue(Boolean.FALSE.toString()));
193195
cliOptions.add(new CliOption(BEST_FIT_INT, "Use best fitting integer type where minimum or maximum is set", SchemaTypeUtil.BOOLEAN_TYPE)
194196
.defaultValue(Boolean.FALSE.toString()));
197+
cliOptions.add(new CliOption(AVOID_BOXED_MODELS, "If set, `Box<T>` will not be used for models", SchemaTypeUtil.BOOLEAN_TYPE)
198+
.defaultValue(Boolean.FALSE.toString()));
195199

196200
supportedLibraries.put(HYPER_LIBRARY, "HTTP client: Hyper.");
197201
supportedLibraries.put(REQWEST_LIBRARY, "HTTP client: Reqwest.");
@@ -341,6 +345,11 @@ public void processOpts() {
341345
}
342346
writePropertyBack(BEST_FIT_INT, getBestFitInt());
343347

348+
if (additionalProperties.containsKey(AVOID_BOXED_MODELS)) {
349+
this.setAvoidBoxedModels(convertPropertyToBoolean(AVOID_BOXED_MODELS));
350+
}
351+
writePropertyBack(AVOID_BOXED_MODELS, getAvoidBoxedModels());
352+
344353
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
345354
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
346355

@@ -437,6 +446,14 @@ private void setUseSingleRequestParameter(boolean useSingleRequestParameter) {
437446
this.useSingleRequestParameter = useSingleRequestParameter;
438447
}
439448

449+
public boolean getAvoidBoxedModels() {
450+
return avoidBoxedModels;
451+
}
452+
453+
public void setAvoidBoxedModels(boolean avoidBoxedModels) {
454+
this.avoidBoxedModels = avoidBoxedModels;
455+
}
456+
440457
@Override
441458
public String apiFileFolder() {
442459
return (outputFolder + File.separator + apiFolder).replace("/", File.separator);
@@ -602,5 +619,4 @@ public String toDefaultValue(Schema p) {
602619
return null;
603620
}
604621
}
605-
606622
}

modules/openapi-generator/src/main/resources/rust/model.mustache

+7-7
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub enum {{{classname}}} {
5252
/// {{{.}}}
5353
{{/description}}
5454
#[serde(rename = "{{{baseName}}}"{{^required}}, skip_serializing_if = "Option::is_none"{{/required}})]
55-
{{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{#isModel}}Box<{{{dataType}}}>{{/isModel}}{{^isModel}}{{{dataType}}}{{/isModel}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}},
55+
{{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{^isModel}}{{{dataType}}}{{/isModel}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}},
5656
{{/vars}}
5757
},
5858
{{/mappedModels}}
@@ -65,7 +65,7 @@ pub enum {{{classname}}} {
6565
{{#baseName}}
6666
#[serde(rename="{{{.}}}")]
6767
{{/baseName}}
68-
{{{name}}}(Box<{{{dataType}}}>),
68+
{{{name}}}({{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{/isModel}}{{{dataType}}}{{#isModel}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}),
6969
{{/composedSchemas.oneOf}}
7070
{{/oneOf.isEmpty}}
7171
}
@@ -77,7 +77,7 @@ impl Default for {{classname}} {
7777
{{{name}}}: Default::default(),
7878
{{/vars}}
7979
}{{/-first}}{{/mappedModels}}
80-
{{/oneOf}}{{^oneOf.isEmpty}}{{#composedSchemas.oneOf}}{{#-first}}Self::{{{name}}}(Box::default()){{/-first}}{{/composedSchemas.oneOf}}{{/oneOf.isEmpty}}
80+
{{/oneOf}}{{^oneOf.isEmpty}}{{#composedSchemas.oneOf}}{{#-first}}Self::{{{name}}}(Default::default()){{/-first}}{{/composedSchemas.oneOf}}{{/oneOf.isEmpty}}
8181
}
8282
}
8383

@@ -93,7 +93,7 @@ pub struct {{{classname}}} {
9393
/// {{{.}}}
9494
{{/description}}
9595
#[serde(rename = "{{{baseName}}}"{{^required}}{{#isNullable}}, default, with = "::serde_with::rust::double_option"{{/isNullable}}{{/required}}{{^required}}, skip_serializing_if = "Option::is_none"{{/required}}{{#required}}{{#isNullable}}, deserialize_with = "Option::deserialize"{{/isNullable}}{{/required}})]
96-
pub {{{name}}}: {{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{^isEnum}}{{#isModel}}Box<{{{dataType}}}>{{/isModel}}{{^isModel}}{{{dataType}}}{{/isModel}}{{/isEnum}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
96+
pub {{{name}}}: {{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{^isEnum}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{^isModel}}{{{dataType}}}{{/isModel}}{{/isEnum}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
9797
{{/vars}}
9898
}
9999

@@ -104,7 +104,7 @@ impl {{{classname}}} {
104104
pub fn new({{#requiredVars}}{{{name}}}: {{#isNullable}}Option<{{/isNullable}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}>{{/isNullable}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
105105
{{{classname}}} {
106106
{{#vars}}
107-
{{{name}}}{{^required}}: None{{/required}}{{#required}}{{#isModel}}: {{^isNullable}}Box::new({{{name}}}){{/isNullable}}{{#isNullable}}if let Some(x) = {{{name}}} {Some(Box::new(x))} else {None}{{/isNullable}}{{/isModel}}{{/required}},
107+
{{{name}}}{{^required}}: None{{/required}}{{#required}}{{#isModel}}{{^avoidBoxedModels}}: {{^isNullable}}Box::new({{{name}}}){{/isNullable}}{{#isNullable}}if let Some(x) = {{{name}}} {Some(Box::new(x))} else {None}{{/isNullable}}{{/avoidBoxedModels}}{{/isModel}}{{/required}},
108108
{{/vars}}
109109
}
110110
}
@@ -122,13 +122,13 @@ pub enum {{classname}} {
122122
{{#description}}
123123
/// {{{.}}}
124124
{{/description}}
125-
{{{name}}}(Box<{{{dataType}}}>),
125+
{{{name}}}({{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{/isModel}}{{{dataType}}}{{#isModel}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}),
126126
{{/composedSchemas.oneOf}}
127127
}
128128

129129
impl Default for {{classname}} {
130130
fn default() -> Self {
131-
{{#composedSchemas.oneOf}}{{#-first}}Self::{{{name}}}(Box::default()){{/-first}}{{/composedSchemas.oneOf}}
131+
{{#composedSchemas.oneOf}}{{#-first}}Self::{{{name}}}(Default::default()){{/-first}}{{/composedSchemas.oneOf}}
132132
}
133133
}
134134
{{/oneOf.isEmpty}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustClientCodegenTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public void testSettersForConfigValues() throws Exception {
4848
codegen.setHideGenerationTimestamp(false);
4949
codegen.setPreferUnsignedInt(true);
5050
codegen.setBestFitInt(true);
51+
codegen.setAvoidBoxedModels(true);
5152
codegen.processOpts();
5253

5354
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE);
@@ -58,6 +59,9 @@ public void testSettersForConfigValues() throws Exception {
5859

5960
Assert.assertEquals(codegen.additionalProperties().get(RustClientCodegen.BEST_FIT_INT), Boolean.TRUE);
6061
Assert.assertTrue(codegen.getBestFitInt());
62+
63+
Assert.assertEquals(codegen.additionalProperties().get(RustClientCodegen.AVOID_BOXED_MODELS), Boolean.TRUE);
64+
Assert.assertTrue(codegen.getAvoidBoxedModels());
6165
}
6266

6367
@Test

samples/client/others/rust/hyper/composed-oneof/src/models/create_state_request.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum CreateStateRequest {
2121

2222
impl Default for CreateStateRequest {
2323
fn default() -> Self {
24-
Self::AType(Box::default())
24+
Self::AType(Default::default())
2525
}
2626
}
2727

samples/client/others/rust/hyper/composed-oneof/src/models/custom_one_of_array_schema_inner.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum CustomOneOfArraySchemaInner {
2323

2424
impl Default for CustomOneOfArraySchemaInner {
2525
fn default() -> Self {
26-
Self::AType(Box::default())
26+
Self::AType(Default::default())
2727
}
2828
}
2929

samples/client/others/rust/hyper/composed-oneof/src/models/custom_one_of_schema.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum CustomOneOfSchema {
2121

2222
impl Default for CustomOneOfSchema {
2323
fn default() -> Self {
24-
Self::AType(Box::default())
24+
Self::AType(Default::default())
2525
}
2626
}
2727

samples/client/others/rust/hyper/composed-oneof/src/models/get_state_200_response.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum GetState200Response {
2323

2424
impl Default for GetState200Response {
2525
fn default() -> Self {
26-
Self::AType(Box::default())
26+
Self::AType(Default::default())
2727
}
2828
}
2929

samples/client/others/rust/hyper/oneOf-array-map/src/models/fruit.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use crate::models;
1313
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1414
#[serde(untagged)]
1515
pub enum Fruit {
16-
Apples(Box<std::collections::HashMap<String, models::Apple>>),
17-
Grapes(Box<Vec<models::Grape>>),
16+
Apples(std::collections::HashMap<String, models::Apple>),
17+
Grapes(Vec<models::Grape>),
1818
}
1919

2020
impl Default for Fruit {
2121
fn default() -> Self {
22-
Self::Apples(Box::default())
22+
Self::Apples(Default::default())
2323
}
2424
}
2525

samples/client/others/rust/hyper/oneOf-reuseRef/src/models/fruit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum Fruit {
2323

2424
impl Default for Fruit {
2525
fn default() -> Self {
26-
Self::GreenApple(Box::default())
26+
Self::GreenApple(Default::default())
2727
}
2828
}
2929

samples/client/others/rust/hyper/oneOf/src/models/bar_ref_or_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub enum BarRefOrValue {
1919

2020
impl Default for BarRefOrValue {
2121
fn default() -> Self {
22-
Self::Bar(Box::default())
22+
Self::Bar(Default::default())
2323
}
2424
}
2525

samples/client/others/rust/hyper/oneOf/src/models/foo_ref_or_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum FooRefOrValue {
2121

2222
impl Default for FooRefOrValue {
2323
fn default() -> Self {
24-
Self::Foo(Box::default())
24+
Self::Foo(Default::default())
2525
}
2626
}
2727

samples/client/others/rust/hyper/oneOf/src/models/fruit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum Fruit {
2121

2222
impl Default for Fruit {
2323
fn default() -> Self {
24-
Self::Apple(Box::default())
24+
Self::Apple(Default::default())
2525
}
2626
}
2727

samples/client/others/rust/reqwest/composed-oneof/src/models/create_state_request.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum CreateStateRequest {
2121

2222
impl Default for CreateStateRequest {
2323
fn default() -> Self {
24-
Self::AType(Box::default())
24+
Self::AType(Default::default())
2525
}
2626
}
2727

samples/client/others/rust/reqwest/composed-oneof/src/models/custom_one_of_array_schema_inner.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum CustomOneOfArraySchemaInner {
2323

2424
impl Default for CustomOneOfArraySchemaInner {
2525
fn default() -> Self {
26-
Self::AType(Box::default())
26+
Self::AType(Default::default())
2727
}
2828
}
2929

samples/client/others/rust/reqwest/composed-oneof/src/models/custom_one_of_schema.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum CustomOneOfSchema {
2121

2222
impl Default for CustomOneOfSchema {
2323
fn default() -> Self {
24-
Self::AType(Box::default())
24+
Self::AType(Default::default())
2525
}
2626
}
2727

samples/client/others/rust/reqwest/composed-oneof/src/models/get_state_200_response.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum GetState200Response {
2323

2424
impl Default for GetState200Response {
2525
fn default() -> Self {
26-
Self::AType(Box::default())
26+
Self::AType(Default::default())
2727
}
2828
}
2929

samples/client/others/rust/reqwest/oneOf-array-map/src/models/fruit.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use crate::models;
1313
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1414
#[serde(untagged)]
1515
pub enum Fruit {
16-
Apples(Box<std::collections::HashMap<String, models::Apple>>),
17-
Grapes(Box<Vec<models::Grape>>),
16+
Apples(std::collections::HashMap<String, models::Apple>),
17+
Grapes(Vec<models::Grape>),
1818
}
1919

2020
impl Default for Fruit {
2121
fn default() -> Self {
22-
Self::Apples(Box::default())
22+
Self::Apples(Default::default())
2323
}
2424
}
2525

samples/client/others/rust/reqwest/oneOf-reuseRef/src/models/fruit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum Fruit {
2323

2424
impl Default for Fruit {
2525
fn default() -> Self {
26-
Self::GreenApple(Box::default())
26+
Self::GreenApple(Default::default())
2727
}
2828
}
2929

samples/client/others/rust/reqwest/oneOf/src/models/bar_ref_or_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub enum BarRefOrValue {
1919

2020
impl Default for BarRefOrValue {
2121
fn default() -> Self {
22-
Self::Bar(Box::default())
22+
Self::Bar(Default::default())
2323
}
2424
}
2525

samples/client/others/rust/reqwest/oneOf/src/models/foo_ref_or_value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum FooRefOrValue {
2121

2222
impl Default for FooRefOrValue {
2323
fn default() -> Self {
24-
Self::Foo(Box::default())
24+
Self::Foo(Default::default())
2525
}
2626
}
2727

samples/client/others/rust/reqwest/oneOf/src/models/fruit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum Fruit {
2121

2222
impl Default for Fruit {
2323
fn default() -> Self {
24-
Self::Apple(Box::default())
24+
Self::Apple(Default::default())
2525
}
2626
}
2727

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target/
2+
**/*.rs.bk
3+
Cargo.lock
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md

0 commit comments

Comments
 (0)