Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/utils/test_file_list.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@
sha256: 45cdaba3d2adc212cd4f0184ad475419a95e2326254c2ef84175e210c922b2f3
# rust axum test files
- filename: "samples/server/petstore/rust-axum/output/rust-axum-oneof/tests/oneof_with_discriminator.rs"
sha256: 2d4f5a069fdcb3057bb078d5e75b3de63cd477b97725e457079df24bd2c30600
sha256: b2093528aac971193f2863a70f46eea45cf8bda79120b133a614599e80d8b46d
- filename: "samples/server/petstore/rust-axum/output/openapi-v3/tests/oneof_untagged.rs"
sha256: 1d3fb01f65e98290b1d3eece28014c7d3e3f2fdf18e7110249d3c591cc4642ab
Original file line number Diff line number Diff line change
Expand Up @@ -648,38 +648,40 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
}

private void postProcessPolymorphism(final List<ModelMap> allModels) {
final HashMap<String, List<String>> discriminatorsForModel = new HashMap<>();
final HashMap<String, List<CodegenDiscriminator>> discriminatorsForModel = new HashMap<>();

for (final ModelMap mo : allModels) {
final CodegenModel cm = mo.getModel();

final CodegenComposedSchemas cs = cm.getComposedSchemas();
if (cs != null) {
final List<CodegenProperty> csOneOf = cs.getOneOf();
CodegenDiscriminator discriminator = cm.getDiscriminator();

if (csOneOf != null) {
processPolymorphismDataType(csOneOf);
processPolymorphismDataType(csOneOf, discriminator);
cs.setOneOf(csOneOf);
cm.setComposedSchemas(cs);
}

final List<CodegenProperty> csAnyOf = cs.getAnyOf();
if (csAnyOf != null) {
processPolymorphismDataType(csAnyOf);
processPolymorphismDataType(csAnyOf, discriminator);
cs.setAnyOf(csAnyOf);
cm.setComposedSchemas(cs);
}
}

if (cm.discriminator != null) {
for (final String model : cm.oneOf) {
final List<String> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator.getPropertyName());
final List<CodegenDiscriminator> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator);
discriminatorsForModel.put(model, discriminators);
}

for (final String model : cm.anyOf) {
final List<String> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator.getPropertyName());
final List<CodegenDiscriminator> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator);
discriminatorsForModel.put(model, discriminators);
}
}
Expand All @@ -689,11 +691,11 @@ private void postProcessPolymorphism(final List<ModelMap> allModels) {
for (ModelMap mo : allModels) {
final CodegenModel cm = mo.getModel();

final List<String> discriminators = discriminatorsForModel.get(cm.getSchemaName());
final List<CodegenDiscriminator> discriminators = discriminatorsForModel.get(cm.getSchemaName());
if (discriminators != null) {
// If the discriminator field is not a defined attribute in the variant structure, create it.
if (!discriminating(discriminators, cm)) {
final String discriminator = discriminators.get(0);
final CodegenDiscriminator discriminator = discriminators.get(0);

CodegenProperty property = new CodegenProperty();

Expand All @@ -710,17 +712,18 @@ private void postProcessPolymorphism(final List<ModelMap> allModels) {
property.isDiscriminator = true;

// Attributes based on the discriminator value
property.baseName = discriminator;
property.name = discriminator;
property.nameInCamelCase = camelize(discriminator);
property.baseName = discriminator.getPropertyBaseName();
property.name = discriminator.getPropertyName();
property.nameInCamelCase = camelize(discriminator.getPropertyName());
property.nameInPascalCase = property.nameInCamelCase.substring(0, 1).toUpperCase(Locale.ROOT) + property.nameInCamelCase.substring(1);
property.nameInSnakeCase = underscore(discriminator).toUpperCase(Locale.ROOT);
property.nameInSnakeCase = underscore(discriminator.getPropertyName()).toUpperCase(Locale.ROOT);
property.getter = String.format(Locale.ROOT, "get%s", property.nameInPascalCase);
property.setter = String.format(Locale.ROOT, "set%s", property.nameInPascalCase);
property.defaultValueWithParam = String.format(Locale.ROOT, " = data.%s;", property.name);

// Attributes based on the model name
property.defaultValue = String.format(Locale.ROOT, "r#\"%s\"#.to_string()", cm.getSchemaName());
property.discriminatorValue = getDiscriminatorValue(cm.getClassname(), discriminator);
property.jsonSchema = String.format(Locale.ROOT, "{ \"default\":\"%s\"; \"type\":\"string\" }", cm.getSchemaName());

cm.vars.add(property);
Expand All @@ -743,14 +746,27 @@ private void postProcessPolymorphism(final List<ModelMap> allModels) {
}
}

private static boolean discriminating(final List<String> discriminatorsForModel, final CodegenModel cm) {
private static String getDiscriminatorValue(String modelName, CodegenDiscriminator discriminator) {
if (discriminator == null || discriminator.getMappedModels() == null) {
return modelName;
}
return discriminator
.getMappedModels()
.stream()
.filter(m -> m.getModelName().equals(modelName) && m.getMappingName() != null)
.map(CodegenDiscriminator.MappedModel::getMappingName)
.findFirst()
.orElse(modelName);
}

private static boolean discriminating(final List<CodegenDiscriminator> discriminatorsForModel, final CodegenModel cm) {
resetDiscriminatorProperty(cm);

// Discriminator will be presented as enum tag -> One and only one tag is allowed
int countString = 0;
int countNonString = 0;
for (final CodegenProperty var : cm.vars) {
if (discriminatorsForModel.stream().anyMatch(discriminator -> var.baseName.equals(discriminator) || var.name.equals(discriminator))) {
if (discriminatorsForModel.stream().anyMatch(discriminator -> var.baseName.equals(discriminator.getPropertyBaseName()) || var.name.equals(discriminator.getPropertyName()))) {
if (var.isString) {
var.isDiscriminator = true;
++countString;
Expand All @@ -773,7 +789,7 @@ private static void resetDiscriminatorProperty(final CodegenModel cm) {
}
}

private static void processPolymorphismDataType(final List<CodegenProperty> cp) {
private static void processPolymorphismDataType(final List<CodegenProperty> cp, CodegenDiscriminator discriminator) {
final HashSet<String> dedupDataTypeWithEnum = new HashSet<>();
final HashMap<String, Integer> dedupDataType = new HashMap<>();

Expand All @@ -783,6 +799,7 @@ private static void processPolymorphismDataType(final List<CodegenProperty> cp)
// Mainly needed for primitive types.
model.datatypeWithEnum = camelize(model.dataType.replaceAll("(?:\\w+::)+(\\w+)", "$1")
.replace("<", "Of").replace(">", "")).replace(" ", "").replace(",", "");
model.discriminatorValue = getDiscriminatorValue(model.datatypeWithEnum, discriminator);
if (!dedupDataTypeWithEnum.add(model.datatypeWithEnum)) {
model.datatypeWithEnum += ++idx;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,9 @@ impl std::str::FromStr for {{{classname}}} {
pub enum {{{classname}}} {
{{#composedSchemas}}
{{#anyOf}}
{{#discriminator}}
#[serde(alias = "{{{discriminatorValue}}}")]
{{/discriminator}}
{{{datatypeWithEnum}}}({{{dataType}}}),
{{/anyOf}}
{{/composedSchemas}}
Expand Down Expand Up @@ -871,6 +874,9 @@ impl From<{{{dataType}}}> for {{{classname}}} {
pub enum {{{classname}}} {
{{#composedSchemas}}
{{#oneOf}}
{{#discriminator}}
#[serde(alias = "{{{discriminatorValue}}}")]
{{/discriminator}}
{{{datatypeWithEnum}}}({{{dataType}}}),
{{/oneOf}}
{{/composedSchemas}}
Expand Down Expand Up @@ -1071,7 +1077,7 @@ pub struct {{{classname}}} {
{{#isString}}
impl {{{classname}}} {
fn _name_for_{{{name}}}() -> String {
String::from("{{{classname}}}")
String::from("{{#discriminatorValue}}{{{discriminatorValue}}}{{/discriminatorValue}}{{^discriminatorValue}}{{classname}}{{/discriminatorValue}}")
}

fn _serialize_{{{name}}}<S>(_: &String, s: S) -> Result<S::Ok, S::Error>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,4 +738,4 @@ components:
type:
type: string
message:
type: string
type: string
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,14 @@ components:
additionalProperties: false
discriminator:
propertyName: op
mapping:
yo: "#/components/schemas/YoMessage"
oneOf:
- "$ref": "#/components/schemas/Hello"
- "$ref": "#/components/schemas/Greeting"
- "$ref": "#/components/schemas/Goodbye"
- "$ref": "#/components/schemas/SomethingCompletelyDifferent"
- "$ref": "#/components/schemas/YoMessage"
title: Message
Hello:
type: object
Expand Down Expand Up @@ -141,3 +144,17 @@ components:
type: object
type: array
- type: object
YoMessage:
type: object
title: Yo
properties:
d:
type: object
properties:
nickname:
type: string
required:
- nickname
required:
- op
- d
Loading
Loading