[Rust Client] several small fixes to code generation errors (#8845)

* fix cyclic types

* fixed up bad enum names

* fixed double crate:: issue

* add required ToString for enum classes

* Adds Debug/Clone derive macro for generated configuration type

* Updates versions of dependencies recorded in generated Cargo.toml

* fix merge

* bin/generate-samples.sh

Co-authored-by: Benjamin Naecker <bnaecker@fastmail.com>
This commit is contained in:
Adam Leventhal 2021-03-14 19:30:22 -07:00 committed by GitHub
parent a8c56fb26a
commit 15c3bf47a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 51 additions and 32 deletions

View File

@ -30,9 +30,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES ## LANGUAGE PRIMITIVES
<ul class="column-ul"> <ul class="column-ul">
<li>File</li>
<li>String</li> <li>String</li>
<li>Vec&lt;u8&gt;</li>
<li>bool</li> <li>bool</li>
<li>char</li> <li>char</li>
<li>f32</li> <li>f32</li>
@ -41,10 +39,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>i32</li> <li>i32</li>
<li>i64</li> <li>i64</li>
<li>i8</li> <li>i8</li>
<li>isize</li>
<li>str</li>
<li>u16</li> <li>u16</li>
<li>u32</li> <li>u32</li>
<li>u64</li> <li>u64</li>
<li>u8</li> <li>u8</li>
<li>usize</li>
</ul> </ul>
## RESERVED WORDS ## RESERVED WORDS

View File

@ -32,7 +32,6 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -134,8 +133,8 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
Arrays.asList( Arrays.asList(
"i8", "i16", "i32", "i64", "i8", "i16", "i32", "i64",
"u8", "u16", "u32", "u64", "u8", "u16", "u32", "u64",
"f32", "f64", "f32", "f64", "isize", "usize",
"char", "bool", "String", "Vec<u8>", "File") "char", "bool", "str", "String")
); );
instantiationTypes.clear(); instantiationTypes.clear();
@ -212,6 +211,7 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
allModels.put(modelName, cm); allModels.put(modelName, cm);
} }
} }
for (Map.Entry<String, Object> entry : objs.entrySet()) { for (Map.Entry<String, Object> entry : objs.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue(); Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models"); List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
@ -224,7 +224,11 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
Map<String, Object> mas = new HashMap<>(); Map<String, Object> mas = new HashMap<>();
mas.put("modelName", camelize(mappedModel.getModelName())); mas.put("modelName", camelize(mappedModel.getModelName()));
mas.put("mappingName", mappedModel.getMappingName()); mas.put("mappingName", mappedModel.getMappingName());
List<CodegenProperty> vars = model.getVars();
// TODO: deleting the variable from the array was
// problematic; I don't know what this is supposed to do
// so I'm just cloning it for the moment
List<CodegenProperty> vars = new ArrayList<>(model.getVars());
vars.removeIf(p -> p.name.equals(cm.discriminator.getPropertyName())); vars.removeIf(p -> p.name.equals(cm.discriminator.getPropertyName()));
mas.put("vars", vars); mas.put("vars", vars);
discriminatorVars.add(mas); discriminatorVars.add(mas);
@ -480,14 +484,10 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public String getSchemaType(Schema p) { public String getSchemaType(Schema p) {
String schemaType = super.getSchemaType(p); String schemaType = super.getSchemaType(p);
String type = null;
if (typeMapping.containsKey(schemaType)) { if (typeMapping.containsKey(schemaType)) {
type = typeMapping.get(schemaType); return typeMapping.get(schemaType);
if (languageSpecificPrimitives.contains(type)) }
return (type); return schemaType;
} else
type = schemaType;
return type;
} }
@Override @Override
@ -637,7 +637,7 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
} }
// string // string
String enumName = sanitizeName(camelize(name)); String enumName = camelize(sanitizeName(name));
enumName = enumName.replaceFirst("^_", ""); enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", ""); enumName = enumName.replaceFirst("_$", "");

