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 76ba95107cff..008466ab7635 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 @@ -331,6 +331,42 @@ public CodegenModel fromModel(String name, Schema model) { return mdl; } + @Override + public Map postProcessAllModels(Map objs) { + objs = super.postProcessAllModels(objs); + + for (ModelsMap modelsMap : objs.values()) { + for (ModelMap modelMap : modelsMap.getModels()) { + CodegenModel cm = modelMap.getModel(); + CodegenDiscriminator discriminator = cm.discriminator; + if (discriminator == null || discriminator.getMappedModels() == null) { + continue; + } + // a mapping that names the base itself leaves no struct to wrap, and an enum-typed tag would be + // written twice (the child's copy keeps its default): keep the inline variants + if (discriminator.getMappedModels().stream().anyMatch(m -> cm.name.equals(m.getSchemaName())) + || cm.allVars.stream().anyMatch(v -> discriminator.getPropertyBaseName().equals(v.baseName) && v.getIsEnumOrRef())) { + discriminator.getVendorExtensions().put("x-rust-inline-variants", true); + continue; + } + // a mapped child's discriminator doubles as the union's serde tag, which is consumed before the + // child deserializes: mark it so the template defaults it and skips it while unset + for (CodegenDiscriminator.MappedModel mapped : discriminator.getMappedModels()) { + if (mapped.getModel() == null) { + continue; + } + for (CodegenProperty var : mapped.getModel().vars) { + if (discriminator.getPropertyBaseName().equals(var.baseName)) { + var.isDiscriminator = true; + } + } + } + } + } + + return objs; + } + @Override public ModelsMap postProcessModels(ModelsMap objs) { for (ModelMap model : objs.getModels()) { diff --git a/modules/openapi-generator/src/main/resources/rust/model.mustache b/modules/openapi-generator/src/main/resources/rust/model.mustache index a2c60b117a45..3a89ab2299c0 100644 --- a/modules/openapi-generator/src/main/resources/rust/model.mustache +++ b/modules/openapi-generator/src/main/resources/rust/model.mustache @@ -84,6 +84,11 @@ pub enum {{{classname}}} { {{^oneOf}} {{#mappedModels}} #[serde(rename="{{mappingName}}")] + {{^vendorExtensions.x-rust-inline-variants}} + {{!-- newtype variant: the child's own fields survive; named by modelName (unique per mapping), wraps the real classname --}} + {{{modelName}}}({{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}models::{{#model}}{{{classname}}}{{/model}}{{^model}}{{{modelName}}}{{/model}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}), + {{/vendorExtensions.x-rust-inline-variants}} + {{#vendorExtensions.x-rust-inline-variants}} {{{modelName}}} { {{#vars}} {{#description}} @@ -93,6 +98,7 @@ pub enum {{{classname}}} { {{{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}}, {{/vars}} }, + {{/vendorExtensions.x-rust-inline-variants}} {{/mappedModels}} {{/oneOf}} {{^oneOf.isEmpty}} @@ -110,11 +116,11 @@ pub enum {{{classname}}} { impl Default for {{classname}} { fn default() -> Self { - {{^oneOf}}{{#mappedModels}}{{#-first}}Self::{{modelName}} { + {{^oneOf}}{{#mappedModels}}{{#-first}}{{^vendorExtensions.x-rust-inline-variants}}Self::{{modelName}}(Default::default()){{/vendorExtensions.x-rust-inline-variants}}{{#vendorExtensions.x-rust-inline-variants}}Self::{{modelName}} { {{#vars}} {{{name}}}: Default::default(), {{/vars}} - }{{/-first}}{{/mappedModels}} + }{{/vendorExtensions.x-rust-inline-variants}}{{/-first}}{{/mappedModels}} {{/oneOf}}{{^oneOf.isEmpty}}{{#composedSchemas.oneOf}}{{#-first}}Self::{{{name}}}(Default::default()){{/-first}}{{/composedSchemas.oneOf}}{{/oneOf.isEmpty}} } } @@ -133,7 +139,8 @@ pub struct {{{classname}}} { {{#isByteArray}} {{#vendorExtensions.isMandatory}}#[serde_as(as = "serde_with::base64::Base64")]{{/vendorExtensions.isMandatory}}{{^vendorExtensions.isMandatory}}#[serde_as(as = "{{^serdeAsDoubleOption}}Option{{/serdeAsDoubleOption}}{{#serdeAsDoubleOption}}super::DoubleOption{{/serdeAsDoubleOption}}")]{{/vendorExtensions.isMandatory}} {{/isByteArray}} - #[serde(rename = "{{{baseName}}}"{{^required}}{{#isNullable}}, default{{^isByteArray}}, with = "::serde_with::rust::double_option"{{/isByteArray}}{{/isNullable}}{{/required}}{{^required}}, skip_serializing_if = "Option::is_none"{{/required}}{{#required}}{{#isNullable}}, deserialize_with = "Option::deserialize"{{/isNullable}}{{/required}})] + {{!-- a mapped child's discriminator is the union's consumed serde tag: default it, skip it while unset --}} + #[serde(rename = "{{{baseName}}}"{{#isDiscriminator}}{{#required}}, default{{#isNullable}}, skip_serializing_if = "Option::is_none"{{/isNullable}}{{^isNullable}}{{#isString}}{{^isEnum}}, skip_serializing_if = "String::is_empty"{{/isEnum}}{{/isString}}{{/isNullable}}{{/required}}{{/isDiscriminator}}{{^required}}{{#isNullable}}, default{{^isByteArray}}, with = "::serde_with::rust::double_option"{{/isByteArray}}{{/isNullable}}{{/required}}{{^required}}, skip_serializing_if = "Option::is_none"{{/required}}{{#required}}{{#isNullable}}{{^isDiscriminator}}, deserialize_with = "Option::deserialize"{{/isDiscriminator}}{{/isNullable}}{{/required}})] pub {{{name}}}: {{! ### Option Start }}{{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{! diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustClientCodegenTest.java index 4ca3f4c70c91..76e96393bb6a 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustClientCodegenTest.java @@ -298,6 +298,49 @@ public void testMultipleArrayTypesEnum() throws IOException { TestUtils.assertFileContains(outputPath, enumSpec); } + @Test + public void testDiscriminatedUnionKeepsChildFields() throws IOException { + Path target = Files.createTempDirectory("test"); + target.toFile().deleteOnExit(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("rust") + .setInputSpec("src/test/resources/3_0/rust/discriminated-union.yaml") + .setSkipOverwrite(false) + .setOutputDir(target.toAbsolutePath().toString().replace("\\", "/")); + new DefaultGenerator().opts(configurator.toClientOptInput()).generate(); + + // newtype variants, so the child's own fields survive + Path unionPath = Path.of(target.toString(), "/src/models/api_error.rs"); + TestUtils.assertFileContains(unionPath, "#[serde(tag = \"type\")]"); + TestUtils.assertFileContains(unionPath, "ObjectExists(Box),"); + TestUtils.assertFileContains(unionPath, "ValidationError(Box),"); + TestUtils.assertFileContains(unionPath, "Self::ObjectExists(Default::default())"); + TestUtils.assertFileNotContains(unionPath, "ObjectExists {"); + + // the consumed tag key defaults and is skipped while unset; standalone field and new() unchanged + Path childPath = Path.of(target.toString(), "/src/models/object_exists.rs"); + TestUtils.assertFileContains(childPath, + "#[serde(rename = \"type\", default, skip_serializing_if = \"String::is_empty\")]", + "pub identifier: String,", + "pub fn new(r#type: String, message: String, identifier: String) -> ObjectExists {"); + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/alpha.rs"), + "#[serde(rename = \"kind\", default, skip_serializing_if = \"Option::is_none\")]"); + // an enum-typed tag would be written twice, the child's copy keeping its default: inline variants, children untouched + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/pet.rs"), + "#[serde(rename=\"Cat\")]\n Cat {", "#[serde(rename=\"Dog\")]\n Dog {"); + TestUtils.assertFileNotContains(Path.of(target.toString(), "/src/models/pet.rs"), "Box"); + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/cat.rs"), "#[serde(rename = \"petType\")]\n pub pet_type: PetType,"); + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/shape.rs"), "#[serde(rename=\"circle\")]\n Circle {"); + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/circle.rs"), "#[serde(rename = \"kind\")]\n pub kind: models::ShapeKind,"); + + // a mapping that names the base itself leaves no struct to wrap (E0275): inline variants, children untouched + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/creature.rs"), + "#[serde(rename=\"Creature\")]\n Creature {", "#[serde(rename=\"Bird\")]\n Bird {"); + TestUtils.assertFileNotContains(Path.of(target.toString(), "/src/models/creature.rs"), "Box"); + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/creature.rs"), "#[serde(tag = \"kind\")]"); + TestUtils.assertFileContains(Path.of(target.toString(), "/src/models/bird.rs"), "#[serde(rename = \"kind\")]\n pub kind: String,"); + } + @Test public void testIntegerPropertyEnum() throws IOException { Path target = Files.createTempDirectory("test"); diff --git a/modules/openapi-generator/src/test/resources/3_0/rust/discriminated-union.yaml b/modules/openapi-generator/src/test/resources/3_0/rust/discriminated-union.yaml new file mode 100644 index 000000000000..c7c9b6010033 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/rust/discriminated-union.yaml @@ -0,0 +1,143 @@ +openapi: 3.0.3 +info: + title: discriminated union + version: 1.0.0 +paths: + /errors: + get: + operationId: getError + responses: + '200': + description: ok + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' +components: + schemas: + ApiError: + type: object + required: + - type + - message + properties: + type: + type: string + message: + type: string + discriminator: + propertyName: type + mapping: + ObjectExists: '#/components/schemas/ObjectExists' + ValidationError: '#/components/schemas/ValidationError' + ObjectExists: + allOf: + - $ref: '#/components/schemas/ApiError' + - type: object + required: + - identifier + properties: + identifier: + type: string + objectType: + type: string + ValidationError: + allOf: + - $ref: '#/components/schemas/ApiError' + - type: object + properties: + field: + type: string + # nullable discriminator: String::is_empty would not compile against it + NullableTagged: + type: object + required: + - kind + properties: + kind: + type: string + nullable: true + label: + type: string + discriminator: + propertyName: kind + mapping: + Alpha: '#/components/schemas/Alpha' + Alpha: + allOf: + - $ref: '#/components/schemas/NullableTagged' + - type: object + properties: + alphaOnly: + type: string + # enum-typed discriminators, inline and $ref: the union keeps the inline variants + Pet: + type: object + required: + - petType + properties: + petType: + type: string + enum: [Cat, Dog] + discriminator: + propertyName: petType + mapping: + Cat: '#/components/schemas/Cat' + Dog: '#/components/schemas/Dog' + Cat: + allOf: + - $ref: '#/components/schemas/Pet' + - type: object + properties: + lives: + type: integer + Dog: + allOf: + - $ref: '#/components/schemas/Pet' + - type: object + properties: + bark: + type: boolean + ShapeKind: + type: string + enum: [circle] + Shape: + type: object + required: + - kind + properties: + kind: + $ref: '#/components/schemas/ShapeKind' + discriminator: + propertyName: kind + mapping: + circle: '#/components/schemas/Circle' + Circle: + allOf: + - $ref: '#/components/schemas/Shape' + - type: object + properties: + radius: + type: number + # the mapping names the base itself: no struct to wrap, so the union keeps the inline variants + Creature: + type: object + required: + - kind + properties: + kind: + type: string + name: + type: string + discriminator: + propertyName: kind + mapping: + Creature: '#/components/schemas/Creature' + Bird: '#/components/schemas/Bird' + Bird: + allOf: + - $ref: '#/components/schemas/Creature' + - type: object + properties: + wingspan: + type: number diff --git a/samples/client/others/rust/hyper/oneOf/src/models/bar.rs b/samples/client/others/rust/hyper/oneOf/src/models/bar.rs index ed85518807f2..0e5acbf27e4d 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/bar.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/bar.rs @@ -25,7 +25,7 @@ pub struct Bar { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")] pub bar_prop_a: Option, diff --git a/samples/client/others/rust/hyper/oneOf/src/models/bar_create.rs b/samples/client/others/rust/hyper/oneOf/src/models/bar_create.rs index 98481c64e2f9..3a0da7cd7500 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/bar_create.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/bar_create.rs @@ -26,7 +26,7 @@ pub struct BarCreate { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")] pub bar_prop_a: Option, diff --git a/samples/client/others/rust/hyper/oneOf/src/models/bar_ref.rs b/samples/client/others/rust/hyper/oneOf/src/models/bar_ref.rs index ce4ee09caf9d..07ca991d8627 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/bar_ref.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/bar_ref.rs @@ -26,7 +26,7 @@ pub struct BarRef { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, /// Name of the related entity. #[serde(rename = "name", skip_serializing_if = "Option::is_none")] diff --git a/samples/client/others/rust/hyper/oneOf/src/models/entity.rs b/samples/client/others/rust/hyper/oneOf/src/models/entity.rs index bfb1aac3382c..6f6c47efe667 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/entity.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/entity.rs @@ -15,105 +15,22 @@ use serde::{Deserialize, Serialize}; #[serde(tag = "@type")] pub enum Entity { #[serde(rename="Bar")] - Bar { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Bar(Box), #[serde(rename="Bar_Create")] - BarCreate { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + BarCreate(Box), #[serde(rename="Foo")] - Foo { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Foo(Box), #[serde(rename="Pasta")] - Pasta { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Pasta(Box), #[serde(rename="Pizza")] - Pizza { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Pizza(Box), #[serde(rename="PizzaSpeziale")] - PizzaSpeziale { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + PizzaSpeziale(Box), } impl Default for Entity { fn default() -> Self { - Self::Bar { - href: Default::default(), - id: Default::default(), - at_schema_location: Default::default(), - at_base_type: Default::default(), - } + Self::Bar(Default::default()) } } diff --git a/samples/client/others/rust/hyper/oneOf/src/models/entity_ref.rs b/samples/client/others/rust/hyper/oneOf/src/models/entity_ref.rs index d1a9853dc89b..ea762128d931 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/entity_ref.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/entity_ref.rs @@ -15,59 +15,14 @@ use serde::{Deserialize, Serialize}; #[serde(tag = "@type")] pub enum EntityRef { #[serde(rename="BarRef")] - BarRef { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - /// Name of the related entity. - #[serde(rename = "name", skip_serializing_if = "Option::is_none")] - name: Option, - /// The actual type of the target instance when needed for disambiguation. - #[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")] - at_referred_type: Option, - }, + BarRef(Box), #[serde(rename="FooRef")] - FooRef { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - /// Name of the related entity. - #[serde(rename = "name", skip_serializing_if = "Option::is_none")] - name: Option, - /// The actual type of the target instance when needed for disambiguation. - #[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")] - at_referred_type: Option, - }, + FooRef(Box), } impl Default for EntityRef { fn default() -> Self { - Self::BarRef { - href: Default::default(), - id: Default::default(), - at_schema_location: Default::default(), - at_base_type: Default::default(), - name: Default::default(), - at_referred_type: Default::default(), - } + Self::BarRef(Default::default()) } } diff --git a/samples/client/others/rust/hyper/oneOf/src/models/foo.rs b/samples/client/others/rust/hyper/oneOf/src/models/foo.rs index becc6957dd5d..6365749a7432 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/foo.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/foo.rs @@ -26,7 +26,7 @@ pub struct Foo { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "fooPropA", skip_serializing_if = "Option::is_none")] pub foo_prop_a: Option, diff --git a/samples/client/others/rust/hyper/oneOf/src/models/foo_ref.rs b/samples/client/others/rust/hyper/oneOf/src/models/foo_ref.rs index f4b3a2837fb7..09d760d3bae1 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/foo_ref.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/foo_ref.rs @@ -26,7 +26,7 @@ pub struct FooRef { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, /// Name of the related entity. #[serde(rename = "name", skip_serializing_if = "Option::is_none")] diff --git a/samples/client/others/rust/hyper/oneOf/src/models/pasta.rs b/samples/client/others/rust/hyper/oneOf/src/models/pasta.rs index 5352c0da9d41..a6dec55be07b 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/pasta.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/pasta.rs @@ -26,7 +26,7 @@ pub struct Pasta { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "vendor", skip_serializing_if = "Option::is_none")] pub vendor: Option, diff --git a/samples/client/others/rust/hyper/oneOf/src/models/pizza.rs b/samples/client/others/rust/hyper/oneOf/src/models/pizza.rs index b99e41a1a354..a0c7390b126f 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/pizza.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/pizza.rs @@ -26,7 +26,7 @@ pub struct Pizza { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "pizzaSize", skip_serializing_if = "Option::is_none")] pub pizza_size: Option, diff --git a/samples/client/others/rust/hyper/oneOf/src/models/pizza_speziale.rs b/samples/client/others/rust/hyper/oneOf/src/models/pizza_speziale.rs index f3cfea721eff..40133bbf0304 100644 --- a/samples/client/others/rust/hyper/oneOf/src/models/pizza_speziale.rs +++ b/samples/client/others/rust/hyper/oneOf/src/models/pizza_speziale.rs @@ -26,7 +26,7 @@ pub struct PizzaSpeziale { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "pizzaSize", skip_serializing_if = "Option::is_none")] pub pizza_size: Option, diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/bar.rs b/samples/client/others/rust/reqwest/oneOf/src/models/bar.rs index ed85518807f2..0e5acbf27e4d 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/bar.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/bar.rs @@ -25,7 +25,7 @@ pub struct Bar { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")] pub bar_prop_a: Option, diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/bar_create.rs b/samples/client/others/rust/reqwest/oneOf/src/models/bar_create.rs index 98481c64e2f9..3a0da7cd7500 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/bar_create.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/bar_create.rs @@ -26,7 +26,7 @@ pub struct BarCreate { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "barPropA", skip_serializing_if = "Option::is_none")] pub bar_prop_a: Option, diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/bar_ref.rs b/samples/client/others/rust/reqwest/oneOf/src/models/bar_ref.rs index ce4ee09caf9d..07ca991d8627 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/bar_ref.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/bar_ref.rs @@ -26,7 +26,7 @@ pub struct BarRef { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, /// Name of the related entity. #[serde(rename = "name", skip_serializing_if = "Option::is_none")] diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/entity.rs b/samples/client/others/rust/reqwest/oneOf/src/models/entity.rs index bfb1aac3382c..6f6c47efe667 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/entity.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/entity.rs @@ -15,105 +15,22 @@ use serde::{Deserialize, Serialize}; #[serde(tag = "@type")] pub enum Entity { #[serde(rename="Bar")] - Bar { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Bar(Box), #[serde(rename="Bar_Create")] - BarCreate { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + BarCreate(Box), #[serde(rename="Foo")] - Foo { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Foo(Box), #[serde(rename="Pasta")] - Pasta { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Pasta(Box), #[serde(rename="Pizza")] - Pizza { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + Pizza(Box), #[serde(rename="PizzaSpeziale")] - PizzaSpeziale { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - }, + PizzaSpeziale(Box), } impl Default for Entity { fn default() -> Self { - Self::Bar { - href: Default::default(), - id: Default::default(), - at_schema_location: Default::default(), - at_base_type: Default::default(), - } + Self::Bar(Default::default()) } } diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/entity_ref.rs b/samples/client/others/rust/reqwest/oneOf/src/models/entity_ref.rs index d1a9853dc89b..ea762128d931 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/entity_ref.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/entity_ref.rs @@ -15,59 +15,14 @@ use serde::{Deserialize, Serialize}; #[serde(tag = "@type")] pub enum EntityRef { #[serde(rename="BarRef")] - BarRef { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - /// Name of the related entity. - #[serde(rename = "name", skip_serializing_if = "Option::is_none")] - name: Option, - /// The actual type of the target instance when needed for disambiguation. - #[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")] - at_referred_type: Option, - }, + BarRef(Box), #[serde(rename="FooRef")] - FooRef { - /// Hyperlink reference - #[serde(rename = "href", skip_serializing_if = "Option::is_none")] - href: Option, - /// unique identifier - #[serde(rename = "id", skip_serializing_if = "Option::is_none")] - id: Option, - /// A URI to a JSON-Schema file that defines additional attributes and relationships - #[serde(rename = "@schemaLocation", skip_serializing_if = "Option::is_none")] - at_schema_location: Option, - /// When sub-classing, this defines the super-class - #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] - at_base_type: Option, - /// Name of the related entity. - #[serde(rename = "name", skip_serializing_if = "Option::is_none")] - name: Option, - /// The actual type of the target instance when needed for disambiguation. - #[serde(rename = "@referredType", skip_serializing_if = "Option::is_none")] - at_referred_type: Option, - }, + FooRef(Box), } impl Default for EntityRef { fn default() -> Self { - Self::BarRef { - href: Default::default(), - id: Default::default(), - at_schema_location: Default::default(), - at_base_type: Default::default(), - name: Default::default(), - at_referred_type: Default::default(), - } + Self::BarRef(Default::default()) } } diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/foo.rs b/samples/client/others/rust/reqwest/oneOf/src/models/foo.rs index becc6957dd5d..6365749a7432 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/foo.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/foo.rs @@ -26,7 +26,7 @@ pub struct Foo { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "fooPropA", skip_serializing_if = "Option::is_none")] pub foo_prop_a: Option, diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/foo_ref.rs b/samples/client/others/rust/reqwest/oneOf/src/models/foo_ref.rs index f4b3a2837fb7..09d760d3bae1 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/foo_ref.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/foo_ref.rs @@ -26,7 +26,7 @@ pub struct FooRef { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, /// Name of the related entity. #[serde(rename = "name", skip_serializing_if = "Option::is_none")] diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/pasta.rs b/samples/client/others/rust/reqwest/oneOf/src/models/pasta.rs index 5352c0da9d41..a6dec55be07b 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/pasta.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/pasta.rs @@ -26,7 +26,7 @@ pub struct Pasta { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "vendor", skip_serializing_if = "Option::is_none")] pub vendor: Option, diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/pizza.rs b/samples/client/others/rust/reqwest/oneOf/src/models/pizza.rs index b99e41a1a354..a0c7390b126f 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/pizza.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/pizza.rs @@ -26,7 +26,7 @@ pub struct Pizza { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "pizzaSize", skip_serializing_if = "Option::is_none")] pub pizza_size: Option, diff --git a/samples/client/others/rust/reqwest/oneOf/src/models/pizza_speziale.rs b/samples/client/others/rust/reqwest/oneOf/src/models/pizza_speziale.rs index f3cfea721eff..40133bbf0304 100644 --- a/samples/client/others/rust/reqwest/oneOf/src/models/pizza_speziale.rs +++ b/samples/client/others/rust/reqwest/oneOf/src/models/pizza_speziale.rs @@ -26,7 +26,7 @@ pub struct PizzaSpeziale { #[serde(rename = "@baseType", skip_serializing_if = "Option::is_none")] pub at_base_type: Option, /// When sub-classing, this defines the sub-class Extensible name - #[serde(rename = "@type")] + #[serde(rename = "@type", default, skip_serializing_if = "String::is_empty")] pub at_type: String, #[serde(rename = "pizzaSize", skip_serializing_if = "Option::is_none")] pub pizza_size: Option, diff --git a/samples/client/petstore/rust/hyper/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs b/samples/client/petstore/rust/hyper/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs index 91ae6492101b..a7886f3c293f 100644 --- a/samples/client/petstore/rust/hyper/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs +++ b/samples/client/petstore/rust/hyper/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs @@ -15,41 +15,16 @@ use serde::{Deserialize, Serialize}; #[serde(tag = "objectType")] pub enum TestsDiscriminatorDuplicateEnumsGet200Response { #[serde(rename="car")] - Vehicle { - #[serde(rename = "type")] - r#type: String, - #[serde(rename = "name")] - name: String, - #[serde(rename = "speed")] - speed: f64, - }, + Vehicle(Box), #[serde(rename="student")] - PersonStudent { - #[serde(rename = "type")] - r#type: String, - #[serde(rename = "name")] - name: String, - #[serde(rename = "speed")] - speed: f64, - }, + PersonStudent(Box), #[serde(rename="teacher")] - PersonTeacher { - #[serde(rename = "type")] - r#type: String, - #[serde(rename = "name")] - name: String, - #[serde(rename = "speed")] - speed: f64, - }, + PersonTeacher(Box), } impl Default for TestsDiscriminatorDuplicateEnumsGet200Response { fn default() -> Self { - Self::Vehicle { - r#type: Default::default(), - name: Default::default(), - speed: Default::default(), - } + Self::Vehicle(Default::default()) } } diff --git a/samples/client/petstore/rust/reqwest/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs b/samples/client/petstore/rust/reqwest/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs index 91ae6492101b..a7886f3c293f 100644 --- a/samples/client/petstore/rust/reqwest/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs +++ b/samples/client/petstore/rust/reqwest/test-duplicates/src/models/_tests_discriminator_duplicate_enums_get_200_response.rs @@ -15,41 +15,16 @@ use serde::{Deserialize, Serialize}; #[serde(tag = "objectType")] pub enum TestsDiscriminatorDuplicateEnumsGet200Response { #[serde(rename="car")] - Vehicle { - #[serde(rename = "type")] - r#type: String, - #[serde(rename = "name")] - name: String, - #[serde(rename = "speed")] - speed: f64, - }, + Vehicle(Box), #[serde(rename="student")] - PersonStudent { - #[serde(rename = "type")] - r#type: String, - #[serde(rename = "name")] - name: String, - #[serde(rename = "speed")] - speed: f64, - }, + PersonStudent(Box), #[serde(rename="teacher")] - PersonTeacher { - #[serde(rename = "type")] - r#type: String, - #[serde(rename = "name")] - name: String, - #[serde(rename = "speed")] - speed: f64, - }, + PersonTeacher(Box), } impl Default for TestsDiscriminatorDuplicateEnumsGet200Response { fn default() -> Self { - Self::Vehicle { - r#type: Default::default(), - name: Default::default(), - speed: Default::default(), - } + Self::Vehicle(Default::default()) } }