mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-10-14 16:33:56 +00:00
[Rust-Axum] Support AnyOf, AllOf (#21948)
* Support AnyOf, AllOf * Update * Fix * Update * Update * Update * Update * Update * Update * Update * Update * Update * Update * Update * Update
This commit is contained in:
parent
2afac1aa28
commit
e38f6c0580
@ -61,4 +61,4 @@
|
||||
- filename: "samples/server/petstore/rust-axum/output/rust-axum-oneof/tests/oneof_with_discriminator.rs"
|
||||
sha256: 2d4f5a069fdcb3057bb078d5e75b3de63cd477b97725e457079df24bd2c30600
|
||||
- filename: "samples/server/petstore/rust-axum/output/openapi-v3/tests/oneof_untagged.rs"
|
||||
sha256: e72fbf81a9849dc7abb7e2169f2fc355c8b1cf991c0e2ffc083126abd9e966e7
|
||||
sha256: 1d3fb01f65e98290b1d3eece28014c7d3e3f2fdf18e7110249d3c591cc4642ab
|
||||
|
@ -77,6 +77,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
<li>dyn</li>
|
||||
<li>else</li>
|
||||
<li>enum</li>
|
||||
<li>errors</li>
|
||||
<li>extern</li>
|
||||
<li>false</li>
|
||||
<li>final</li>
|
||||
@ -207,8 +208,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|Composite|✓|OAS2,OAS3
|
||||
|Polymorphism|✗|OAS2,OAS3
|
||||
|Union|✗|OAS3
|
||||
|allOf|✗|OAS2,OAS3
|
||||
|anyOf|✗|OAS3
|
||||
|allOf|✓|OAS2,OAS3
|
||||
|anyOf|✓|OAS3
|
||||
|oneOf|✓|OAS3
|
||||
|not|✗|OAS3
|
||||
|
||||
|
@ -99,6 +99,18 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
public RustAxumServerCodegen() {
|
||||
super();
|
||||
|
||||
// The `#[validate(nested)]` macro relies on an internal field named `errors` to accumulate validation results. Therefore, defining a struct like this will fail:
|
||||
//
|
||||
// ```rust
|
||||
// struct A {
|
||||
// #[validate(nested)]
|
||||
// errors: B,
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// To avoid this, either rename the field to something other than "errors", or reserve it.
|
||||
this.reservedWords.add("errors");
|
||||
|
||||
modifyFeatureSet(features -> features
|
||||
.wireFormatFeatures(EnumSet.of(
|
||||
WireFormatFeature.JSON,
|
||||
@ -112,7 +124,9 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
.schemaSupportFeatures(EnumSet.of(
|
||||
SchemaSupportFeature.Simple,
|
||||
SchemaSupportFeature.Composite,
|
||||
SchemaSupportFeature.oneOf
|
||||
SchemaSupportFeature.oneOf,
|
||||
SchemaSupportFeature.anyOf,
|
||||
SchemaSupportFeature.allOf
|
||||
))
|
||||
.excludeGlobalFeatures(
|
||||
GlobalFeature.Info,
|
||||
@ -633,105 +647,163 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
return op;
|
||||
}
|
||||
|
||||
private void postProcessOneOfModels(List<ModelMap> allModels) {
|
||||
final HashMap<String, List<String>> oneOfMapDiscriminator = new HashMap<>();
|
||||
private void postProcessPolymorphism(final List<ModelMap> allModels) {
|
||||
final HashMap<String, List<String>> discriminatorsForModel = new HashMap<>();
|
||||
|
||||
for (ModelMap mo : allModels) {
|
||||
for (final ModelMap mo : allModels) {
|
||||
final CodegenModel cm = mo.getModel();
|
||||
|
||||
final CodegenComposedSchemas cs = cm.getComposedSchemas();
|
||||
if (cs != null) {
|
||||
final List<CodegenProperty> csOneOf = cs.getOneOf();
|
||||
|
||||
if (csOneOf != null) {
|
||||
for (CodegenProperty model : csOneOf) {
|
||||
// Generate a valid name for the enum variant.
|
||||
// Mainly needed for primitive types.
|
||||
|
||||
model.datatypeWithEnum = camelize(model.dataType.replaceAll("(?:\\w+::)+(\\w+)", "$1")
|
||||
.replace("<", "Of").replace(">", ""));
|
||||
|
||||
// Primitive type is not properly set, this overrides it to guarantee adequate model generation.
|
||||
if (!model.getDataType().matches(String.format(Locale.ROOT, ".*::%s", model.getDatatypeWithEnum()))) {
|
||||
model.isPrimitiveType = true;
|
||||
}
|
||||
}
|
||||
|
||||
processPolymorphismDataType(csOneOf);
|
||||
cs.setOneOf(csOneOf);
|
||||
cm.setComposedSchemas(cs);
|
||||
}
|
||||
|
||||
final List<CodegenProperty> csAnyOf = cs.getAnyOf();
|
||||
if (csAnyOf != null) {
|
||||
processPolymorphismDataType(csAnyOf);
|
||||
cs.setAnyOf(csAnyOf);
|
||||
cm.setComposedSchemas(cs);
|
||||
}
|
||||
}
|
||||
|
||||
if (cm.discriminator != null) {
|
||||
for (String model : cm.oneOf) {
|
||||
List<String> discriminators = oneOfMapDiscriminator.getOrDefault(model, new ArrayList<>());
|
||||
for (final String model : cm.oneOf) {
|
||||
final List<String> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
|
||||
discriminators.add(cm.discriminator.getPropertyName());
|
||||
oneOfMapDiscriminator.put(model, discriminators);
|
||||
discriminatorsForModel.put(model, discriminators);
|
||||
}
|
||||
|
||||
for (final String model : cm.anyOf) {
|
||||
final List<String> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
|
||||
discriminators.add(cm.discriminator.getPropertyName());
|
||||
discriminatorsForModel.put(model, discriminators);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final var blocking = new HashSet<String>();
|
||||
for (ModelMap mo : allModels) {
|
||||
final CodegenModel cm = mo.getModel();
|
||||
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
var.isDiscriminator = false;
|
||||
final List<String> 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);
|
||||
|
||||
CodegenProperty property = new CodegenProperty();
|
||||
|
||||
// Static attributes
|
||||
// Only strings are supported by serde for tag field types, so it's the only one we'll deal with
|
||||
property.openApiType = "string";
|
||||
property.complexType = "string";
|
||||
property.dataType = "String";
|
||||
property.datatypeWithEnum = "String";
|
||||
property.baseType = "string";
|
||||
property.required = true;
|
||||
property.isPrimitiveType = true;
|
||||
property.isString = true;
|
||||
property.isDiscriminator = true;
|
||||
|
||||
// Attributes based on the discriminator value
|
||||
property.baseName = discriminator;
|
||||
property.name = discriminator;
|
||||
property.nameInCamelCase = camelize(discriminator);
|
||||
property.nameInPascalCase = property.nameInCamelCase.substring(0, 1).toUpperCase(Locale.ROOT) + property.nameInCamelCase.substring(1);
|
||||
property.nameInSnakeCase = underscore(discriminator).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.jsonSchema = String.format(Locale.ROOT, "{ \"default\":\"%s\"; \"type\":\"string\" }", cm.getSchemaName());
|
||||
|
||||
cm.vars.add(property);
|
||||
}
|
||||
}
|
||||
|
||||
final List<String> discriminatorsForModel = oneOfMapDiscriminator.get(cm.getSchemaName());
|
||||
if (cm.vars.stream().noneMatch(v -> v.isDiscriminator)) {
|
||||
blocking.add(cm.getSchemaName());
|
||||
}
|
||||
}
|
||||
|
||||
if (discriminatorsForModel != null) {
|
||||
for (String discriminator : discriminatorsForModel) {
|
||||
boolean hasDiscriminatorDefined = false;
|
||||
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
if (var.baseName.equals(discriminator)) {
|
||||
var.isDiscriminator = true;
|
||||
hasDiscriminatorDefined = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the discriminator field is not a defined attribute in the variant structure, create it.
|
||||
if (!hasDiscriminatorDefined) {
|
||||
CodegenProperty property = new CodegenProperty();
|
||||
|
||||
// Static attributes
|
||||
// Only strings are supported by serde for tag field types, so it's the only one we'll deal with
|
||||
property.openApiType = "string";
|
||||
property.complexType = "string";
|
||||
property.dataType = "String";
|
||||
property.datatypeWithEnum = "String";
|
||||
property.baseType = "string";
|
||||
property.required = true;
|
||||
property.isPrimitiveType = true;
|
||||
property.isString = true;
|
||||
property.isDiscriminator = true;
|
||||
|
||||
// Attributes based on the discriminator value
|
||||
property.baseName = discriminator;
|
||||
property.name = discriminator;
|
||||
property.nameInCamelCase = camelize(discriminator);
|
||||
property.nameInPascalCase = property.nameInCamelCase.substring(0, 1).toUpperCase(Locale.ROOT) + property.nameInCamelCase.substring(1);
|
||||
property.nameInSnakeCase = underscore(discriminator).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.jsonSchema = String.format(Locale.ROOT, "{ \"default\":\"%s\"; \"type\":\"string\" }", cm.getSchemaName());
|
||||
|
||||
cm.vars.add(property);
|
||||
}
|
||||
for (final ModelMap mo : allModels) {
|
||||
final CodegenModel cm = mo.getModel();
|
||||
if (cm.discriminator != null) {
|
||||
// if no discriminator in any of variant -> disable discriminator
|
||||
if (cm.oneOf.stream().anyMatch(blocking::contains) || cm.anyOf.stream().anyMatch(blocking::contains)) {
|
||||
cm.discriminator = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean discriminating(final List<String> 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 (var.isString) {
|
||||
var.isDiscriminator = true;
|
||||
++countString;
|
||||
} else
|
||||
++countNonString;
|
||||
}
|
||||
}
|
||||
|
||||
if (countString > 0 && (countNonString > 0 || countString > 1)) {
|
||||
// at least two discriminator, one of them is string -> should not render serde tag
|
||||
resetDiscriminatorProperty(cm);
|
||||
}
|
||||
|
||||
return countNonString > 0 || countString > 0;
|
||||
}
|
||||
|
||||
private static void resetDiscriminatorProperty(final CodegenModel cm) {
|
||||
for (final CodegenProperty var : cm.vars) {
|
||||
var.isDiscriminator = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void processPolymorphismDataType(final List<CodegenProperty> cp) {
|
||||
final HashSet<String> dedupDataTypeWithEnum = new HashSet<>();
|
||||
final HashMap<String, Integer> dedupDataType = new HashMap<>();
|
||||
|
||||
int idx = 0;
|
||||
for (CodegenProperty model : cp) {
|
||||
// Generate a valid name for the enum variant.
|
||||
// Mainly needed for primitive types.
|
||||
model.datatypeWithEnum = camelize(model.dataType.replaceAll("(?:\\w+::)+(\\w+)", "$1")
|
||||
.replace("<", "Of").replace(">", "")).replace(" ", "").replace(",", "");
|
||||
if (!dedupDataTypeWithEnum.add(model.datatypeWithEnum)) {
|
||||
model.datatypeWithEnum += ++idx;
|
||||
}
|
||||
|
||||
dedupDataType.put(model.getDataType(), dedupDataType.getOrDefault(model.getDataType(), 0) + 1);
|
||||
|
||||
if (!model.getDataType().matches(String.format(Locale.ROOT, ".*::%s", model.getDatatypeWithEnum()))) {
|
||||
model.isPrimitiveType = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenProperty model : cp) {
|
||||
if (dedupDataType.get(model.getDataType()) == 1) {
|
||||
model.vendorExtensions.put("x-from-trait", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationsMap postProcessOperationsWithModels(final OperationsMap operationsMap, List<ModelMap> allModels) {
|
||||
postProcessOneOfModels(allModels);
|
||||
postProcessPolymorphism(allModels);
|
||||
|
||||
final OperationMap operations = operationsMap.getOperations();
|
||||
operations.put("classnamePascalCase", camelize(operations.getClassname()));
|
||||
@ -901,7 +973,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
// restore things to sensible values.
|
||||
@Override
|
||||
public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, String bodyParameterName) {
|
||||
final Schema original_schema = ModelUtils.getSchemaFromRequestBody(body);
|
||||
final var original_schema = ModelUtils.getSchemaFromRequestBody(body);
|
||||
CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName);
|
||||
|
||||
if (StringUtils.isNotBlank(original_schema.get$ref())) {
|
||||
@ -920,10 +992,10 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
@Override
|
||||
public String toInstantiationType(final Schema p) {
|
||||
if (ModelUtils.isArraySchema(p)) {
|
||||
final Schema inner = ModelUtils.getSchemaItems(p);
|
||||
final var inner = ModelUtils.getSchemaItems(p);
|
||||
return instantiationTypes.get("array") + "<" + getSchemaType(inner) + ">";
|
||||
} else if (ModelUtils.isMapSchema(p)) {
|
||||
final Schema inner = ModelUtils.getAdditionalProperties(p);
|
||||
final var inner = ModelUtils.getAdditionalProperties(p);
|
||||
return instantiationTypes.get("map") + "<" + typeMapping.get("string") + ", " + getSchemaType(inner) + ">";
|
||||
} else {
|
||||
return null;
|
||||
@ -952,6 +1024,10 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
@Override
|
||||
public String toDefaultValue(final Schema p) {
|
||||
String defaultValue = null;
|
||||
|
||||
if (ModelUtils.isEnumSchema(p))
|
||||
return null;
|
||||
|
||||
if ((ModelUtils.isNullable(p)) && (p.getDefault() != null) && ("null".equalsIgnoreCase(p.getDefault().toString())))
|
||||
return "Nullable::Null";
|
||||
|
||||
@ -965,6 +1041,9 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
} else if (ModelUtils.isNumberSchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
defaultValue = p.getDefault().toString();
|
||||
if (!defaultValue.contains(".")) {
|
||||
defaultValue += ".0";
|
||||
}
|
||||
}
|
||||
} else if (ModelUtils.isIntegerSchema(p)) {
|
||||
if (p.getDefault() != null) {
|
||||
@ -1081,7 +1160,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
String cmd = System.getenv("RUST_POST_PROCESS_FILE");
|
||||
if (StringUtils.isEmpty(cmd)) {
|
||||
cmd = "rustfmt";
|
||||
command = new String[]{cmd, "--edition", "2021", fileName};
|
||||
command = new String[]{cmd, "--edition", "2024", fileName};
|
||||
} else {
|
||||
command = new String[]{cmd, fileName};
|
||||
}
|
||||
@ -1093,7 +1172,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateParameterForString(CodegenParameter codegenParameter, Schema parameterSchema) {
|
||||
protected void updateParameterForString(CodegenParameter codegenParameter, final Schema parameterSchema) {
|
||||
if (ModelUtils.isEmailSchema(parameterSchema)) {
|
||||
codegenParameter.isEmail = true;
|
||||
} else if (ModelUtils.isUUIDSchema(parameterSchema)) {
|
||||
@ -1120,7 +1199,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
codegenParameter.isDecimal = true;
|
||||
codegenParameter.isPrimitiveType = true;
|
||||
}
|
||||
if (Boolean.TRUE.equals(codegenParameter.isString)) {
|
||||
if (codegenParameter.isString) {
|
||||
codegenParameter.isPrimitiveType = true;
|
||||
}
|
||||
}
|
||||
@ -1152,6 +1231,16 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
final var varName = super.toVarName(name);
|
||||
|
||||
if (varName.startsWith("r#"))
|
||||
return "r_" + varName.substring(2);
|
||||
|
||||
return varName;
|
||||
}
|
||||
|
||||
static class PathMethodOperations {
|
||||
public String path;
|
||||
public ArrayList<MethodOperation> methodOperations;
|
||||
|
@ -524,7 +524,7 @@ pub fn check_xss_map<T>(v: &std::collections::HashMap<String, T>) -> std::result
|
||||
/// Enumeration of values.
|
||||
/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]`
|
||||
/// which helps with FFI.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
|
||||
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
|
||||
@ -751,17 +751,38 @@ impl std::str::FromStr for {{{classname}}} {
|
||||
{{^arrayModelType}}
|
||||
{{! general struct}}
|
||||
{{#anyOf.size}}
|
||||
/// Any of:
|
||||
{{#anyOf}}
|
||||
/// - {{{.}}}
|
||||
{{/anyOf}}
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct {{{classname}}}(Box<serde_json::value::RawValue>);
|
||||
{{#discriminator}}
|
||||
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
|
||||
#[serde(tag = "{{{propertyBaseName}}}")]
|
||||
{{/discriminator}}
|
||||
{{^discriminator}}
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
{{/discriminator}}
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum {{{classname}}} {
|
||||
{{#composedSchemas}}
|
||||
{{#anyOf}}
|
||||
{{{datatypeWithEnum}}}({{{dataType}}}),
|
||||
{{/anyOf}}
|
||||
{{/composedSchemas}}
|
||||
}
|
||||
|
||||
impl validator::Validate for {{{classname}}}
|
||||
{
|
||||
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
|
||||
std::result::Result::Ok(())
|
||||
match self {
|
||||
{{#composedSchemas}}
|
||||
{{#anyOf}}
|
||||
{{^isModel}}
|
||||
Self::{{{datatypeWithEnum}}}(_) => std::result::Result::Ok(()),
|
||||
{{/isModel}}
|
||||
{{#isModel}}
|
||||
Self::{{{datatypeWithEnum}}}(v) => v.validate(),
|
||||
{{/isModel}}
|
||||
{{/anyOf}}
|
||||
{{/composedSchemas}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -776,11 +797,32 @@ impl std::str::FromStr for {{{classname}}} {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for {{{classname}}} {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.get() == other.0.get()
|
||||
{{#discriminator}}
|
||||
impl serde::Serialize for {{{classname}}} {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: serde::Serializer {
|
||||
match self {
|
||||
{{#composedSchemas}}
|
||||
{{#anyOf}}
|
||||
Self::{{{datatypeWithEnum}}}(x) => x.serialize(serializer),
|
||||
{{/anyOf}}
|
||||
{{/composedSchemas}}
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/discriminator}}
|
||||
|
||||
{{#composedSchemas}}
|
||||
{{#anyOf}}
|
||||
{{#vendorExtensions.x-from-trait}}
|
||||
impl From<{{{dataType}}}> for {{{classname}}} {
|
||||
fn from(value: {{{dataType}}}) -> Self {
|
||||
Self::{{{datatypeWithEnum}}}(value)
|
||||
}
|
||||
}
|
||||
{{/vendorExtensions.x-from-trait}}
|
||||
{{/anyOf}}
|
||||
{{/composedSchemas}}
|
||||
|
||||
{{/anyOf.size}}
|
||||
{{#oneOf.size}}
|
||||
@ -792,11 +834,11 @@ impl PartialEq for {{{classname}}} {
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
{{/discriminator}}
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum {{{classname}}} {
|
||||
{{#composedSchemas}}
|
||||
{{#oneOf}}
|
||||
{{{datatypeWithEnum}}}(Box<{{{dataType}}}>),
|
||||
{{{datatypeWithEnum}}}({{{dataType}}}),
|
||||
{{/oneOf}}
|
||||
{{/composedSchemas}}
|
||||
}
|
||||
@ -807,18 +849,29 @@ impl validator::Validate for {{{classname}}}
|
||||
match self {
|
||||
{{#composedSchemas}}
|
||||
{{#oneOf}}
|
||||
{{#isPrimitiveType}}
|
||||
{{^isModel}}
|
||||
Self::{{{datatypeWithEnum}}}(_) => std::result::Result::Ok(()),
|
||||
{{/isPrimitiveType}}
|
||||
{{^isPrimitiveType}}
|
||||
Self::{{{datatypeWithEnum}}}(x) => x.validate(),
|
||||
{{/isPrimitiveType}}
|
||||
{{/isModel}}
|
||||
{{#isModel}}
|
||||
Self::{{{datatypeWithEnum}}}(v) => v.validate(),
|
||||
{{/isModel}}
|
||||
{{/oneOf}}
|
||||
{{/composedSchemas}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value
|
||||
/// as specified in https://swagger.io/docs/specification/serialization/
|
||||
/// Should be implemented in a serde deserializer
|
||||
impl std::str::FromStr for {{{classname}}} {
|
||||
type Err = serde_json::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
serde_json::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
{{#discriminator}}
|
||||
impl serde::Serialize for {{{classname}}} {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@ -834,29 +887,18 @@ impl serde::Serialize for {{{classname}}} {
|
||||
}
|
||||
{{/discriminator}}
|
||||
|
||||
|
||||
|
||||
{{#composedSchemas}}
|
||||
{{#oneOf}}
|
||||
{{#vendorExtensions.x-from-trait}}
|
||||
impl From<{{{dataType}}}> for {{{classname}}} {
|
||||
fn from(value: {{{dataType}}}) -> Self {
|
||||
Self::{{{datatypeWithEnum}}}(Box::new(value))
|
||||
Self::{{{datatypeWithEnum}}}(value)
|
||||
}
|
||||
}
|
||||
{{/vendorExtensions.x-from-trait}}
|
||||
{{/oneOf}}
|
||||
{{/composedSchemas}}
|
||||
|
||||
/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value
|
||||
/// as specified in https://swagger.io/docs/specification/serialization/
|
||||
/// Should be implemented in a serde deserializer
|
||||
impl std::str::FromStr for {{{classname}}} {
|
||||
type Err = serde_json::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
serde_json::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
{{/oneOf.size}}
|
||||
{{^anyOf.size}}
|
||||
{{^oneOf.size}}
|
||||
@ -871,8 +913,10 @@ pub struct {{{classname}}} {
|
||||
/// Note: inline enums are not fully supported by openapi-generator
|
||||
{{/isEnum}}
|
||||
{{#isDiscriminator}}
|
||||
{{#isString}}
|
||||
#[serde(default = "{{{classname}}}::_name_for_{{{name}}}")]
|
||||
#[serde(serialize_with = "{{{classname}}}::_serialize_{{{name}}}")]
|
||||
{{/isString}}
|
||||
{{/isDiscriminator}}
|
||||
#[serde(rename = "{{{baseName}}}")]
|
||||
{{#hasValidation}}
|
||||
@ -989,9 +1033,9 @@ pub struct {{{classname}}} {
|
||||
{{/vars}}
|
||||
}
|
||||
|
||||
|
||||
{{#vars}}
|
||||
{{#isDiscriminator}}
|
||||
{{#isString}}
|
||||
impl {{{classname}}} {
|
||||
fn _name_for_{{{name}}}() -> String {
|
||||
String::from("{{{classname}}}")
|
||||
@ -1004,10 +1048,10 @@ impl {{{classname}}} {
|
||||
s.serialize_str(&Self::_name_for_{{{name}}}())
|
||||
}
|
||||
}
|
||||
{{/isString}}
|
||||
{{/isDiscriminator}}
|
||||
{{/vars}}
|
||||
|
||||
|
||||
{{#vars}}
|
||||
{{#hasValidation}}
|
||||
{{#pattern}}
|
||||
@ -1035,9 +1079,9 @@ fn validate_byte_{{#lambda.lowercase}}{{{classname}}}_{{{name}}}{{/lambda.lowerc
|
||||
|
||||
impl {{{classname}}} {
|
||||
#[allow(clippy::new_without_default, clippy::too_many_arguments)]
|
||||
pub fn new({{#vars}}{{^defaultValue}}{{{name}}}: {{#isNullable}}Nullable<{{/isNullable}}{{{dataType}}}{{#isNullable}}>{{/isNullable}}, {{/defaultValue}}{{/vars}}) -> {{{classname}}} {
|
||||
pub fn new({{#vars}}{{^isDiscriminator}}{{^defaultValue}}{{{name}}}: {{#isNullable}}Nullable<{{/isNullable}}{{{dataType}}}{{#isNullable}}>{{/isNullable}}, {{/defaultValue}}{{/isDiscriminator}}{{#isDiscriminator}}{{^isString}}{{^defaultValue}}{{{name}}}: {{#isNullable}}Nullable<{{/isNullable}}{{{dataType}}}{{#isNullable}}>{{/isNullable}}, {{/defaultValue}}{{/isString}}{{/isDiscriminator}}{{/vars}}) -> {{{classname}}} {
|
||||
{{{classname}}} {
|
||||
{{#vars}} {{#defaultValue}}{{{name}}}: {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}},
|
||||
{{#vars}} {{^isDiscriminator}}{{#defaultValue}}{{{name}}}: {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}}{{/isDiscriminator}}{{#isDiscriminator}}{{#isString}}{{{name}}}: Self::_name_for_{{{name}}}(){{/isString}}{{^isString}}{{#defaultValue}}{{{name}}}: {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}}{{/isString}}{{/isDiscriminator}},
|
||||
{{/vars}}
|
||||
}
|
||||
}
|
||||
@ -1075,7 +1119,7 @@ impl std::fmt::Display for {{{classname}}} {
|
||||
{{/isArray}}
|
||||
{{#isArray}}
|
||||
{{#isNullable}}
|
||||
Some(self.{{{name}}}.as_ref().map_or(vec!["null".to_string()], |x| x.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))),
|
||||
Some(self.{{{name}}}.as_ref().map_or("null".to_string(), |x| x.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))),
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
Some(self.{{{name}}}.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",")),
|
||||
@ -1226,7 +1270,6 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<{{{classname
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{{/oneOf.size}}
|
||||
{{/anyOf.size}}
|
||||
|
||||
|
@ -594,7 +594,7 @@ pub struct PaymentMethod {
|
||||
#[serde(rename = "type")]
|
||||
#[validate(custom(function = "check_xss_string"))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub r#type: Option<String>,
|
||||
pub r_type: Option<String>,
|
||||
}
|
||||
|
||||
impl PaymentMethod {
|
||||
@ -602,7 +602,7 @@ impl PaymentMethod {
|
||||
pub fn new() -> PaymentMethod {
|
||||
PaymentMethod {
|
||||
name: None,
|
||||
r#type: None,
|
||||
r_type: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -616,9 +616,9 @@ impl std::fmt::Display for PaymentMethod {
|
||||
self.name
|
||||
.as_ref()
|
||||
.map(|name| ["name".to_string(), name.to_string()].join(",")),
|
||||
self.r#type
|
||||
self.r_type
|
||||
.as_ref()
|
||||
.map(|r#type| ["type".to_string(), r#type.to_string()].join(",")),
|
||||
.map(|r_type| ["type".to_string(), r_type.to_string()].join(",")),
|
||||
];
|
||||
|
||||
write!(
|
||||
@ -641,7 +641,7 @@ impl std::str::FromStr for PaymentMethod {
|
||||
#[allow(dead_code)]
|
||||
struct IntermediateRep {
|
||||
pub name: Vec<String>,
|
||||
pub r#type: Vec<String>,
|
||||
pub r_type: Vec<String>,
|
||||
}
|
||||
|
||||
let mut intermediate_rep = IntermediateRep::default();
|
||||
@ -668,7 +668,7 @@ impl std::str::FromStr for PaymentMethod {
|
||||
<String as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
#[allow(clippy::redundant_clone)]
|
||||
"type" => intermediate_rep.r#type.push(
|
||||
"type" => intermediate_rep.r_type.push(
|
||||
<String as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
_ => {
|
||||
@ -686,7 +686,7 @@ impl std::str::FromStr for PaymentMethod {
|
||||
// Use the intermediate representation to return the struct
|
||||
std::result::Result::Ok(PaymentMethod {
|
||||
name: intermediate_rep.name.into_iter().next(),
|
||||
r#type: intermediate_rep.r#type.into_iter().next(),
|
||||
r_type: intermediate_rep.r_type.into_iter().next(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -594,7 +594,7 @@ pub struct PaymentMethod {
|
||||
#[serde(rename = "type")]
|
||||
#[validate(custom(function = "check_xss_string"))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub r#type: Option<String>,
|
||||
pub r_type: Option<String>,
|
||||
}
|
||||
|
||||
impl PaymentMethod {
|
||||
@ -602,7 +602,7 @@ impl PaymentMethod {
|
||||
pub fn new() -> PaymentMethod {
|
||||
PaymentMethod {
|
||||
name: None,
|
||||
r#type: None,
|
||||
r_type: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -616,9 +616,9 @@ impl std::fmt::Display for PaymentMethod {
|
||||
self.name
|
||||
.as_ref()
|
||||
.map(|name| ["name".to_string(), name.to_string()].join(",")),
|
||||
self.r#type
|
||||
self.r_type
|
||||
.as_ref()
|
||||
.map(|r#type| ["type".to_string(), r#type.to_string()].join(",")),
|
||||
.map(|r_type| ["type".to_string(), r_type.to_string()].join(",")),
|
||||
];
|
||||
|
||||
write!(
|
||||
@ -641,7 +641,7 @@ impl std::str::FromStr for PaymentMethod {
|
||||
#[allow(dead_code)]
|
||||
struct IntermediateRep {
|
||||
pub name: Vec<String>,
|
||||
pub r#type: Vec<String>,
|
||||
pub r_type: Vec<String>,
|
||||
}
|
||||
|
||||
let mut intermediate_rep = IntermediateRep::default();
|
||||
@ -668,7 +668,7 @@ impl std::str::FromStr for PaymentMethod {
|
||||
<String as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
#[allow(clippy::redundant_clone)]
|
||||
"type" => intermediate_rep.r#type.push(
|
||||
"type" => intermediate_rep.r_type.push(
|
||||
<String as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
_ => {
|
||||
@ -686,7 +686,7 @@ impl std::str::FromStr for PaymentMethod {
|
||||
// Use the intermediate representation to return the struct
|
||||
std::result::Result::Ok(PaymentMethod {
|
||||
name: intermediate_rep.name.into_iter().next(),
|
||||
r#type: intermediate_rep.r#type.into_iter().next(),
|
||||
r_type: intermediate_rep.r_type.into_iter().next(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -767,15 +767,20 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<AnotherXmlOb
|
||||
}
|
||||
}
|
||||
|
||||
/// Any of:
|
||||
/// - String
|
||||
/// - uuid::Uuid
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct AnyOfGet202Response(Box<serde_json::value::RawValue>);
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum AnyOfGet202Response {
|
||||
String(String),
|
||||
Uuid(uuid::Uuid),
|
||||
}
|
||||
|
||||
impl validator::Validate for AnyOfGet202Response {
|
||||
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
|
||||
std::result::Result::Ok(())
|
||||
match self {
|
||||
Self::String(_) => std::result::Result::Ok(()),
|
||||
Self::Uuid(_) => std::result::Result::Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -790,22 +795,32 @@ impl std::str::FromStr for AnyOfGet202Response {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for AnyOfGet202Response {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.get() == other.0.get()
|
||||
impl From<String> for AnyOfGet202Response {
|
||||
fn from(value: String) -> Self {
|
||||
Self::String(value)
|
||||
}
|
||||
}
|
||||
impl From<uuid::Uuid> for AnyOfGet202Response {
|
||||
fn from(value: uuid::Uuid) -> Self {
|
||||
Self::Uuid(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Test a model containing an anyOf of a hash map
|
||||
/// Any of:
|
||||
/// - String
|
||||
/// - std::collections::HashMap<String, String>
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct AnyOfHashMapObject(Box<serde_json::value::RawValue>);
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum AnyOfHashMapObject {
|
||||
String(String),
|
||||
HashMapOfStringString(std::collections::HashMap<String, String>),
|
||||
}
|
||||
|
||||
impl validator::Validate for AnyOfHashMapObject {
|
||||
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
|
||||
std::result::Result::Ok(())
|
||||
match self {
|
||||
Self::String(_) => std::result::Result::Ok(()),
|
||||
Self::HashMapOfStringString(_) => std::result::Result::Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -820,21 +835,32 @@ impl std::str::FromStr for AnyOfHashMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for AnyOfHashMapObject {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.get() == other.0.get()
|
||||
impl From<String> for AnyOfHashMapObject {
|
||||
fn from(value: String) -> Self {
|
||||
Self::String(value)
|
||||
}
|
||||
}
|
||||
impl From<std::collections::HashMap<String, String>> for AnyOfHashMapObject {
|
||||
fn from(value: std::collections::HashMap<String, String>) -> Self {
|
||||
Self::HashMapOfStringString(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Test a model containing an anyOf
|
||||
/// Any of:
|
||||
/// - String
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct AnyOfObject(Box<serde_json::value::RawValue>);
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum AnyOfObject {
|
||||
String(String),
|
||||
String1(String),
|
||||
}
|
||||
|
||||
impl validator::Validate for AnyOfObject {
|
||||
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
|
||||
std::result::Result::Ok(())
|
||||
match self {
|
||||
Self::String(_) => std::result::Result::Ok(()),
|
||||
Self::String1(_) => std::result::Result::Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -849,12 +875,6 @@ impl std::str::FromStr for AnyOfObject {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for AnyOfObject {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.get() == other.0.get()
|
||||
}
|
||||
}
|
||||
|
||||
/// Test containing an anyOf object
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)]
|
||||
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
|
||||
@ -1166,7 +1186,7 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<DuplicateXml
|
||||
/// Enumeration of values.
|
||||
/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]`
|
||||
/// which helps with FFI.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
#[repr(C)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
|
||||
@ -1451,14 +1471,20 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<FormTestRequ
|
||||
}
|
||||
|
||||
/// Test a model containing an anyOf that starts with a number
|
||||
/// Any of:
|
||||
/// - String
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Model12345AnyOfObject(Box<serde_json::value::RawValue>);
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum Model12345AnyOfObject {
|
||||
String(String),
|
||||
String1(String),
|
||||
}
|
||||
|
||||
impl validator::Validate for Model12345AnyOfObject {
|
||||
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
|
||||
std::result::Result::Ok(())
|
||||
match self {
|
||||
Self::String(_) => std::result::Result::Ok(()),
|
||||
Self::String1(_) => std::result::Result::Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1473,12 +1499,6 @@ impl std::str::FromStr for Model12345AnyOfObject {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Model12345AnyOfObject {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.get() == other.0.get()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)]
|
||||
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
|
||||
pub struct MultigetGet201Response {
|
||||
@ -2319,8 +2339,9 @@ pub struct ObjectParam {
|
||||
pub required_param: bool,
|
||||
|
||||
#[serde(rename = "optionalParam")]
|
||||
#[validate(range(min = 1u64, max = 10000000000000000000u64))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub optional_param: Option<i32>,
|
||||
pub optional_param: Option<u64>,
|
||||
}
|
||||
|
||||
impl ObjectParam {
|
||||
@ -2366,7 +2387,7 @@ impl std::str::FromStr for ObjectParam {
|
||||
#[allow(dead_code)]
|
||||
struct IntermediateRep {
|
||||
pub required_param: Vec<bool>,
|
||||
pub optional_param: Vec<i32>,
|
||||
pub optional_param: Vec<u64>,
|
||||
}
|
||||
|
||||
let mut intermediate_rep = IntermediateRep::default();
|
||||
@ -2394,7 +2415,7 @@ impl std::str::FromStr for ObjectParam {
|
||||
),
|
||||
#[allow(clippy::redundant_clone)]
|
||||
"optionalParam" => intermediate_rep.optional_param.push(
|
||||
<i32 as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
<u64 as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
_ => {
|
||||
return std::result::Result::Err(
|
||||
@ -2813,10 +2834,10 @@ impl std::ops::DerefMut for Ok {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum OneOfGet200Response {
|
||||
I32(Box<i32>),
|
||||
VecOfString(Box<Vec<String>>),
|
||||
I32(i32),
|
||||
VecOfString(Vec<String>),
|
||||
}
|
||||
|
||||
impl validator::Validate for OneOfGet200Response {
|
||||
@ -2828,17 +2849,6 @@ impl validator::Validate for OneOfGet200Response {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for OneOfGet200Response {
|
||||
fn from(value: i32) -> Self {
|
||||
Self::I32(Box::new(value))
|
||||
}
|
||||
}
|
||||
impl From<Vec<String>> for OneOfGet200Response {
|
||||
fn from(value: Vec<String>) -> Self {
|
||||
Self::VecOfString(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts Query Parameters representation (style=form, explode=false) to a OneOfGet200Response value
|
||||
/// as specified in https://swagger.io/docs/specification/serialization/
|
||||
/// Should be implemented in a serde deserializer
|
||||
@ -2850,6 +2860,17 @@ impl std::str::FromStr for OneOfGet200Response {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for OneOfGet200Response {
|
||||
fn from(value: i32) -> Self {
|
||||
Self::I32(value)
|
||||
}
|
||||
}
|
||||
impl From<Vec<String>> for OneOfGet200Response {
|
||||
fn from(value: Vec<String>) -> Self {
|
||||
Self::VecOfString(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
|
||||
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
|
||||
pub struct OptionalObjectHeader(i32);
|
||||
@ -2971,7 +2992,7 @@ impl std::ops::DerefMut for Result {
|
||||
/// Enumeration of values.
|
||||
/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]`
|
||||
/// which helps with FFI.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
#[repr(C)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
|
||||
|
@ -12,7 +12,7 @@ fn test_oneof_schema_untagged() {
|
||||
let test2 = r#"{"value": ["foo", "bar"]}"#;
|
||||
|
||||
let test3 = Test {
|
||||
value: OneOfGet200Response::I32(123.into()),
|
||||
value: OneOfGet200Response::I32(123),
|
||||
};
|
||||
let test4 = Test {
|
||||
value: OneOfGet200Response::VecOfString(vec!["foo".to_string(), "bar".to_string()].into()),
|
||||
|
@ -349,6 +349,8 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<AdditionalPr
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)]
|
||||
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
|
||||
pub struct Animal {
|
||||
#[serde(default = "Animal::_name_for_class_name")]
|
||||
#[serde(serialize_with = "Animal::_serialize_class_name")]
|
||||
#[serde(rename = "className")]
|
||||
#[validate(custom(function = "check_xss_string"))]
|
||||
pub class_name: String,
|
||||
@ -359,11 +361,24 @@ pub struct Animal {
|
||||
pub color: Option<String>,
|
||||
}
|
||||
|
||||
impl Animal {
|
||||
fn _name_for_class_name() -> String {
|
||||
String::from("Animal")
|
||||
}
|
||||
|
||||
fn _serialize_class_name<S>(_: &String, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
s.serialize_str(&Self::_name_for_class_name())
|
||||
}
|
||||
}
|
||||
|
||||
impl Animal {
|
||||
#[allow(clippy::new_without_default, clippy::too_many_arguments)]
|
||||
pub fn new(class_name: String) -> Animal {
|
||||
pub fn new() -> Animal {
|
||||
Animal {
|
||||
class_name,
|
||||
class_name: Self::_name_for_class_name(),
|
||||
color: Some(r#"red"#.to_string()),
|
||||
}
|
||||
}
|
||||
@ -649,7 +664,7 @@ pub struct ApiResponse {
|
||||
#[serde(rename = "type")]
|
||||
#[validate(custom(function = "check_xss_string"))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub r#type: Option<String>,
|
||||
pub r_type: Option<String>,
|
||||
|
||||
#[serde(rename = "message")]
|
||||
#[validate(custom(function = "check_xss_string"))]
|
||||
@ -662,7 +677,7 @@ impl ApiResponse {
|
||||
pub fn new() -> ApiResponse {
|
||||
ApiResponse {
|
||||
code: None,
|
||||
r#type: None,
|
||||
r_type: None,
|
||||
message: None,
|
||||
}
|
||||
}
|
||||
@ -677,9 +692,9 @@ impl std::fmt::Display for ApiResponse {
|
||||
self.code
|
||||
.as_ref()
|
||||
.map(|code| ["code".to_string(), code.to_string()].join(",")),
|
||||
self.r#type
|
||||
self.r_type
|
||||
.as_ref()
|
||||
.map(|r#type| ["type".to_string(), r#type.to_string()].join(",")),
|
||||
.map(|r_type| ["type".to_string(), r_type.to_string()].join(",")),
|
||||
self.message
|
||||
.as_ref()
|
||||
.map(|message| ["message".to_string(), message.to_string()].join(",")),
|
||||
@ -705,7 +720,7 @@ impl std::str::FromStr for ApiResponse {
|
||||
#[allow(dead_code)]
|
||||
struct IntermediateRep {
|
||||
pub code: Vec<i32>,
|
||||
pub r#type: Vec<String>,
|
||||
pub r_type: Vec<String>,
|
||||
pub message: Vec<String>,
|
||||
}
|
||||
|
||||
@ -733,7 +748,7 @@ impl std::str::FromStr for ApiResponse {
|
||||
<i32 as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
#[allow(clippy::redundant_clone)]
|
||||
"type" => intermediate_rep.r#type.push(
|
||||
"type" => intermediate_rep.r_type.push(
|
||||
<String as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
#[allow(clippy::redundant_clone)]
|
||||
@ -755,7 +770,7 @@ impl std::str::FromStr for ApiResponse {
|
||||
// Use the intermediate representation to return the struct
|
||||
std::result::Result::Ok(ApiResponse {
|
||||
code: intermediate_rep.code.into_iter().next(),
|
||||
r#type: intermediate_rep.r#type.into_iter().next(),
|
||||
r_type: intermediate_rep.r_type.into_iter().next(),
|
||||
message: intermediate_rep.message.into_iter().next(),
|
||||
})
|
||||
}
|
||||
@ -2539,7 +2554,7 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<EnumArrays>
|
||||
/// Enumeration of values.
|
||||
/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]`
|
||||
/// which helps with FFI.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
#[repr(C)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
|
||||
@ -3337,7 +3352,9 @@ impl std::str::FromStr for List {
|
||||
let val = match string_iter.next() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return std::result::Result::Err("Missing value while parsing List".to_string());
|
||||
return std::result::Result::Err(
|
||||
"Missing value while parsing List".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -3976,7 +3993,9 @@ impl std::str::FromStr for Name {
|
||||
let val = match string_iter.next() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return std::result::Result::Err("Missing value while parsing Name".to_string());
|
||||
return std::result::Result::Err(
|
||||
"Missing value while parsing Name".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -4786,7 +4805,7 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<OuterComposi
|
||||
/// Enumeration of values.
|
||||
/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]`
|
||||
/// which helps with FFI.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
#[repr(C)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
|
||||
@ -5283,13 +5302,13 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<ReadOnlyFirs
|
||||
pub struct Return {
|
||||
#[serde(rename = "return")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub r#return: Option<i32>,
|
||||
pub r_return: Option<i32>,
|
||||
}
|
||||
|
||||
impl Return {
|
||||
#[allow(clippy::new_without_default, clippy::too_many_arguments)]
|
||||
pub fn new() -> Return {
|
||||
Return { r#return: None }
|
||||
Return { r_return: None }
|
||||
}
|
||||
}
|
||||
|
||||
@ -5299,9 +5318,9 @@ impl Return {
|
||||
impl std::fmt::Display for Return {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let params: Vec<Option<String>> = vec![
|
||||
self.r#return
|
||||
self.r_return
|
||||
.as_ref()
|
||||
.map(|r#return| ["return".to_string(), r#return.to_string()].join(",")),
|
||||
.map(|r_return| ["return".to_string(), r_return.to_string()].join(",")),
|
||||
];
|
||||
|
||||
write!(
|
||||
@ -5323,7 +5342,7 @@ impl std::str::FromStr for Return {
|
||||
#[derive(Default)]
|
||||
#[allow(dead_code)]
|
||||
struct IntermediateRep {
|
||||
pub r#return: Vec<i32>,
|
||||
pub r_return: Vec<i32>,
|
||||
}
|
||||
|
||||
let mut intermediate_rep = IntermediateRep::default();
|
||||
@ -5346,7 +5365,7 @@ impl std::str::FromStr for Return {
|
||||
#[allow(clippy::match_single_binding)]
|
||||
match key {
|
||||
#[allow(clippy::redundant_clone)]
|
||||
"return" => intermediate_rep.r#return.push(
|
||||
"return" => intermediate_rep.r_return.push(
|
||||
<i32 as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
_ => {
|
||||
@ -5363,7 +5382,7 @@ impl std::str::FromStr for Return {
|
||||
|
||||
// Use the intermediate representation to return the struct
|
||||
std::result::Result::Ok(Return {
|
||||
r#return: intermediate_rep.r#return.into_iter().next(),
|
||||
r_return: intermediate_rep.r_return.into_iter().next(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -5899,7 +5918,7 @@ impl TestEnumParametersRequest {
|
||||
#[allow(clippy::new_without_default, clippy::too_many_arguments)]
|
||||
pub fn new() -> TestEnumParametersRequest {
|
||||
TestEnumParametersRequest {
|
||||
enum_form_string: Some(r#"-efg"#.to_string()),
|
||||
enum_form_string: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6611,7 +6630,9 @@ impl std::str::FromStr for User {
|
||||
let val = match string_iter.next() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return std::result::Result::Err("Missing value while parsing User".to_string());
|
||||
return std::result::Result::Err(
|
||||
"Missing value while parsing User".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -177,7 +177,7 @@ pub struct ApiResponse {
|
||||
#[serde(rename = "type")]
|
||||
#[validate(custom(function = "check_xss_string"))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub r#type: Option<String>,
|
||||
pub r_type: Option<String>,
|
||||
|
||||
#[serde(rename = "message")]
|
||||
#[validate(custom(function = "check_xss_string"))]
|
||||
@ -190,7 +190,7 @@ impl ApiResponse {
|
||||
pub fn new() -> ApiResponse {
|
||||
ApiResponse {
|
||||
code: None,
|
||||
r#type: None,
|
||||
r_type: None,
|
||||
message: None,
|
||||
}
|
||||
}
|
||||
@ -205,9 +205,9 @@ impl std::fmt::Display for ApiResponse {
|
||||
self.code
|
||||
.as_ref()
|
||||
.map(|code| ["code".to_string(), code.to_string()].join(",")),
|
||||
self.r#type
|
||||
self.r_type
|
||||
.as_ref()
|
||||
.map(|r#type| ["type".to_string(), r#type.to_string()].join(",")),
|
||||
.map(|r_type| ["type".to_string(), r_type.to_string()].join(",")),
|
||||
self.message
|
||||
.as_ref()
|
||||
.map(|message| ["message".to_string(), message.to_string()].join(",")),
|
||||
@ -233,7 +233,7 @@ impl std::str::FromStr for ApiResponse {
|
||||
#[allow(dead_code)]
|
||||
struct IntermediateRep {
|
||||
pub code: Vec<i32>,
|
||||
pub r#type: Vec<String>,
|
||||
pub r_type: Vec<String>,
|
||||
pub message: Vec<String>,
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ impl std::str::FromStr for ApiResponse {
|
||||
<i32 as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
#[allow(clippy::redundant_clone)]
|
||||
"type" => intermediate_rep.r#type.push(
|
||||
"type" => intermediate_rep.r_type.push(
|
||||
<String as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?,
|
||||
),
|
||||
#[allow(clippy::redundant_clone)]
|
||||
@ -283,7 +283,7 @@ impl std::str::FromStr for ApiResponse {
|
||||
// Use the intermediate representation to return the struct
|
||||
std::result::Result::Ok(ApiResponse {
|
||||
code: intermediate_rep.code.into_iter().next(),
|
||||
r#type: intermediate_rep.r#type.into_iter().next(),
|
||||
r_type: intermediate_rep.r_type.into_iter().next(),
|
||||
message: intermediate_rep.message.into_iter().next(),
|
||||
})
|
||||
}
|
||||
@ -1491,7 +1491,9 @@ impl std::str::FromStr for User {
|
||||
let val = match string_iter.next() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
return std::result::Result::Err("Missing value while parsing User".to_string());
|
||||
return std::result::Result::Err(
|
||||
"Missing value while parsing User".to_string(),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -91,8 +91,11 @@ impl Goodbye {
|
||||
|
||||
impl Goodbye {
|
||||
#[allow(clippy::new_without_default, clippy::too_many_arguments)]
|
||||
pub fn new(op: String, d: models::GoodbyeD) -> Goodbye {
|
||||
Goodbye { op, d }
|
||||
pub fn new(d: models::GoodbyeD) -> Goodbye {
|
||||
Goodbye {
|
||||
op: Self::_name_for_op(),
|
||||
d,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,7 +397,7 @@ impl Greeting {
|
||||
pub fn new(d: models::GreetingD) -> Greeting {
|
||||
Greeting {
|
||||
d,
|
||||
op: r#"Greeting"#.to_string(),
|
||||
op: Self::_name_for_op(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -698,7 +701,7 @@ impl Hello {
|
||||
#[allow(clippy::new_without_default, clippy::too_many_arguments)]
|
||||
pub fn new(d: models::HelloD) -> Hello {
|
||||
Hello {
|
||||
op: r#"Hello"#.to_string(),
|
||||
op: Self::_name_for_op(),
|
||||
d,
|
||||
}
|
||||
}
|
||||
@ -971,25 +974,36 @@ impl std::convert::TryFrom<HeaderValue> for header::IntoHeaderValue<HelloD> {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
|
||||
#[serde(tag = "op")]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum Message {
|
||||
Hello(Box<models::Hello>),
|
||||
Greeting(Box<models::Greeting>),
|
||||
Goodbye(Box<models::Goodbye>),
|
||||
SomethingCompletelyDifferent(Box<models::SomethingCompletelyDifferent>),
|
||||
Hello(models::Hello),
|
||||
Greeting(models::Greeting),
|
||||
Goodbye(models::Goodbye),
|
||||
SomethingCompletelyDifferent(models::SomethingCompletelyDifferent),
|
||||
}
|
||||
|
||||
impl validator::Validate for Message {
|
||||
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
|
||||
match self {
|
||||
Self::Hello(x) => x.validate(),
|
||||
Self::Greeting(x) => x.validate(),
|
||||
Self::Goodbye(x) => x.validate(),
|
||||
Self::SomethingCompletelyDifferent(x) => x.validate(),
|
||||
Self::Hello(v) => v.validate(),
|
||||
Self::Greeting(v) => v.validate(),
|
||||
Self::Goodbye(v) => v.validate(),
|
||||
Self::SomethingCompletelyDifferent(v) => v.validate(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts Query Parameters representation (style=form, explode=false) to a Message value
|
||||
/// as specified in https://swagger.io/docs/specification/serialization/
|
||||
/// Should be implemented in a serde deserializer
|
||||
impl std::str::FromStr for Message {
|
||||
type Err = serde_json::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
serde_json::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for Message {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@ -1006,64 +1020,42 @@ impl serde::Serialize for Message {
|
||||
|
||||
impl From<models::Hello> for Message {
|
||||
fn from(value: models::Hello) -> Self {
|
||||
Self::Hello(Box::new(value))
|
||||
Self::Hello(value)
|
||||
}
|
||||
}
|
||||
impl From<models::Greeting> for Message {
|
||||
fn from(value: models::Greeting) -> Self {
|
||||
Self::Greeting(Box::new(value))
|
||||
Self::Greeting(value)
|
||||
}
|
||||
}
|
||||
impl From<models::Goodbye> for Message {
|
||||
fn from(value: models::Goodbye) -> Self {
|
||||
Self::Goodbye(Box::new(value))
|
||||
Self::Goodbye(value)
|
||||
}
|
||||
}
|
||||
impl From<models::SomethingCompletelyDifferent> for Message {
|
||||
fn from(value: models::SomethingCompletelyDifferent) -> Self {
|
||||
Self::SomethingCompletelyDifferent(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts Query Parameters representation (style=form, explode=false) to a Message value
|
||||
/// as specified in https://swagger.io/docs/specification/serialization/
|
||||
/// Should be implemented in a serde deserializer
|
||||
impl std::str::FromStr for Message {
|
||||
type Err = serde_json::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
serde_json::from_str(s)
|
||||
Self::SomethingCompletelyDifferent(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_camel_case_types, clippy::large_enum_variant)]
|
||||
pub enum SomethingCompletelyDifferent {
|
||||
VecOfObject(Box<Vec<crate::types::Object>>),
|
||||
Object(Box<crate::types::Object>),
|
||||
VecOfObject(Vec<crate::types::Object>),
|
||||
Object(crate::types::Object),
|
||||
}
|
||||
|
||||
impl validator::Validate for SomethingCompletelyDifferent {
|
||||
fn validate(&self) -> std::result::Result<(), validator::ValidationErrors> {
|
||||
match self {
|
||||
Self::VecOfObject(_) => std::result::Result::Ok(()),
|
||||
Self::Object(x) => x.validate(),
|
||||
Self::Object(_) => std::result::Result::Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<crate::types::Object>> for SomethingCompletelyDifferent {
|
||||
fn from(value: Vec<crate::types::Object>) -> Self {
|
||||
Self::VecOfObject(Box::new(value))
|
||||
}
|
||||
}
|
||||
impl From<crate::types::Object> for SomethingCompletelyDifferent {
|
||||
fn from(value: crate::types::Object) -> Self {
|
||||
Self::Object(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts Query Parameters representation (style=form, explode=false) to a SomethingCompletelyDifferent value
|
||||
/// as specified in https://swagger.io/docs/specification/serialization/
|
||||
/// Should be implemented in a serde deserializer
|
||||
@ -1074,3 +1066,14 @@ impl std::str::FromStr for SomethingCompletelyDifferent {
|
||||
serde_json::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<crate::types::Object>> for SomethingCompletelyDifferent {
|
||||
fn from(value: Vec<crate::types::Object>) -> Self {
|
||||
Self::VecOfObject(value)
|
||||
}
|
||||
}
|
||||
impl From<crate::types::Object> for SomethingCompletelyDifferent {
|
||||
fn from(value: crate::types::Object) -> Self {
|
||||
Self::Object(value)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user