View File

@ -8,7 +8,7 @@ edition = "2018"
serde = "^1.0" serde = "^1.0"
serde_derive = "^1.0" serde_derive = "^1.0"
serde_json = "^1.0" serde_json = "^1.0"
url = "1.5" url = "^2.2"
{{#hyper}} {{#hyper}}
hyper = "~0.11" hyper = "~0.11"
serde_yaml = "0.7" serde_yaml = "0.7"

View File

@ -9,30 +9,42 @@
{{#isEnum}} {{#isEnum}}
/// {{{description}}} /// {{{description}}}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum {{classname}} { pub enum {{{classname}}} {
{{#allowableValues}} {{#allowableValues}}
{{#enumVars}} {{#enumVars}}
#[serde(rename = "{{{value}}}")] #[serde(rename = "{{{value}}}")]
{{name}}, {{{name}}},
{{/enumVars}}{{/allowableValues}} {{/enumVars}}{{/allowableValues}}
} }
impl ToString for {{{classname}}} {
fn to_string(&self) -> String {
match self {
{{#allowableValues}}
{{#enumVars}}
Self::{{{name}}} => String::from("{{{value}}}"),
{{/enumVars}}
{{/allowableValues}}
}
}
}
{{/isEnum}} {{/isEnum}}
{{!-- for schemas that have a discriminator --}} {{!-- for schemas that have a discriminator --}}
{{#discriminator}} {{#discriminator}}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "{{{vendorExtensions.x-tag-name}}}")] #[serde(tag = "{{{vendorExtensions.x-tag-name}}}")]
pub enum {{classname}} { pub enum {{{classname}}} {
{{#vendorExtensions}} {{#vendorExtensions}}
{{#x-mapped-models}} {{#x-mapped-models}}
#[serde(rename="{{mappingName}}")] #[serde(rename="{{mappingName}}")]
{{modelName}} { {{{modelName}}} {
{{#vars}} {{#vars}}
{{#description}} {{#description}}
/// {{{description}}} /// {{{description}}}
{{/description}} {{/description}}
#[serde(rename = "{{{baseName}}}"{{^required}}, skip_serializing_if = "Option::is_none"{{/required}})] #[serde(rename = "{{{baseName}}}"{{^required}}, skip_serializing_if = "Option::is_none"{{/required}})]
{{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}}, {{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{#isModel}}Box<{{{dataType}}}>{{/isModel}}{{^isModel}}{{{dataType}}}{{/isModel}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}},
{{/vars}} {{/vars}}
}, },
{{/x-mapped-models}} {{/x-mapped-models}}
@ -51,7 +63,7 @@ pub struct {{{classname}}} {
/// {{{description}}} /// {{{description}}}
{{/description}} {{/description}}
#[serde(rename = "{{{baseName}}}"{{^required}}, skip_serializing_if = "Option::is_none"{{/required}})] #[serde(rename = "{{{baseName}}}"{{^required}}, skip_serializing_if = "Option::is_none"{{/required}})]
pub {{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}}, pub {{{name}}}: {{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{^required}}Option<{{/required}}{{#isEnum}}{{#isArray}}{{#uniqueItems}}std::collections::HashSet<{{/uniqueItems}}{{^uniqueItems}}Vec<{{/uniqueItems}}{{/isArray}}{{{enumName}}}{{#isArray}}>{{/isArray}}{{/isEnum}}{{^isEnum}}{{#isModel}}Box<{{{dataType}}}>{{/isModel}}{{^isModel}}{{{dataType}}}{{/isModel}}{{/isEnum}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^required}}>{{/required}},
{{/vars}} {{/vars}}
} }
@ -62,7 +74,7 @@ impl {{{classname}}} {
pub fn new({{#requiredVars}}{{{name}}}: {{#isNullable}}Option<{{/isNullable}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}>{{/isNullable}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} { pub fn new({{#requiredVars}}{{{name}}}: {{#isNullable}}Option<{{/isNullable}}{{#isEnum}}{{{enumName}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}>{{/isNullable}}{{^-last}}, {{/-last}}{{/requiredVars}}) -> {{{classname}}} {
{{{classname}}} { {{{classname}}} {
{{#vars}} {{#vars}}
{{{name}}}{{^required}}{{#isArray}}: None{{/isArray}}{{#isMap}}: None{{/isMap}}{{^isContainer}}: None{{/isContainer}}{{/required}}, {{{name}}}{{^required}}{{#isArray}}: None{{/isArray}}{{#isMap}}: None{{/isMap}}{{^isContainer}}: None{{/isContainer}}{{/required}}{{#required}}{{#isModel}}: Box::new({{{name}}}){{/isModel}}{{/required}},
{{/vars}} {{/vars}}
} }
} }
@ -75,11 +87,11 @@ impl {{{classname}}} {
{{#isEnum}} {{#isEnum}}
/// {{{description}}} /// {{{description}}}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum {{enumName}} { pub enum {{{enumName}}} {
{{#allowableValues}} {{#allowableValues}}
{{#enumVars}} {{#enumVars}}
#[serde(rename = "{{{value}}}")] #[serde(rename = "{{{value}}}")]
{{name}}, {{{name}}},
{{/enumVars}} {{/enumVars}}
{{/allowableValues}} {{/allowableValues}}
} }

View File

@ -17,7 +17,7 @@ pub struct {{{operationIdCamelCase}}}Params {
{{#description}} {{#description}}
/// {{{.}}} /// {{{.}}}
{{/description}} {{/description}}
pub {{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}},{{/-last}} pub {{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}String{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}{{#isBodyParam}}crate::models::{{/isBodyParam}}{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}},{{/-last}}
{{#-last}} {{#-last}}
} }
@ -88,7 +88,7 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration:
{{/vendorExtensions.x-group-parameters}} {{/vendorExtensions.x-group-parameters}}
{{^vendorExtensions.x-group-parameters}} {{^vendorExtensions.x-group-parameters}}
pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: &configuration::Configuration, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error<{{{operationIdCamelCase}}}Error>> { pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}(configuration: &configuration::Configuration, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isString}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}{{#isBodyParam}}crate::models::{{/isBodyParam}}{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) -> Result<{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}{{/supportMultipleResponses}}, Error<{{{operationIdCamelCase}}}Error>> {
{{/vendorExtensions.x-group-parameters}} {{/vendorExtensions.x-group-parameters}}
let local_var_client = &configuration.client; let local_var_client = &configuration.client;

View File

@ -2,6 +2,7 @@
use reqwest; use reqwest;
#[derive(Debug, Clone)]
pub struct Configuration { pub struct Configuration {
pub base_path: String, pub base_path: String,
pub user_agent: Option<String>, pub user_agent: Option<String>,
@ -15,6 +16,7 @@ pub struct Configuration {
pub type BasicAuth = (String, Option<String>); pub type BasicAuth = (String, Option<String>);
#[derive(Debug, Clone)]
pub struct ApiKey { pub struct ApiKey {
pub prefix: Option<String>, pub prefix: Option<String>,
pub key: String, pub key: String,

View File

@ -8,7 +8,7 @@ edition = "2018"
serde = "^1.0" serde = "^1.0"
serde_derive = "^1.0" serde_derive = "^1.0"
serde_json = "^1.0" serde_json = "^1.0"
url = "1.5" url = "^2.2"
hyper = "~0.11" hyper = "~0.11"
serde_yaml = "0.7" serde_yaml = "0.7"
base64 = "~0.7.0" base64 = "~0.7.0"

View File

@ -17,7 +17,7 @@ pub struct Pet {
#[serde(rename = "id", skip_serializing_if = "Option::is_none")] #[serde(rename = "id", skip_serializing_if = "Option::is_none")]
pub id: Option<i64>, pub id: Option<i64>,
#[serde(rename = "category", skip_serializing_if = "Option::is_none")] #[serde(rename = "category", skip_serializing_if = "Option::is_none")]
pub category: Option<crate::models::Category>, pub category: Option<Box<crate::models::Category>>,
#[serde(rename = "name")] #[serde(rename = "name")]
pub name: String, pub name: String,
#[serde(rename = "photoUrls")] #[serde(rename = "photoUrls")]

View File

@ -8,7 +8,7 @@ edition = "2018"
serde = "^1.0" serde = "^1.0"
serde_derive = "^1.0" serde_derive = "^1.0"
serde_json = "^1.0" serde_json = "^1.0"
url = "1.5" url = "^2.2"
[dependencies.reqwest] [dependencies.reqwest]
version = "^0.11" version = "^0.11"
default-features = false default-features = false

View File

@ -11,6 +11,7 @@
use reqwest; use reqwest;
#[derive(Debug, Clone)]
pub struct Configuration { pub struct Configuration {
pub base_path: String, pub base_path: String,
pub user_agent: Option<String>, pub user_agent: Option<String>,
@ -24,6 +25,7 @@ pub struct Configuration {
pub type BasicAuth = (String, Option<String>); pub type BasicAuth = (String, Option<String>);
#[derive(Debug, Clone)]
pub struct ApiKey { pub struct ApiKey {
pub prefix: Option<String>, pub prefix: Option<String>,
pub key: String, pub key: String,

View File

@ -17,7 +17,7 @@ pub struct Pet {
#[serde(rename = "id", skip_serializing_if = "Option::is_none")] #[serde(rename = "id", skip_serializing_if = "Option::is_none")]
pub id: Option<i64>, pub id: Option<i64>,
#[serde(rename = "category", skip_serializing_if = "Option::is_none")] #[serde(rename = "category", skip_serializing_if = "Option::is_none")]
pub category: Option<crate::models::Category>, pub category: Option<Box<crate::models::Category>>,
#[serde(rename = "name")] #[serde(rename = "name")]
pub name: String, pub name: String,
#[serde(rename = "photoUrls")] #[serde(rename = "photoUrls")]

View File

@ -8,7 +8,7 @@ edition = "2018"
serde = "^1.0" serde = "^1.0"
serde_derive = "^1.0" serde_derive = "^1.0"
serde_json = "^1.0" serde_json = "^1.0"
url = "1.5" url = "^2.2"
reqwest = "~0.9" reqwest = "~0.9"
[dev-dependencies] [dev-dependencies]

View File

@ -11,6 +11,7 @@
use reqwest; use reqwest;
#[derive(Debug, Clone)]
pub struct Configuration { pub struct Configuration {
pub base_path: String, pub base_path: String,
pub user_agent: Option<String>, pub user_agent: Option<String>,
@ -24,6 +25,7 @@ pub struct Configuration {
pub type BasicAuth = (String, Option<String>); pub type BasicAuth = (String, Option<String>);
#[derive(Debug, Clone)]
pub struct ApiKey { pub struct ApiKey {
pub prefix: Option<String>, pub prefix: Option<String>,
pub key: String, pub key: String,

View File

@ -17,7 +17,7 @@ pub struct Pet {
#[serde(rename = "id", skip_serializing_if = "Option::is_none")] #[serde(rename = "id", skip_serializing_if = "Option::is_none")]
pub id: Option<i64>, pub id: Option<i64>,
#[serde(rename = "category", skip_serializing_if = "Option::is_none")] #[serde(rename = "category", skip_serializing_if = "Option::is_none")]
pub category: Option<crate::models::Category>, pub category: Option<Box<crate::models::Category>>,
#[serde(rename = "name")] #[serde(rename = "name")]
pub name: String, pub name: String,
#[serde(rename = "photoUrls")] #[serde(rename = "photoUrls")]