mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-10-14 08:23:45 +00:00
This reverts commit ee40887d47f6d7a16318772f49c63b8eb0553488.
This commit is contained in:
parent
44a3be170f
commit
30096d63b7
@ -307,69 +307,6 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
|
|||||||
mdl.getComposedSchemas().setOneOf(newOneOfs);
|
mdl.getComposedSchemas().setOneOf(newOneOfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle anyOf schemas similarly to oneOf
|
|
||||||
// This is pragmatic since Rust's untagged enum will deserialize to the first matching variant
|
|
||||||
if (mdl.getComposedSchemas() != null && mdl.getComposedSchemas().getAnyOf() != null
|
|
||||||
&& !mdl.getComposedSchemas().getAnyOf().isEmpty()) {
|
|
||||||
|
|
||||||
List<CodegenProperty> newAnyOfs = mdl.getComposedSchemas().getAnyOf().stream()
|
|
||||||
.map(CodegenProperty::clone)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
List<Schema> schemas = ModelUtils.getInterfaces(model);
|
|
||||||
if (newAnyOfs.size() != schemas.size()) {
|
|
||||||
// For safety reasons, this should never happen unless there is an error in the code
|
|
||||||
throw new RuntimeException("anyOf size does not match the model");
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> refsMapping = Optional.ofNullable(model.getDiscriminator())
|
|
||||||
.map(Discriminator::getMapping).orElse(Collections.emptyMap());
|
|
||||||
|
|
||||||
// Reverse mapped references to use as baseName for anyOf, but different keys may point to the same $ref.
|
|
||||||
// Thus, we group them by the value
|
|
||||||
Map<String, List<String>> mappedNamesByRef = refsMapping.entrySet().stream()
|
|
||||||
.collect(Collectors.groupingBy(Map.Entry::getValue,
|
|
||||||
Collectors.mapping(Map.Entry::getKey, Collectors.toList())
|
|
||||||
));
|
|
||||||
|
|
||||||
for (int i = 0; i < newAnyOfs.size(); i++) {
|
|
||||||
CodegenProperty anyOf = newAnyOfs.get(i);
|
|
||||||
Schema schema = schemas.get(i);
|
|
||||||
|
|
||||||
if (mappedNamesByRef.containsKey(schema.get$ref())) {
|
|
||||||
// prefer mapped names if present
|
|
||||||
// remove mapping not in order not to reuse for the next occurrence of the ref
|
|
||||||
List<String> names = mappedNamesByRef.get(schema.get$ref());
|
|
||||||
String mappedName = names.remove(0);
|
|
||||||
anyOf.setBaseName(mappedName);
|
|
||||||
anyOf.setName(toModelName(mappedName));
|
|
||||||
} else if (!org.apache.commons.lang3.StringUtils.isEmpty(schema.get$ref())) {
|
|
||||||
// use $ref if it's reference
|
|
||||||
String refName = ModelUtils.getSimpleRef(schema.get$ref());
|
|
||||||
if (refName != null) {
|
|
||||||
String modelName = toModelName(refName);
|
|
||||||
anyOf.setName(modelName);
|
|
||||||
anyOf.setBaseName(refName);
|
|
||||||
}
|
|
||||||
} else if (anyOf.isArray) {
|
|
||||||
// If the type is an array, extend the name with the inner type to prevent name collisions
|
|
||||||
// in case multiple arrays with different types are defined. If the user has manually specified
|
|
||||||
// a name, use that name instead.
|
|
||||||
String collectionWithTypeName = toModelName(schema.getType()) + anyOf.containerTypeMapped + anyOf.items.dataType;
|
|
||||||
String anyOfName = Optional.ofNullable(schema.getTitle()).orElse(collectionWithTypeName);
|
|
||||||
anyOf.setName(anyOfName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// In-placed type (primitive), because there is no mapping or ref for it.
|
|
||||||
// use camelized `title` if present, otherwise use `type`
|
|
||||||
String anyOfName = Optional.ofNullable(schema.getTitle()).orElseGet(schema::getType);
|
|
||||||
anyOf.setName(toModelName(anyOfName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set anyOf as oneOf for template processing since we want the same output
|
|
||||||
mdl.getComposedSchemas().setOneOf(newAnyOfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mdl;
|
return mdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,145 +121,80 @@ impl Default for {{classname}} {
|
|||||||
{{!-- for non-enum schemas --}}
|
{{!-- for non-enum schemas --}}
|
||||||
{{^isEnum}}
|
{{^isEnum}}
|
||||||
{{^discriminator}}
|
{{^discriminator}}
|
||||||
{{#composedSchemas}}
|
{{#vendorExtensions.x-rust-has-byte-array}}#[serde_as]
|
||||||
{{#oneOf}}
|
{{/vendorExtensions.x-rust-has-byte-array}}{{#oneOf.isEmpty}}#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
{{#-first}}
|
pub struct {{{classname}}} {
|
||||||
{{! Model with composedSchemas.oneOf - generate enum}}
|
{{#vars}}
|
||||||
|
{{#description}}
|
||||||
|
/// {{{.}}}
|
||||||
|
{{/description}}
|
||||||
|
{{#isByteArray}}
|
||||||
|
{{#vendorExtensions.isMandatory}}#[serde_as(as = "serde_with::base64::Base64")]{{/vendorExtensions.isMandatory}}{{^vendorExtensions.isMandatory}}#[serde_as(as = "{{^serdeAsDoubleOption}}Option{{/serdeAsDoubleOption}}{{#serdeAsDoubleOption}}super::DoubleOption{{/serdeAsDoubleOption}}<serde_with::base64::Base64>")]{{/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}})]
|
||||||
|
pub {{{name}}}: {{!
|
||||||
|
### Option Start
|
||||||
|
}}{{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{!
|
||||||
|
### Enums
|
||||||
|
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
|
||||||
|
### Non-Enums Start
|
||||||
|
}}{{^isEnum}}{{!
|
||||||
|
### Models
|
||||||
|
}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{!
|
||||||
|
### Primative datatypes
|
||||||
|
}}{{^isModel}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isModel}}{{!
|
||||||
|
### Non-Enums End
|
||||||
|
}}{{/isEnum}}{{!
|
||||||
|
### Option End (and trailing comma)
|
||||||
|
}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
|
||||||
|
{{/vars}}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl {{{classname}}} {
|
||||||
|
{{#description}}
|
||||||
|
/// {{{.}}}
|
||||||
|
{{/description}}
|
||||||
|
pub fn new({{#requiredVars}}{{{name}}}: {{!
|
||||||
|
### Option Start
|
||||||
|
}}{{#isNullable}}Option<{{/isNullable}}{{!
|
||||||
|
### Enums
|
||||||
|
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
|
||||||
|
### Non-Enums
|
||||||
|
}}{{^isEnum}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isEnum}}{{!
|
||||||
|
### Option End
|
||||||
|
}}{{#isNullable}}>{{/isNullable}}{{!
|
||||||
|
### Comma for next arguement
|
||||||
|
}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
|
||||||
|
{{{classname}}} {
|
||||||
|
{{#vars}}
|
||||||
|
{{{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}},
|
||||||
|
{{/vars}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/oneOf.isEmpty}}
|
||||||
|
{{^oneOf.isEmpty}}
|
||||||
|
{{! TODO: add other vars that are not part of the oneOf}}
|
||||||
|
{{#description}}
|
||||||
|
/// {{{.}}}
|
||||||
|
{{/description}}
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum {{classname}} {
|
pub enum {{classname}} {
|
||||||
{{/-first}}
|
{{#composedSchemas.oneOf}}
|
||||||
{{/oneOf}}
|
|
||||||
{{/composedSchemas}}
|
|
||||||
{{#composedSchemas}}
|
|
||||||
{{#oneOf}}
|
|
||||||
{{#description}}
|
{{#description}}
|
||||||
/// {{{.}}}
|
/// {{{.}}}
|
||||||
{{/description}}
|
{{/description}}
|
||||||
{{{name}}}({{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{/isModel}}{{{dataType}}}{{#isModel}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}),
|
{{{name}}}({{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{/isModel}}{{{dataType}}}{{#isModel}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}),
|
||||||
{{/oneOf}}
|
{{/composedSchemas.oneOf}}
|
||||||
{{/composedSchemas}}
|
|
||||||
{{#composedSchemas}}
|
|
||||||
{{#oneOf}}
|
|
||||||
{{#-last}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for {{classname}} {
|
impl Default for {{classname}} {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
{{#oneOf}}{{#-first}}Self::{{{name}}}(Default::default()){{/-first}}{{/oneOf}}
|
{{#composedSchemas.oneOf}}{{#-first}}Self::{{{name}}}(Default::default()){{/-first}}{{/composedSchemas.oneOf}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/-last}}
|
{{/oneOf.isEmpty}}
|
||||||
{{/oneOf}}
|
|
||||||
{{^oneOf}}
|
|
||||||
{{! composedSchemas exists but no oneOf - generate normal struct}}
|
|
||||||
{{#vendorExtensions.x-rust-has-byte-array}}#[serde_as]
|
|
||||||
{{/vendorExtensions.x-rust-has-byte-array}}#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct {{{classname}}} {
|
|
||||||
{{#vars}}
|
|
||||||
{{#description}}
|
|
||||||
/// {{{.}}}
|
|
||||||
{{/description}}
|
|
||||||
{{#isByteArray}}
|
|
||||||
{{#vendorExtensions.isMandatory}}#[serde_as(as = "serde_with::base64::Base64")]{{/vendorExtensions.isMandatory}}{{^vendorExtensions.isMandatory}}#[serde_as(as = "{{^serdeAsDoubleOption}}Option{{/serdeAsDoubleOption}}{{#serdeAsDoubleOption}}super::DoubleOption{{/serdeAsDoubleOption}}<serde_with::base64::Base64>")]{{/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}})]
|
|
||||||
pub {{{name}}}: {{!
|
|
||||||
### Option Start
|
|
||||||
}}{{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{!
|
|
||||||
### Enums
|
|
||||||
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
|
|
||||||
### Non-Enums Start
|
|
||||||
}}{{^isEnum}}{{!
|
|
||||||
### Models
|
|
||||||
}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{!
|
|
||||||
### Primative datatypes
|
|
||||||
}}{{^isModel}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isModel}}{{!
|
|
||||||
### Non-Enums End
|
|
||||||
}}{{/isEnum}}{{!
|
|
||||||
### Option End (and trailing comma)
|
|
||||||
}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
|
|
||||||
{{/vars}}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl {{{classname}}} {
|
|
||||||
{{#description}}
|
|
||||||
/// {{{.}}}
|
|
||||||
{{/description}}
|
|
||||||
pub fn new({{#requiredVars}}{{{name}}}: {{!
|
|
||||||
### Option Start
|
|
||||||
}}{{#isNullable}}Option<{{/isNullable}}{{!
|
|
||||||
### Enums
|
|
||||||
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
|
|
||||||
### Non-Enums
|
|
||||||
}}{{^isEnum}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isEnum}}{{!
|
|
||||||
### Option End
|
|
||||||
}}{{#isNullable}}>{{/isNullable}}{{!
|
|
||||||
### Comma for next arguement
|
|
||||||
}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
|
|
||||||
{{{classname}}} {
|
|
||||||
{{#vars}}
|
|
||||||
{{{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}},
|
|
||||||
{{/vars}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{{/oneOf}}
|
|
||||||
{{/composedSchemas}}
|
|
||||||
{{^composedSchemas}}
|
|
||||||
{{! Normal struct without composedSchemas}}
|
|
||||||
{{#vendorExtensions.x-rust-has-byte-array}}#[serde_as]
|
|
||||||
{{/vendorExtensions.x-rust-has-byte-array}}#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct {{{classname}}} {
|
|
||||||
{{#vars}}
|
|
||||||
{{#description}}
|
|
||||||
/// {{{.}}}
|
|
||||||
{{/description}}
|
|
||||||
{{#isByteArray}}
|
|
||||||
{{#vendorExtensions.isMandatory}}#[serde_as(as = "serde_with::base64::Base64")]{{/vendorExtensions.isMandatory}}{{^vendorExtensions.isMandatory}}#[serde_as(as = "{{^serdeAsDoubleOption}}Option{{/serdeAsDoubleOption}}{{#serdeAsDoubleOption}}super::DoubleOption{{/serdeAsDoubleOption}}<serde_with::base64::Base64>")]{{/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}})]
|
|
||||||
pub {{{name}}}: {{!
|
|
||||||
### Option Start
|
|
||||||
}}{{#isNullable}}Option<{{/isNullable}}{{^required}}Option<{{/required}}{{!
|
|
||||||
### Enums
|
|
||||||
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
|
|
||||||
### Non-Enums Start
|
|
||||||
}}{{^isEnum}}{{!
|
|
||||||
### Models
|
|
||||||
}}{{#isModel}}{{^avoidBoxedModels}}Box<{{/avoidBoxedModels}}{{{dataType}}}{{^avoidBoxedModels}}>{{/avoidBoxedModels}}{{/isModel}}{{!
|
|
||||||
### Primative datatypes
|
|
||||||
}}{{^isModel}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isModel}}{{!
|
|
||||||
### Non-Enums End
|
|
||||||
}}{{/isEnum}}{{!
|
|
||||||
### Option End (and trailing comma)
|
|
||||||
}}{{#isNullable}}>{{/isNullable}}{{^required}}>{{/required}},
|
|
||||||
{{/vars}}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl {{{classname}}} {
|
|
||||||
{{#description}}
|
|
||||||
/// {{{.}}}
|
|
||||||
{{/description}}
|
|
||||||
pub fn new({{#requiredVars}}{{{name}}}: {{!
|
|
||||||
### Option Start
|
|
||||||
}}{{#isNullable}}Option<{{/isNullable}}{{!
|
|
||||||
### Enums
|
|
||||||
}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{!
|
|
||||||
### Non-Enums
|
|
||||||
}}{{^isEnum}}{{#isByteArray}}Vec<u8>{{/isByteArray}}{{^isByteArray}}{{{dataType}}}{{/isByteArray}}{{/isEnum}}{{!
|
|
||||||
### Option End
|
|
||||||
}}{{#isNullable}}>{{/isNullable}}{{!
|
|
||||||
### Comma for next arguement
|
|
||||||
}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
|
|
||||||
{{{classname}}} {
|
|
||||||
{{#vars}}
|
|
||||||
{{{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}},
|
|
||||||
{{/vars}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{{/composedSchemas}}
|
|
||||||
{{/discriminator}}
|
{{/discriminator}}
|
||||||
{{/isEnum}}
|
{{/isEnum}}
|
||||||
{{!-- for properties that are of enum type --}}
|
{{!-- for properties that are of enum type --}}
|
||||||
|
@ -271,37 +271,4 @@ public class RustClientCodegenTest {
|
|||||||
TestUtils.assertFileExists(outputPath);
|
TestUtils.assertFileExists(outputPath);
|
||||||
TestUtils.assertFileContains(outputPath, enumSpec);
|
TestUtils.assertFileContains(outputPath, enumSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAnyOfSupport() throws IOException {
|
|
||||||
Path target = Files.createTempDirectory("test-anyof");
|
|
||||||
final CodegenConfigurator configurator = new CodegenConfigurator()
|
|
||||||
.setGeneratorName("rust")
|
|
||||||
.setInputSpec("src/test/resources/3_0/rust/rust-anyof-test.yaml")
|
|
||||||
.setSkipOverwrite(false)
|
|
||||||
.setOutputDir(target.toAbsolutePath().toString().replace("\\", "/"));
|
|
||||||
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
|
|
||||||
files.forEach(File::deleteOnExit);
|
|
||||||
|
|
||||||
// Test that ModelIdentifier generates an untagged enum, not an empty struct
|
|
||||||
Path modelIdentifierPath = Path.of(target.toString(), "/src/models/model_identifier.rs");
|
|
||||||
TestUtils.assertFileExists(modelIdentifierPath);
|
|
||||||
|
|
||||||
// Should generate an untagged enum
|
|
||||||
TestUtils.assertFileContains(modelIdentifierPath, "#[serde(untagged)]");
|
|
||||||
TestUtils.assertFileContains(modelIdentifierPath, "pub enum ModelIdentifier");
|
|
||||||
|
|
||||||
// Should have String variant (for anyOf with string types)
|
|
||||||
TestUtils.assertFileContains(modelIdentifierPath, "String(String)");
|
|
||||||
|
|
||||||
// Should NOT generate an empty struct
|
|
||||||
TestUtils.assertFileNotContains(modelIdentifierPath, "pub struct ModelIdentifier {");
|
|
||||||
TestUtils.assertFileNotContains(modelIdentifierPath, "pub fn new()");
|
|
||||||
|
|
||||||
// Test AnotherAnyOfTest with mixed types
|
|
||||||
Path anotherTestPath = Path.of(target.toString(), "/src/models/another_any_of_test.rs");
|
|
||||||
TestUtils.assertFileExists(anotherTestPath);
|
|
||||||
TestUtils.assertFileContains(anotherTestPath, "#[serde(untagged)]");
|
|
||||||
TestUtils.assertFileContains(anotherTestPath, "pub enum AnotherAnyOfTest");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
openapi: 3.0.0
|
|
||||||
info:
|
|
||||||
title: Rust anyOf Test
|
|
||||||
version: 1.0.0
|
|
||||||
paths:
|
|
||||||
/model:
|
|
||||||
get:
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: OK
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/TestResponse'
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
TestResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
model:
|
|
||||||
$ref: '#/components/schemas/ModelIdentifier'
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
ModelIdentifier:
|
|
||||||
description: Model identifier that can be a string or specific enum value
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
description: Any model name as string
|
|
||||||
- type: string
|
|
||||||
enum:
|
|
||||||
- gpt-4
|
|
||||||
- gpt-3.5-turbo
|
|
||||||
- dall-e-3
|
|
||||||
description: Known model enum values
|
|
||||||
AnotherAnyOfTest:
|
|
||||||
description: Another test case with different types
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
- type: integer
|
|
||||||
- type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
Loading…
x
Reference in New Issue
Block a user