[rust] [rust-server] Add AbstractRustCodegen (#13231)

* Add AbstractRustCodegen

* Fix minor bug

* Fix copy-pasting mistake

* Simplify addApiNamePrefixAndSuffix
This commit is contained in:
Jacob Halsey
2022-08-26 05:11:19 +01:00
committed by GitHub
parent 96521f2234
commit dc7ae051b8
42 changed files with 876 additions and 609 deletions

View File

@@ -59,9 +59,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## RESERVED WORDS
<ul class="column-ul">
<li>Self</li>
<li>abstract</li>
<li>alignof</li>
<li>as</li>
<li>async</li>
<li>await</li>
<li>become</li>
<li>box</li>
<li>break</li>
@@ -69,6 +71,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>continue</li>
<li>crate</li>
<li>do</li>
<li>dyn</li>
<li>else</li>
<li>enum</li>
<li>extern</li>
@@ -86,21 +89,18 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>mod</li>
<li>move</li>
<li>mut</li>
<li>offsetof</li>
<li>override</li>
<li>priv</li>
<li>proc</li>
<li>pub</li>
<li>pure</li>
<li>ref</li>
<li>return</li>
<li>self</li>
<li>sizeof</li>
<li>static</li>
<li>struct</li>
<li>super</li>
<li>trait</li>
<li>true</li>
<li>try</li>
<li>type</li>
<li>typeof</li>
<li>unsafe</li>

View File

@@ -66,8 +66,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## RESERVED WORDS
<ul class="column-ul">
<li>Self</li>
<li>abstract</li>
<li>alignof</li>
<li>as</li>
<li>async</li>
<li>await</li>
@@ -96,16 +96,12 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>mod</li>
<li>move</li>
<li>mut</li>
<li>offsetof</li>
<li>override</li>
<li>priv</li>
<li>proc</li>
<li>pub</li>
<li>pure</li>
<li>ref</li>
<li>return</li>
<li>self</li>
<li>sizeof</li>
<li>static</li>
<li>struct</li>
<li>super</li>

View File

@@ -0,0 +1,234 @@
package org.openapitools.codegen.languages;
import com.google.common.base.Strings;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.function.Function;
import static org.openapitools.codegen.utils.StringUtils.*;
public abstract class AbstractRustCodegen extends DefaultCodegen implements CodegenConfig {
private final Logger LOGGER = LoggerFactory.getLogger(AbstractRustCodegen.class);
protected List<String> charactersToAllow = Collections.singletonList("_");
protected Set<String> keywordsThatDoNotSupportRawIdentifiers = new HashSet<>(
Arrays.asList("super", "self", "Self", "extern", "crate"));
protected String enumSuffix = "";
public AbstractRustCodegen() {
super();
// All 'Strict' and 'Reserved' keywords from https://doc.rust-lang.org/reference/keywords.html
// Note: These are case-sensitive
this.reservedWords = new HashSet<>(
Arrays.asList(
"as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", "fn", "for",
"if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref", "return",
"self", "Self", "static", "struct", "super", "trait", "true", "type", "unsafe", "use", "where",
"while", "async", "await", "dyn", "abstract", "become", "box", "do", "final", "macro",
"override", "priv", "typeof", "unsized", "virtual", "yield", "try"
)
);
}
@Override
public boolean isReservedWord(String word) {
// This is overridden to take account of Rust reserved words being case-sensitive.
return word != null && reservedWords.contains(word);
}
public enum CasingType {CAMEL_CASE, SNAKE_CASE};
/**
* General purpose sanitizing function for Rust identifiers (fields, variables, structs, parameters, etc.).<br>
* Rules for Rust are fairly simple:
* <ul>
* <li>Characters must belong to [A-Za-z0-9_]
* <li>Cannot use reserved words (but can sometimes prefix with "r#")
* <li>Cannot begin with a number
* </ul>
* @param name The input string
* @param casingType Which casing type to apply
* @param escapePrefix Prefix to escape words beginning with numbers or reserved words
* @param type The type of identifier (used for logging)
* @param allowRawIdentifiers Raw identifiers can't always be used, because of filename vs import mismatch.
* @return Sanitized string
*/
public String sanitizeIdentifier(String name, CasingType casingType, String escapePrefix, String type, boolean allowRawIdentifiers) {
String originalName = name;
Function<String, String> casingFunction;
switch (casingType) {
case CAMEL_CASE:
// This probably seems odd, but it is necessary for two reasons
// Compatibility with rust-server, such that MyIDList => my_id_list => MyIdList
// Conversion from SCREAMING_SNAKE_CASE to ScreamingSnakeCase
casingFunction = (input) -> camelize(underscore(input));
break;
case SNAKE_CASE:
casingFunction = StringUtils::underscore;
break;
default:
throw new IllegalArgumentException("Unknown CasingType");
}
// Replace hyphens with underscores
name = name.replaceAll("-", "_");
// Apply special character escapes, e.g. "@type" => "At_type"
// Remove the trailing underscore if necessary
if (!Strings.isNullOrEmpty(name)) {
boolean endedWithUnderscore = name.endsWith("_");
name = escape(name, specialCharReplacements, charactersToAllow, "_");
if (!endedWithUnderscore && name.endsWith("_")) {
name = org.apache.commons.lang3.StringUtils.chop(name);
}
}
// Sanitize any other special characters that weren't replaced
name = sanitizeName(name);
// Keep track of modifications prior to casing
boolean nameWasModified = !originalName.equals(name);
// Convert casing
name = casingFunction.apply(name);
// If word starts with number add a prefix
// Note: this must be done after casing since CamelCase will strip leading underscores
if (name.matches("^\\d.*")) {
nameWasModified = true;
name = casingFunction.apply(escapePrefix + '_' + name);
}
// Escape reserved words - this is case-sensitive so must be done after casing
// There is currently a bug in Rust where this doesn't work for a few reserved words :(
// https://internals.rust-lang.org/t/raw-identifiers-dont-work-for-all-identifiers/9094
if (isReservedWord(name)) {
nameWasModified = true;
if (this.keywordsThatDoNotSupportRawIdentifiers.contains(name) || !allowRawIdentifiers) {
name = casingFunction.apply(escapePrefix + '_' + name);
} else {
name = "r#" + name;
};
}
// If the name had to be modified (not just because of casing), log the change
if (nameWasModified) {
LOGGER.warn("{} cannot be used as a {} name. Renamed to {}", casingFunction.apply(originalName), type, name);
}
return name;
}
@Override
public String toVarName(String name) {
return sanitizeIdentifier(name, CasingType.SNAKE_CASE, "param", "field/variable", true);
}
@Override
public String toParamName(String name) {
return sanitizeIdentifier(name, CasingType.SNAKE_CASE, "param", "parameter", true);
}
@Override
public String toOperationId(String operationId) {
return sanitizeIdentifier(operationId, CasingType.SNAKE_CASE, "call", "method", true);
}
//// Model naming ////
protected String addModelNamePrefixAndSuffix(String name) {
if (!Strings.isNullOrEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!Strings.isNullOrEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
return name;
}
@Override
public String toModelName(String name) {
return sanitizeIdentifier(addModelNamePrefixAndSuffix(name), CasingType.CAMEL_CASE, "model", "model", false);
}
@Override
public String toModelFilename(String name) {
return sanitizeIdentifier(addModelNamePrefixAndSuffix(name), CasingType.SNAKE_CASE, "model", "model file", false);
}
@Override
public String toModelDocFilename(String name) {
return toModelName(name);
}
//// Enum naming ////
@Override
public String toEnumVarName(String name, String datatype) {
// Rust Enum variants should be camel cased
return sanitizeIdentifier(name, CasingType.CAMEL_CASE, "variant", "enum variant", true);
}
@Override
public String toEnumName(CodegenProperty property) {
// Note: Strangely this function is only used for inline enums, schema enums go through the toModelName function
String name = property.name;
if (!Strings.isNullOrEmpty(enumSuffix)) {
name = name + "_" + enumSuffix;
}
return sanitizeIdentifier(name, CasingType.CAMEL_CASE, "enum", "enum", false);
}
@Override
public String toEnumValue(String value, String datatype) {
// This is the representation of the enum that will be serialized / deserialized
// Note: generators currently only support string enums, so checking the type here is pointless
return escapeText(value);
}
@Override
public String toEnumDefaultValue(String value, String datatype) {
// TODO: Bug: currently the templates ignore this function and just use `Self::{{ enumVars.0.name }}`
// Return the Rust type name of the variant so we can `impl Default` with it
return toEnumVarName(value, datatype);
}
//// API naming ////
protected String addApiNamePrefixAndSuffix(String name) {
if (Strings.isNullOrEmpty(name)) {
name = "default";
}
if (!Strings.isNullOrEmpty(apiNamePrefix)) {
name = apiNamePrefix + "_" + name;
}
if (!Strings.isNullOrEmpty(apiNameSuffix)) {
name = name + "_" + apiNameSuffix;
}
return name;
}
@Override
public String toApiName(String name) {
return sanitizeIdentifier(addApiNamePrefixAndSuffix(name), CasingType.CAMEL_CASE, "api", "API", false);
}
@Override
public String toApiFilename(String name) {
return sanitizeIdentifier(addApiNamePrefixAndSuffix(name), CasingType.SNAKE_CASE, "api", "API file", false);
}
@Override
public String toApiDocFilename(String name) {
return toApiName(name);
}
}

View File

@@ -17,10 +17,8 @@
package org.openapitools.codegen.languages;
import com.samskivert.mustache.Mustache.Lambda;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import com.google.common.base.Strings;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
@@ -43,9 +41,8 @@ import java.math.BigDecimal;
import java.util.*;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
public class RustClientCodegen extends AbstractRustCodegen implements CodegenConfig {
private final Logger LOGGER = LoggerFactory.getLogger(RustClientCodegen.class);
private boolean useSingleRequestParameter = false;
private boolean supportAsync = true;
@@ -69,7 +66,6 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String modelDocPath = "docs/";
protected String apiFolder = "src/apis";
protected String modelFolder = "src/models";
protected String enumSuffix = ""; // default to empty string for backward compatibility
protected Map<String, String> unsignedMapping;
public CodegenType getTag() {
@@ -124,22 +120,6 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
embeddedTemplateDir = templateDir = "rust";
setReservedWordsLowerCase(
Arrays.asList(
"abstract", "alignof", "as", "become", "box",
"break", "const", "continue", "crate", "do",
"else", "enum", "extern", "false", "final",
"fn", "for", "if", "impl", "in",
"let", "loop", "macro", "match", "mod",
"move", "mut", "offsetof", "override", "priv",
"proc", "pub", "pure", "ref", "return",
"Self", "self", "sizeof", "static", "struct",
"super", "trait", "true", "type", "typeof",
"unsafe", "unsized", "use", "virtual", "where",
"while", "yield", "async", "await", "dyn", "try"
)
);
defaultIncludes = new HashSet<>(
Arrays.asList(
"map",
@@ -410,100 +390,16 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
this.useSingleRequestParameter = useSingleRequestParameter;
}
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return '_' + name;
}
@Override
public String apiFileFolder() {
return (outputFolder + File.separator + apiFolder).replace("/", File.separator);
}
@Override
public String modelFileFolder() {
return (outputFolder + File.separator + modelFolder).replace("/", File.separator);
}
@Override
public String toVarName(String name) {
// translate @ for properties (like @type) to at_.
// Otherwise an additional "type" property will leed to duplcates
name = name.replaceAll("^@", "at_");
// replace - with _ e.g. created-at => created_at
name = sanitizeName(name.replaceAll("-", "_"));
// if it's all upper case, convert to lower case
if (name.matches("^[A-Z_]*$"))
return name.toLowerCase(Locale.ROOT);
// snake_case, e.g. PetId => pet_id
name = underscore(name);
// for reserved word or word starting with number, append _
if (isReservedWord(name))
name = escapeReservedWord(name);
// for reserved word or word starting with number, append _
if (name.matches("^\\d.*"))
name = "var_" + name;
return name;
}
@Override
public String toParamName(String name) {
return toVarName(name);
}
@Override
public String toModelName(String name) {
// camelize the model name
// phone_number => PhoneNumber
return camelize(toModelFilename(name));
}
@Override
public String toModelFilename(String name) {
if (!Strings.isNullOrEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!Strings.isNullOrEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
name = sanitizeName(name);
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) {
LOGGER.warn("{} (reserved word) cannot be used as model name. Renamed to {}", name, "model_" + name);
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
}
// model name starts with number
if (name.matches("^\\d.*")) {
LOGGER.warn("{} (model name starts with number) cannot be used as model name. Renamed to {}", name,
"model_" + name);
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
}
return underscore(name);
}
@Override
public String toApiFilename(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
// e.g. PetApi.rs => pet_api.rs
return underscore(name) + "_api";
}
@Override
public String apiDocFileFolder() {
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
@@ -514,16 +410,6 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
}
@Override
public String toModelDocFilename(String name) {
return toModelName(name);
}
@Override
public String toApiDocFilename(String name) {
return toApiName(name);
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
@@ -607,19 +493,6 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
return type;
}
@Override
public String toOperationId(String operationId) {
String sanitizedOperationId = sanitizeName(operationId);
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(sanitizedOperationId)) {
LOGGER.warn("{} (reserved word) cannot be used as method name. Renamed to {}", operationId, StringUtils.underscore("call_" + operationId));
sanitizedOperationId = "call_" + sanitizedOperationId;
}
return StringUtils.underscore(sanitizedOperationId);
}
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
OperationMap objectMap = objs.getOperations();
@@ -716,72 +589,6 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String toEnumValue(String value, String datatype) {
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
return value;
} else {
return escapeText(value);
}
}
@Override
public String toEnumDefaultValue(String value, String datatype) {
return datatype + "_" + value;
}
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "Empty";
}
// number
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
String varName = name;
varName = varName.replaceAll("-", "Minus");
varName = varName.replaceAll("\\+", "Plus");
varName = varName.replaceAll("\\.", "Dot");
return varName;
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return getSymbolName(name);
}
// string
String enumName = camelize(sanitizeName(name));
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
if (isReservedWord(enumName) || enumName.matches("\\d.*")) { // reserved word or starts with number
return escapeReservedWord(enumName);
} else {
return enumName;
}
}
@Override
public String toEnumName(CodegenProperty property) {
String name = property.name;
if (!org.apache.commons.lang3.StringUtils.isEmpty(enumSuffix)) {
name = name + "_" + enumSuffix;
}
// camelize the enum name
// phone_number => PhoneNumber
String enumName = camelize(toModelName(name));
// remove [] for array or map of enum
enumName = enumName.replace("[]", "");
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}
@Override
public String toDefaultValue(Schema p) {
if (p.getDefault() != null) {

View File

@@ -55,7 +55,7 @@ import java.util.regex.Pattern;
import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
public class RustServerCodegen extends AbstractRustCodegen implements CodegenConfig {
private final Logger LOGGER = LoggerFactory.getLogger(RustServerCodegen.class);
@@ -150,22 +150,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
*/
embeddedTemplateDir = templateDir = "rust-server";
/*
* Reserved words. Override this with reserved words specific to your language
*/
setReservedWordsLowerCase(
Arrays.asList(
// From https://doc.rust-lang.org/grammar.html#keywords
"abstract", "alignof", "as", "become", "box", "break", "const",
"continue", "crate", "do", "else", "enum", "extern", "false",
"final", "fn", "for", "if", "impl", "in", "let", "loop", "macro",
"match", "mod", "move", "mut", "offsetof", "override", "priv",
"proc", "pub", "pure", "ref", "return", "Self", "self", "sizeof",
"static", "struct", "super", "trait", "true", "type", "typeof",
"unsafe", "unsized", "use", "virtual", "where", "while", "yield"
)
);
defaultIncludes = new HashSet<>(
Arrays.asList(
"map",
@@ -368,21 +352,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
if (name.isEmpty()) {
return "default";
}
return underscore(name);
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return name + "_"; // add an underscore _suffix_ to the name - a prefix implies unused
return sanitizeIdentifier(name, CasingType.SNAKE_CASE, "api", "API", true);
}
/**
@@ -394,148 +364,16 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
}
@Override
public String toModelName(String name) {
// camelize the model name
// phone_number => PhoneNumber
String camelizedName = camelize(toModelFilename(name));
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
final String modelName = "Model" + camelizedName;
LOGGER.warn("{} (reserved word) cannot be used as model name. Renamed to {}", camelizedName, modelName);
return modelName;
}
// model name starts with number
else if (camelizedName.matches("^\\d.*")) {
// e.g. 200Response => Model200Response (after camelize)
camelizedName = "Model" + camelizedName;
LOGGER.warn("{} (model name starts with number) cannot be used as model name. Renamed to {}", name,
camelizedName);
}
return camelizedName;
}
@Override
public String toParamName(String name) {
// should be the same as variable name (stolen from RubyClientCodegen)
return toVarName(name);
}
@Override
public String toVarName(String name) {
// translate @ for properties (like @type) to at_.
// Otherwise an additional "type" property will leed to duplcates
name = name.replaceAll("^@", "at_");
String sanitizedName = super.sanitizeName(name);
// for reserved word, append _
if (isReservedWord(sanitizedName)) {
sanitizedName = escapeReservedWord(sanitizedName);
}
// for word starting with number, prepend "param_"
else if (sanitizedName.matches("^\\d.*")) {
sanitizedName = "param_" + sanitizedName;
}
return underscore(sanitizedName);
}
@Override
public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
LOGGER.warn("{} (reserved word) cannot be used as method name. Renamed to {}", operationId, camelize("call_" + operationId));
operationId = "call_" + operationId;
} else if (operationId.matches("\\d.*")) {
LOGGER.warn("{} cannot be used as method name because it starts with a digit. Renamed to {}", operationId,
camelize("call_" + operationId));
operationId = "call_" + operationId;
}
return camelize(operationId);
}
@Override
public String toModelFilename(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
name = sanitizeName(name);
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(name)) {
LOGGER.warn("{} (reserved word) cannot be used as model name. Renamed to {}", name, camelize("model_" + name));
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
}
return underscore(name);
}
@Override
public String toEnumName(CodegenProperty property) {
return sanitizeName(camelize(property.name)) + "Enum";
}
@Override
public String toEnumVarName(String value, String datatype) {
String var = null;
if (value.isEmpty()) {
var = "EMPTY";
}
// for symbol, e.g. $, #
else if (getSymbolName(value) != null) {
var = getSymbolName(value).toUpperCase(Locale.ROOT);
}
// number
else if ("Integer".equals(datatype) || "Long".equals(datatype) ||
"Float".equals(datatype) || "Double".equals(datatype)) {
String varName = "NUMBER_" + value;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
var = varName;
}
// string
else {
var = value.replaceAll("\\W+", "_").toUpperCase(Locale.ROOT);
if (var.matches("\\d.*")) {
var = "_" + var;
} else {
var = sanitizeName(var);
}
}
return var;
// rust-server uses camel case instead
return sanitizeIdentifier(operationId, CasingType.CAMEL_CASE, "call", "method", true);
}
@Override
public String toEnumValue(String value, String datatype) {
if ("Integer".equals(datatype) || "Long".equals(datatype) ||
"Float".equals(datatype) || "Double".equals(datatype)) {
return value;
} else {
return "\"" + escapeText(value) + "\"";
}
}
@Override
public String toApiFilename(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
// e.g. PetApi.go => pet_api.go
return underscore(name);
// rust-server templates expect value to be in quotes
return "\"" + super.toEnumValue(value, datatype) + "\"";
}
@Override
@@ -548,11 +386,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
}
@Override
public String toModelDocFilename(String name) {
return toModelName(name);
}
@Override
public String toApiDocFilename(String name) {
return toApiName(name) + "_api";

View File

@@ -0,0 +1,171 @@
package org.openapitools.codegen.rust;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.languages.AbstractRustCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.function.Function;
public class AbstractRustCodegenTest {
private final AbstractRustCodegen fakeRustCodegen = new P_AbstractRustCodegen();
@Test
public void testIsReservedWord() {
Assert.assertTrue(fakeRustCodegen.isReservedWord("return"));
Assert.assertTrue(fakeRustCodegen.isReservedWord("self"));
Assert.assertTrue(fakeRustCodegen.isReservedWord("Self"));
Assert.assertFalse(fakeRustCodegen.isReservedWord("Return"));
}
@Test
public void testSanitizeIdentifier() {
// Functions to make this less verbose
Function<String, String> sanitizeSnakeCase = (String name) ->
fakeRustCodegen.sanitizeIdentifier(name, AbstractRustCodegen.CasingType.SNAKE_CASE, "p", "Rust", true);
Function<String, String> sanitizeCamelCase = (String name) ->
fakeRustCodegen.sanitizeIdentifier(name, AbstractRustCodegen.CasingType.CAMEL_CASE, "p", "Rust", true);
// Underscores should be allowed through
Assert.assertEquals(sanitizeSnakeCase.apply("pet_name"), "pet_name");
// Hyphens should be replaced (https://github.com/OpenAPITools/openapi-generator/commit/4cb7f1d6135aa3a42ff38cf89771105c40e7e5a9)
Assert.assertEquals(sanitizeSnakeCase.apply("pet-name"), "pet_name");
// Special character mappings are applied
Assert.assertEquals(sanitizeSnakeCase.apply("@type"), "at_type");
Assert.assertEquals(sanitizeCamelCase.apply("@type"), "AtType");
// Trailing underscore removed when appropriate
Assert.assertEquals(sanitizeSnakeCase.apply("pet@"), "pet_at");
Assert.assertEquals(sanitizeSnakeCase.apply("pet_"), "pet_");
Assert.assertEquals(sanitizeCamelCase.apply("*"), "Star");
// Any other special characters are sanitized
Assert.assertEquals(sanitizeSnakeCase.apply("Halloween\uD83C\uDF83"), "halloween");
// Regular reserved words
Assert.assertEquals(sanitizeSnakeCase.apply("return"), "r#return");
Assert.assertEquals(sanitizeSnakeCase.apply("Return"), "r#return");
Assert.assertEquals(sanitizeCamelCase.apply("return"), "Return");
Assert.assertEquals(sanitizeCamelCase.apply("return"), "Return");
// Special reserved words
Assert.assertEquals(sanitizeCamelCase.apply("self"), "PSelf");
Assert.assertEquals(sanitizeSnakeCase.apply("self"), "p_self");
Assert.assertEquals(sanitizeCamelCase.apply("Self"), "PSelf");
// Must not start with a number
Assert.assertEquals(sanitizeSnakeCase.apply("1_PET"), "p_1_pet");
Assert.assertEquals(sanitizeSnakeCase.apply("123_PET"), "p_123_pet");
Assert.assertEquals(sanitizeCamelCase.apply("_12345AnyOf"), "P12345AnyOf");
// Other numbers are allowed
Assert.assertEquals(sanitizeSnakeCase.apply("PET_2"), "pet_2");
// Check blank strings don't cause exceptions
Assert.assertEquals(sanitizeSnakeCase.apply(""), "");
}
@Test
public void testToVarName() {
// Should be converted to snake case
Assert.assertEquals(fakeRustCodegen.toVarName("PetName"), "pet_name");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toVarName("1PetName"), "param_1_pet_name");
}
@Test
public void testToParamName() {
// Should be converted to snake case
Assert.assertEquals(fakeRustCodegen.toParamName("PetName"), "pet_name");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toParamName("1PetName"), "param_1_pet_name");
}
@Test
public void testToOperationId() {
// Should be converted to camel case
Assert.assertEquals(fakeRustCodegen.toOperationId("createPet"), "create_pet");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toOperationId("1CreatePet"), "call_1_create_pet");
}
@Test
public void testToModelName() {
// Should be converted to camel case
Assert.assertEquals(fakeRustCodegen.toModelName("pet_summary"), "PetSummary");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toModelName("1_pet_summary"), "Model1PetSummary");
}
@Test
public void testToModelFileName() {
// Should be converted to snake case
Assert.assertEquals(fakeRustCodegen.toModelFilename("PetSummary"), "pet_summary");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toModelFilename("1PetSummary"), "model_1_pet_summary");
}
@Test
public void testToEnumVarName() {
// Should be converted to camel case
Assert.assertEquals(fakeRustCodegen.toEnumVarName("pending", null), "Pending");
// Enums are often represented in SCREAMING_SNAKE_CASE, check these are also converted to Rust enum camel case
Assert.assertEquals(fakeRustCodegen.toEnumVarName("SCREAMING_SNAKE_CASE", null), "ScreamingSnakeCase");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toEnumVarName("1_pending", null), "Variant1Pending");
}
@Test
public void testToEnumName() {
Function<String, String> toEnumName = (String name) -> {
CodegenProperty property = new CodegenProperty();
property.name = name;
return fakeRustCodegen.toEnumName(property);
};
// Should be converted to camel case
Assert.assertEquals(toEnumName.apply("pet_status"), "PetStatusWithSuffix");
// Prefix is added when starting with a number
Assert.assertEquals(toEnumName.apply("1_pet_status"), "Enum1PetStatusWithSuffix");
}
@Test
public void testToEnumValue() {
// Value should match spec
Assert.assertEquals(fakeRustCodegen.toEnumValue("12345valueAbc#!", null), "12345valueAbc#!");
// Quotes should be escaped so that the Rust string is valid
Assert.assertEquals(fakeRustCodegen.toEnumValue("\"quote\"", null), "\\\"quote\\\"");
}
@Test
public void testToApiName() {
// Unnamed
Assert.assertEquals(fakeRustCodegen.toApiName(""), "DefaultWithSuffix");
// Should be camel case
Assert.assertEquals(fakeRustCodegen.toApiName("pet"), "PetWithSuffix");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toApiName("1_pet"), "Api1PetWithSuffix");
}
@Test
public void testToApiFilename() {
// Unnamed
Assert.assertEquals(fakeRustCodegen.toApiFilename(""), "default_with_suffix");
// Should be snake case
Assert.assertEquals(fakeRustCodegen.toApiFilename("Pet"), "pet_with_suffix");
// Prefix is added when starting with a number
Assert.assertEquals(fakeRustCodegen.toApiFilename("1Pet"), "api_1_pet_with_suffix");
}
private static class P_AbstractRustCodegen extends AbstractRustCodegen {
P_AbstractRustCodegen() {
this.enumSuffix = "WithSuffix";
this.apiNameSuffix = "WithSuffix";
}
}
}

View File

@@ -847,3 +847,13 @@ components:
uuid:
type: string
format: uuid
Return:
description: Test using keywords
type: object
properties:
match:
type: integer
async:
type: boolean
super:
type: boolean

View File

@@ -11,6 +11,7 @@ docs/Order.md
docs/Pet.md
docs/PetApi.md
docs/PropertyTest.md
docs/Return.md
docs/StoreApi.md
docs/Tag.md
docs/TestingApi.md
@@ -33,6 +34,7 @@ src/models/api_response.rs
src/models/baz.rs
src/models/category.rs
src/models/mod.rs
src/models/model_return.rs
src/models/order.rs
src/models/pet.rs
src/models/property_test.rs

View File

@@ -59,6 +59,7 @@ Class | Method | HTTP request | Description
- [Order](docs/Order.md)
- [Pet](docs/Pet.md)
- [PropertyTest](docs/PropertyTest.md)
- [Return](docs/Return.md)
- [Tag](docs/Tag.md)
- [TypeTesting](docs/TypeTesting.md)
- [User](docs/User.md)

View File

@@ -5,7 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**code** | Option<**i32**> | | [optional]
**_type** | Option<**String**> | | [optional]
**r#type** | Option<**String**> | | [optional]
**message** | Option<**String**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -1,9 +1,12 @@
# SpecialModelName
# Return
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**special_property_name** | **i64** | | [optional] [default to None]
**r#match** | Option<**i32**> | | [optional]
**r#async** | Option<**bool**> | | [optional]
**param_super** | Option<**bool**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -17,7 +17,7 @@ pub struct ApiResponse {
#[serde(rename = "code", skip_serializing_if = "Option::is_none")]
pub code: Option<i32>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub _type: Option<String>,
pub r#type: Option<String>,
#[serde(rename = "message", skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
@@ -27,7 +27,7 @@ impl ApiResponse {
pub fn new() -> ApiResponse {
ApiResponse {
code: None,
_type: None,
r#type: None,
message: None,
}
}

View File

@@ -12,6 +12,8 @@ pub mod pet;
pub use self::pet::Pet;
pub mod property_test;
pub use self::property_test::PropertyTest;
pub mod model_return;
pub use self::model_return::Return;
pub mod tag;
pub use self::tag::Tag;
pub mod type_testing;

View File

@@ -0,0 +1,36 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
/// Return : Test using keywords
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Return {
#[serde(rename = "match", skip_serializing_if = "Option::is_none")]
pub r#match: Option<i32>,
#[serde(rename = "async", skip_serializing_if = "Option::is_none")]
pub r#async: Option<bool>,
#[serde(rename = "super", skip_serializing_if = "Option::is_none")]
pub param_super: Option<bool>,
}
impl Return {
/// Test using keywords
pub fn new() -> Return {
Return {
r#match: None,
r#async: None,
param_super: None,
}
}
}

View File

@@ -11,6 +11,7 @@ docs/Order.md
docs/Pet.md
docs/PetApi.md
docs/PropertyTest.md
docs/Return.md
docs/StoreApi.md
docs/Tag.md
docs/TestingApi.md
@@ -31,6 +32,7 @@ src/models/api_response.rs
src/models/baz.rs
src/models/category.rs
src/models/mod.rs
src/models/model_return.rs
src/models/order.rs
src/models/pet.rs
src/models/property_test.rs

View File

@@ -59,6 +59,7 @@ Class | Method | HTTP request | Description
- [Order](docs/Order.md)
- [Pet](docs/Pet.md)
- [PropertyTest](docs/PropertyTest.md)
- [Return](docs/Return.md)
- [Tag](docs/Tag.md)
- [TypeTesting](docs/TypeTesting.md)
- [User](docs/User.md)

View File

@@ -5,7 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**code** | Option<**i32**> | | [optional]
**_type** | Option<**String**> | | [optional]
**r#type** | Option<**String**> | | [optional]
**message** | Option<**String**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -0,0 +1,13 @@
# Return
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**r#match** | Option<**i32**> | | [optional]
**r#async** | Option<**bool**> | | [optional]
**param_super** | Option<**bool**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -17,7 +17,7 @@ pub struct ApiResponse {
#[serde(rename = "code", skip_serializing_if = "Option::is_none")]
pub code: Option<i32>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub _type: Option<String>,
pub r#type: Option<String>,
#[serde(rename = "message", skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
@@ -27,7 +27,7 @@ impl ApiResponse {
pub fn new() -> ApiResponse {
ApiResponse {
code: None,
_type: None,
r#type: None,
message: None,
}
}

View File

@@ -12,6 +12,8 @@ pub mod pet;
pub use self::pet::Pet;
pub mod property_test;
pub use self::property_test::PropertyTest;
pub mod model_return;
pub use self::model_return::Return;
pub mod tag;
pub use self::tag::Tag;
pub mod type_testing;

View File

@@ -0,0 +1,36 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
/// Return : Test using keywords
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Return {
#[serde(rename = "match", skip_serializing_if = "Option::is_none")]
pub r#match: Option<i32>,
#[serde(rename = "async", skip_serializing_if = "Option::is_none")]
pub r#async: Option<bool>,
#[serde(rename = "super", skip_serializing_if = "Option::is_none")]
pub param_super: Option<bool>,
}
impl Return {
/// Test using keywords
pub fn new() -> Return {
Return {
r#match: None,
r#async: None,
param_super: None,
}
}
}

View File

@@ -11,6 +11,7 @@ docs/Order.md
docs/Pet.md
docs/PetApi.md
docs/PropertyTest.md
docs/Return.md
docs/StoreApi.md
docs/Tag.md
docs/TestingApi.md
@@ -31,6 +32,7 @@ src/models/api_response.rs
src/models/baz.rs
src/models/category.rs
src/models/mod.rs
src/models/model_return.rs
src/models/order.rs
src/models/pet.rs
src/models/property_test.rs

View File

@@ -59,6 +59,7 @@ Class | Method | HTTP request | Description
- [Order](docs/Order.md)
- [Pet](docs/Pet.md)
- [PropertyTest](docs/PropertyTest.md)
- [Return](docs/Return.md)
- [Tag](docs/Tag.md)
- [TypeTesting](docs/TypeTesting.md)
- [User](docs/User.md)

View File

@@ -5,7 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**code** | Option<**i32**> | | [optional]
**_type** | Option<**String**> | | [optional]
**r#type** | Option<**String**> | | [optional]
**message** | Option<**String**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -0,0 +1,13 @@
# Return
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**r#match** | Option<**i32**> | | [optional]
**r#async** | Option<**bool**> | | [optional]
**param_super** | Option<**bool**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -17,7 +17,7 @@ pub struct ApiResponse {
#[serde(rename = "code", skip_serializing_if = "Option::is_none")]
pub code: Option<i32>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub _type: Option<String>,
pub r#type: Option<String>,
#[serde(rename = "message", skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
@@ -27,7 +27,7 @@ impl ApiResponse {
pub fn new() -> ApiResponse {
ApiResponse {
code: None,
_type: None,
r#type: None,
message: None,
}
}

View File

@@ -12,6 +12,8 @@ pub mod pet;
pub use self::pet::Pet;
pub mod property_test;
pub use self::property_test::PropertyTest;
pub mod model_return;
pub use self::model_return::Return;
pub mod tag;
pub use self::tag::Tag;
pub mod type_testing;

View File

@@ -0,0 +1,36 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
/// Return : Test using keywords
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Return {
#[serde(rename = "match", skip_serializing_if = "Option::is_none")]
pub r#match: Option<i32>,
#[serde(rename = "async", skip_serializing_if = "Option::is_none")]
pub r#async: Option<bool>,
#[serde(rename = "super", skip_serializing_if = "Option::is_none")]
pub param_super: Option<bool>,
}
impl Return {
/// Test using keywords
pub fn new() -> Return {
Return {
r#match: None,
r#async: None,
param_super: None,
}
}
}

View File

@@ -11,6 +11,7 @@ docs/Order.md
docs/Pet.md
docs/PetApi.md
docs/PropertyTest.md
docs/Return.md
docs/StoreApi.md
docs/Tag.md
docs/TestingApi.md
@@ -31,6 +32,7 @@ src/models/api_response.rs
src/models/baz.rs
src/models/category.rs
src/models/mod.rs
src/models/model_return.rs
src/models/order.rs
src/models/pet.rs
src/models/property_test.rs

View File

@@ -59,6 +59,7 @@ Class | Method | HTTP request | Description
- [Order](docs/Order.md)
- [Pet](docs/Pet.md)
- [PropertyTest](docs/PropertyTest.md)
- [Return](docs/Return.md)
- [Tag](docs/Tag.md)
- [TypeTesting](docs/TypeTesting.md)
- [User](docs/User.md)

View File

@@ -5,7 +5,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**code** | Option<**i32**> | | [optional]
**_type** | Option<**String**> | | [optional]
**r#type** | Option<**String**> | | [optional]
**message** | Option<**String**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -0,0 +1,13 @@
# Return
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**r#match** | Option<**i32**> | | [optional]
**r#async** | Option<**bool**> | | [optional]
**param_super** | Option<**bool**> | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -17,7 +17,7 @@ pub struct ApiResponse {
#[serde(rename = "code", skip_serializing_if = "Option::is_none")]
pub code: Option<i32>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub _type: Option<String>,
pub r#type: Option<String>,
#[serde(rename = "message", skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
@@ -27,7 +27,7 @@ impl ApiResponse {
pub fn new() -> ApiResponse {
ApiResponse {
code: None,
_type: None,
r#type: None,
message: None,
}
}

View File

@@ -12,6 +12,8 @@ pub mod pet;
pub use self::pet::Pet;
pub mod property_test;
pub use self::property_test::PropertyTest;
pub mod model_return;
pub use self::model_return::Return;
pub mod tag;
pub use self::tag::Tag;
pub mod type_testing;

View File

@@ -0,0 +1,36 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
/// Return : Test using keywords
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Return {
#[serde(rename = "match", skip_serializing_if = "Option::is_none")]
pub r#match: Option<i32>,
#[serde(rename = "async", skip_serializing_if = "Option::is_none")]
pub r#async: Option<bool>,
#[serde(rename = "super", skip_serializing_if = "Option::is_none")]
pub param_super: Option<bool>,
}
impl Return {
/// Test using keywords
pub fn new() -> Return {
Return {
r#match: None,
r#async: None,
param_super: None,
}
}
}

View File

@@ -629,16 +629,16 @@ impl AnyOfObject {
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
pub enum AnyOfObjectAnyOf {
#[serde(rename = "FOO")]
FOO,
Foo,
#[serde(rename = "BAR")]
BAR,
Bar,
}
impl std::fmt::Display for AnyOfObjectAnyOf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
AnyOfObjectAnyOf::FOO => write!(f, "{}", "FOO"),
AnyOfObjectAnyOf::BAR => write!(f, "{}", "BAR"),
AnyOfObjectAnyOf::Foo => write!(f, "{}", "FOO"),
AnyOfObjectAnyOf::Bar => write!(f, "{}", "BAR"),
}
}
}
@@ -648,8 +648,8 @@ impl std::str::FromStr for AnyOfObjectAnyOf {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"FOO" => std::result::Result::Ok(AnyOfObjectAnyOf::FOO),
"BAR" => std::result::Result::Ok(AnyOfObjectAnyOf::BAR),
"FOO" => std::result::Result::Ok(AnyOfObjectAnyOf::Foo),
"BAR" => std::result::Result::Ok(AnyOfObjectAnyOf::Bar),
_ => std::result::Result::Err(format!("Value not valid: {}", s)),
}
}
@@ -949,19 +949,19 @@ impl DuplicateXmlObject {
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
pub enum EnumWithStarObject {
#[serde(rename = "FOO")]
FOO,
Foo,
#[serde(rename = "BAR")]
BAR,
Bar,
#[serde(rename = "*")]
STAR,
Star,
}
impl std::fmt::Display for EnumWithStarObject {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
EnumWithStarObject::FOO => write!(f, "{}", "FOO"),
EnumWithStarObject::BAR => write!(f, "{}", "BAR"),
EnumWithStarObject::STAR => write!(f, "{}", "*"),
EnumWithStarObject::Foo => write!(f, "{}", "FOO"),
EnumWithStarObject::Bar => write!(f, "{}", "BAR"),
EnumWithStarObject::Star => write!(f, "{}", "*"),
}
}
}
@@ -971,9 +971,9 @@ impl std::str::FromStr for EnumWithStarObject {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"FOO" => std::result::Result::Ok(EnumWithStarObject::FOO),
"BAR" => std::result::Result::Ok(EnumWithStarObject::BAR),
"*" => std::result::Result::Ok(EnumWithStarObject::STAR),
"FOO" => std::result::Result::Ok(EnumWithStarObject::Foo),
"BAR" => std::result::Result::Ok(EnumWithStarObject::Bar),
"*" => std::result::Result::Ok(EnumWithStarObject::Star),
_ => std::result::Result::Err(format!("Value not valid: {}", s)),
}
}
@@ -1212,19 +1212,19 @@ impl Model12345AnyOfObject {
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
pub enum Model12345AnyOfObjectAnyOf {
#[serde(rename = "FOO")]
FOO,
Foo,
#[serde(rename = "BAR")]
BAR,
Bar,
#[serde(rename = "*")]
STAR,
Star,
}
impl std::fmt::Display for Model12345AnyOfObjectAnyOf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
Model12345AnyOfObjectAnyOf::FOO => write!(f, "{}", "FOO"),
Model12345AnyOfObjectAnyOf::BAR => write!(f, "{}", "BAR"),
Model12345AnyOfObjectAnyOf::STAR => write!(f, "{}", "*"),
Model12345AnyOfObjectAnyOf::Foo => write!(f, "{}", "FOO"),
Model12345AnyOfObjectAnyOf::Bar => write!(f, "{}", "BAR"),
Model12345AnyOfObjectAnyOf::Star => write!(f, "{}", "*"),
}
}
}
@@ -1234,9 +1234,9 @@ impl std::str::FromStr for Model12345AnyOfObjectAnyOf {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"FOO" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::FOO),
"BAR" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::BAR),
"*" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::STAR),
"FOO" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Foo),
"BAR" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Bar),
"*" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Star),
_ => std::result::Result::Err(format!("Value not valid: {}", s)),
}
}
@@ -2580,16 +2580,16 @@ impl Result {
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
pub enum StringEnum {
#[serde(rename = "FOO")]
FOO,
Foo,
#[serde(rename = "BAR")]
BAR,
Bar,
}
impl std::fmt::Display for StringEnum {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
StringEnum::FOO => write!(f, "{}", "FOO"),
StringEnum::BAR => write!(f, "{}", "BAR"),
StringEnum::Foo => write!(f, "{}", "FOO"),
StringEnum::Bar => write!(f, "{}", "BAR"),
}
}
}
@@ -2599,8 +2599,8 @@ impl std::str::FromStr for StringEnum {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"FOO" => std::result::Result::Ok(StringEnum::FOO),
"BAR" => std::result::Result::Ok(StringEnum::BAR),
"FOO" => std::result::Result::Ok(StringEnum::Foo),
"BAR" => std::result::Result::Ok(StringEnum::Bar),
_ => std::result::Result::Err(format!("Value not valid: {}", s)),
}
}

View File

@@ -18,6 +18,7 @@ docs/ClassModel.md
docs/Client.md
docs/Dog.md
docs/DogAllOf.md
docs/DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket.md
docs/EnumArrays.md
docs/EnumClass.md
docs/EnumTest.md
@@ -27,7 +28,6 @@ docs/List.md
docs/MapTest.md
docs/MixedPropertiesAndAdditionalPropertiesClass.md
docs/Model200Response.md
docs/ModelReturn.md
docs/Name.md
docs/NumberOnly.md
docs/ObjectContainingObjectWithOnlyAdditionalProperties.md
@@ -40,7 +40,7 @@ docs/OuterNumber.md
docs/OuterString.md
docs/Pet.md
docs/ReadOnlyFirst.md
docs/SpecialModelName.md
docs/Return.md
docs/Tag.md
docs/User.md
docs/another_fake_api.md

View File

@@ -173,6 +173,7 @@ Method | HTTP request | Description
- [Client](docs/Client.md)
- [Dog](docs/Dog.md)
- [DogAllOf](docs/DogAllOf.md)
- [DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket](docs/DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket.md)
- [EnumArrays](docs/EnumArrays.md)
- [EnumClass](docs/EnumClass.md)
- [EnumTest](docs/EnumTest.md)
@@ -182,7 +183,6 @@ Method | HTTP request | Description
- [MapTest](docs/MapTest.md)
- [MixedPropertiesAndAdditionalPropertiesClass](docs/MixedPropertiesAndAdditionalPropertiesClass.md)
- [Model200Response](docs/Model200Response.md)
- [ModelReturn](docs/ModelReturn.md)
- [Name](docs/Name.md)
- [NumberOnly](docs/NumberOnly.md)
- [ObjectContainingObjectWithOnlyAdditionalProperties](docs/ObjectContainingObjectWithOnlyAdditionalProperties.md)
@@ -195,7 +195,7 @@ Method | HTTP request | Description
- [OuterString](docs/OuterString.md)
- [Pet](docs/Pet.md)
- [ReadOnlyFirst](docs/ReadOnlyFirst.md)
- [SpecialModelName](docs/SpecialModelName.md)
- [Return](docs/Return.md)
- [Tag](docs/Tag.md)
- [User](docs/User.md)

View File

@@ -4,7 +4,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**code** | **i32** | | [optional] [default to None]
**type_** | **String** | | [optional] [default to None]
**r#type** | **String** | | [optional] [default to None]
**message** | **String** | | [optional] [default to None]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -0,0 +1,10 @@
# DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**dollar_special_left_square_bracket_property_period_name_right_square_bracket** | **i64** | | [optional] [default to None]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -1,9 +1,9 @@
# ModelReturn
# Return
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**return_** | **i32** | | [optional] [default to None]
**r#return** | **i32** | | [optional] [default to None]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@@ -417,7 +417,7 @@ pub struct ApiResponse {
#[serde(rename = "type")]
#[serde(skip_serializing_if="Option::is_none")]
pub type_: Option<String>,
pub r#type: Option<String>,
#[serde(rename = "message")]
#[serde(skip_serializing_if="Option::is_none")]
@@ -429,7 +429,7 @@ impl ApiResponse {
pub fn new() -> ApiResponse {
ApiResponse {
code: None,
type_: None,
r#type: None,
message: None,
}
}
@@ -448,9 +448,9 @@ impl std::string::ToString for ApiResponse {
}
if let Some(ref type_) = self.type_ {
if let Some(ref r#type) = self.r#type {
params.push("type".to_string());
params.push(type_.to_string());
params.push(r#type.to_string());
}
@@ -474,7 +474,7 @@ impl std::str::FromStr for ApiResponse {
// An intermediate representation of the struct to use for parsing.
struct IntermediateRep {
pub code: Vec<i32>,
pub type_: Vec<String>,
pub r#type: Vec<String>,
pub message: Vec<String>,
}
@@ -493,7 +493,7 @@ impl std::str::FromStr for ApiResponse {
if let Some(key) = key_result {
match key {
"code" => intermediate_rep.code.push(<i32 as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
"type" => intermediate_rep.type_.push(<String as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
"type" => intermediate_rep.r#type.push(<String as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
"message" => intermediate_rep.message.push(<String as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
_ => return std::result::Result::Err("Unexpected key while parsing ApiResponse".to_string())
}
@@ -506,7 +506,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(),
type_: intermediate_rep.type_.into_iter().next(),
r#type: intermediate_rep.r#type.into_iter().next(),
message: intermediate_rep.message.into_iter().next(),
})
}
@@ -2092,6 +2092,131 @@ impl DogAllOf {
}
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
#[serde(rename = "$special[model.name]")]
pub struct DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
#[serde(rename = "$special[property.name]")]
#[serde(skip_serializing_if="Option::is_none")]
pub dollar_special_left_square_bracket_property_period_name_right_square_bracket: Option<i64>,
}
impl DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
pub fn new() -> DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
dollar_special_left_square_bracket_property_period_name_right_square_bracket: None,
}
}
}
/// Converts the DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket value to the Query Parameters representation (style=form, explode=false)
/// specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde serializer
impl std::string::ToString for DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
fn to_string(&self) -> String {
let mut params: Vec<String> = vec![];
if let Some(ref dollar_special_left_square_bracket_property_period_name_right_square_bracket) = self.dollar_special_left_square_bracket_property_period_name_right_square_bracket {
params.push("$special[property.name]".to_string());
params.push(dollar_special_left_square_bracket_property_period_name_right_square_bracket.to_string());
}
params.join(",").to_string()
}
}
/// Converts Query Parameters representation (style=form, explode=false) to a DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket value
/// as specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde deserializer
impl std::str::FromStr for DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
type Err = String;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
#[derive(Default)]
// An intermediate representation of the struct to use for parsing.
struct IntermediateRep {
pub dollar_special_left_square_bracket_property_period_name_right_square_bracket: Vec<i64>,
}
let mut intermediate_rep = IntermediateRep::default();
// Parse into intermediate representation
let mut string_iter = s.split(',').into_iter();
let mut key_result = string_iter.next();
while key_result.is_some() {
let val = match string_iter.next() {
Some(x) => x,
None => return std::result::Result::Err("Missing value while parsing DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket".to_string())
};
if let Some(key) = key_result {
match key {
"$special[property.name]" => intermediate_rep.dollar_special_left_square_bracket_property_period_name_right_square_bracket.push(<i64 as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
_ => return std::result::Result::Err("Unexpected key while parsing DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket".to_string())
}
}
// Get the next key
key_result = string_iter.next();
}
// Use the intermediate representation to return the struct
std::result::Result::Ok(DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
dollar_special_left_square_bracket_property_period_name_right_square_bracket: intermediate_rep.dollar_special_left_square_bracket_property_period_name_right_square_bracket.into_iter().next(),
})
}
}
// Methods for converting between header::IntoHeaderValue<DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket> and hyper::header::HeaderValue
#[cfg(any(feature = "client", feature = "server"))]
impl std::convert::TryFrom<header::IntoHeaderValue<DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket>> for hyper::header::HeaderValue {
type Error = String;
fn try_from(hdr_value: header::IntoHeaderValue<DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket>) -> std::result::Result<Self, Self::Error> {
let hdr_value = hdr_value.to_string();
match hyper::header::HeaderValue::from_str(&hdr_value) {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(e) => std::result::Result::Err(
format!("Invalid header value for DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket - value: {} is invalid {}",
hdr_value, e))
}
}
}
#[cfg(any(feature = "client", feature = "server"))]
impl std::convert::TryFrom<hyper::header::HeaderValue> for header::IntoHeaderValue<DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket> {
type Error = String;
fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result<Self, Self::Error> {
match hdr_value.to_str() {
std::result::Result::Ok(value) => {
match <DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket as std::str::FromStr>::from_str(value) {
std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)),
std::result::Result::Err(err) => std::result::Result::Err(
format!("Unable to convert header value '{}' into DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket - {}",
value, err))
}
},
std::result::Result::Err(e) => std::result::Result::Err(
format!("Unable to convert header: {:?} to string: {}",
hdr_value, e))
}
}
}
impl DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket {
/// Helper function to allow us to convert this model to an XML string.
/// Will panic if serialisation fails.
#[allow(dead_code)]
pub(crate) fn to_xml(&self) -> String {
serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
}
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
pub struct EnumArrays {
@@ -2252,19 +2377,19 @@ impl EnumArrays {
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
pub enum EnumClass {
#[serde(rename = "_abc")]
_ABC,
Abc,
#[serde(rename = "-efg")]
_EFG,
Efg,
#[serde(rename = "(xyz)")]
_XYZ_,
LeftParenthesisXyzRightParenthesis,
}
impl std::fmt::Display for EnumClass {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
EnumClass::_ABC => write!(f, "{}", "_abc"),
EnumClass::_EFG => write!(f, "{}", "-efg"),
EnumClass::_XYZ_ => write!(f, "{}", "(xyz)"),
EnumClass::Abc => write!(f, "{}", "_abc"),
EnumClass::Efg => write!(f, "{}", "-efg"),
EnumClass::LeftParenthesisXyzRightParenthesis => write!(f, "{}", "(xyz)"),
}
}
}
@@ -2274,9 +2399,9 @@ impl std::str::FromStr for EnumClass {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"_abc" => std::result::Result::Ok(EnumClass::_ABC),
"-efg" => std::result::Result::Ok(EnumClass::_EFG),
"(xyz)" => std::result::Result::Ok(EnumClass::_XYZ_),
"_abc" => std::result::Result::Ok(EnumClass::Abc),
"-efg" => std::result::Result::Ok(EnumClass::Efg),
"(xyz)" => std::result::Result::Ok(EnumClass::LeftParenthesisXyzRightParenthesis),
_ => std::result::Result::Err(format!("Value not valid: {}", s)),
}
}
@@ -3421,132 +3546,6 @@ impl Model200Response {
}
}
/// Model for testing reserved words
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
#[serde(rename = "Return")]
pub struct ModelReturn {
#[serde(rename = "return")]
#[serde(skip_serializing_if="Option::is_none")]
pub return_: Option<i32>,
}
impl ModelReturn {
pub fn new() -> ModelReturn {
ModelReturn {
return_: None,
}
}
}
/// Converts the ModelReturn value to the Query Parameters representation (style=form, explode=false)
/// specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde serializer
impl std::string::ToString for ModelReturn {
fn to_string(&self) -> String {
let mut params: Vec<String> = vec![];
if let Some(ref return_) = self.return_ {
params.push("return".to_string());
params.push(return_.to_string());
}
params.join(",").to_string()
}
}
/// Converts Query Parameters representation (style=form, explode=false) to a ModelReturn value
/// as specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde deserializer
impl std::str::FromStr for ModelReturn {
type Err = String;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
#[derive(Default)]
// An intermediate representation of the struct to use for parsing.
struct IntermediateRep {
pub return_: Vec<i32>,
}
let mut intermediate_rep = IntermediateRep::default();
// Parse into intermediate representation
let mut string_iter = s.split(',').into_iter();
let mut key_result = string_iter.next();
while key_result.is_some() {
let val = match string_iter.next() {
Some(x) => x,
None => return std::result::Result::Err("Missing value while parsing ModelReturn".to_string())
};
if let Some(key) = key_result {
match key {
"return" => intermediate_rep.return_.push(<i32 as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
_ => return std::result::Result::Err("Unexpected key while parsing ModelReturn".to_string())
}
}
// Get the next key
key_result = string_iter.next();
}
// Use the intermediate representation to return the struct
std::result::Result::Ok(ModelReturn {
return_: intermediate_rep.return_.into_iter().next(),
})
}
}
// Methods for converting between header::IntoHeaderValue<ModelReturn> and hyper::header::HeaderValue
#[cfg(any(feature = "client", feature = "server"))]
impl std::convert::TryFrom<header::IntoHeaderValue<ModelReturn>> for hyper::header::HeaderValue {
type Error = String;
fn try_from(hdr_value: header::IntoHeaderValue<ModelReturn>) -> std::result::Result<Self, Self::Error> {
let hdr_value = hdr_value.to_string();
match hyper::header::HeaderValue::from_str(&hdr_value) {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(e) => std::result::Result::Err(
format!("Invalid header value for ModelReturn - value: {} is invalid {}",
hdr_value, e))
}
}
}
#[cfg(any(feature = "client", feature = "server"))]
impl std::convert::TryFrom<hyper::header::HeaderValue> for header::IntoHeaderValue<ModelReturn> {
type Error = String;
fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result<Self, Self::Error> {
match hdr_value.to_str() {
std::result::Result::Ok(value) => {
match <ModelReturn as std::str::FromStr>::from_str(value) {
std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)),
std::result::Result::Err(err) => std::result::Result::Err(
format!("Unable to convert header value '{}' into ModelReturn - {}",
value, err))
}
},
std::result::Result::Err(e) => std::result::Result::Err(
format!("Unable to convert header: {:?} to string: {}",
hdr_value, e))
}
}
}
impl ModelReturn {
/// Helper function to allow us to convert this model to an XML string.
/// Will panic if serialisation fails.
#[allow(dead_code)]
pub(crate) fn to_xml(&self) -> String {
serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
}
}
/// Model for testing model name same as property name
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
@@ -4408,19 +4407,19 @@ impl OuterComposite {
#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
pub enum OuterEnum {
#[serde(rename = "placed")]
PLACED,
Placed,
#[serde(rename = "approved")]
APPROVED,
Approved,
#[serde(rename = "delivered")]
DELIVERED,
Delivered,
}
impl std::fmt::Display for OuterEnum {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
OuterEnum::PLACED => write!(f, "{}", "placed"),
OuterEnum::APPROVED => write!(f, "{}", "approved"),
OuterEnum::DELIVERED => write!(f, "{}", "delivered"),
OuterEnum::Placed => write!(f, "{}", "placed"),
OuterEnum::Approved => write!(f, "{}", "approved"),
OuterEnum::Delivered => write!(f, "{}", "delivered"),
}
}
}
@@ -4430,9 +4429,9 @@ impl std::str::FromStr for OuterEnum {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"placed" => std::result::Result::Ok(OuterEnum::PLACED),
"approved" => std::result::Result::Ok(OuterEnum::APPROVED),
"delivered" => std::result::Result::Ok(OuterEnum::DELIVERED),
"placed" => std::result::Result::Ok(OuterEnum::Placed),
"approved" => std::result::Result::Ok(OuterEnum::Approved),
"delivered" => std::result::Result::Ok(OuterEnum::Delivered),
_ => std::result::Result::Err(format!("Value not valid: {}", s)),
}
}
@@ -4859,51 +4858,52 @@ impl ReadOnlyFirst {
}
}
/// Model for testing reserved words
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
#[serde(rename = "$special[model.name]")]
pub struct SpecialModelName {
#[serde(rename = "$special[property.name]")]
#[serde(rename = "Return")]
pub struct Return {
#[serde(rename = "return")]
#[serde(skip_serializing_if="Option::is_none")]
pub special_property_name: Option<i64>,
pub r#return: Option<i32>,
}
impl SpecialModelName {
pub fn new() -> SpecialModelName {
SpecialModelName {
special_property_name: None,
impl Return {
pub fn new() -> Return {
Return {
r#return: None,
}
}
}
/// Converts the SpecialModelName value to the Query Parameters representation (style=form, explode=false)
/// Converts the Return value to the Query Parameters representation (style=form, explode=false)
/// specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde serializer
impl std::string::ToString for SpecialModelName {
impl std::string::ToString for Return {
fn to_string(&self) -> String {
let mut params: Vec<String> = vec![];
if let Some(ref special_property_name) = self.special_property_name {
params.push("$special[property.name]".to_string());
params.push(special_property_name.to_string());
if let Some(ref r#return) = self.r#return {
params.push("return".to_string());
params.push(r#return.to_string());
}
params.join(",").to_string()
}
}
/// Converts Query Parameters representation (style=form, explode=false) to a SpecialModelName value
/// Converts Query Parameters representation (style=form, explode=false) to a Return value
/// as specified in https://swagger.io/docs/specification/serialization/
/// Should be implemented in a serde deserializer
impl std::str::FromStr for SpecialModelName {
impl std::str::FromStr for Return {
type Err = String;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
#[derive(Default)]
// An intermediate representation of the struct to use for parsing.
struct IntermediateRep {
pub special_property_name: Vec<i64>,
pub r#return: Vec<i32>,
}
let mut intermediate_rep = IntermediateRep::default();
@@ -4915,13 +4915,13 @@ impl std::str::FromStr for SpecialModelName {
while key_result.is_some() {
let val = match string_iter.next() {
Some(x) => x,
None => return std::result::Result::Err("Missing value while parsing SpecialModelName".to_string())
None => return std::result::Result::Err("Missing value while parsing Return".to_string())
};
if let Some(key) = key_result {
match key {
"$special[property.name]" => intermediate_rep.special_property_name.push(<i64 as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
_ => return std::result::Result::Err("Unexpected key while parsing SpecialModelName".to_string())
"return" => intermediate_rep.r#return.push(<i32 as std::str::FromStr>::from_str(val).map_err(|x| format!("{}", x))?),
_ => return std::result::Result::Err("Unexpected key while parsing Return".to_string())
}
}
@@ -4930,40 +4930,40 @@ impl std::str::FromStr for SpecialModelName {
}
// Use the intermediate representation to return the struct
std::result::Result::Ok(SpecialModelName {
special_property_name: intermediate_rep.special_property_name.into_iter().next(),
std::result::Result::Ok(Return {
r#return: intermediate_rep.r#return.into_iter().next(),
})
}
}
// Methods for converting between header::IntoHeaderValue<SpecialModelName> and hyper::header::HeaderValue
// Methods for converting between header::IntoHeaderValue<Return> and hyper::header::HeaderValue
#[cfg(any(feature = "client", feature = "server"))]
impl std::convert::TryFrom<header::IntoHeaderValue<SpecialModelName>> for hyper::header::HeaderValue {
impl std::convert::TryFrom<header::IntoHeaderValue<Return>> for hyper::header::HeaderValue {
type Error = String;
fn try_from(hdr_value: header::IntoHeaderValue<SpecialModelName>) -> std::result::Result<Self, Self::Error> {
fn try_from(hdr_value: header::IntoHeaderValue<Return>) -> std::result::Result<Self, Self::Error> {
let hdr_value = hdr_value.to_string();
match hyper::header::HeaderValue::from_str(&hdr_value) {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(e) => std::result::Result::Err(
format!("Invalid header value for SpecialModelName - value: {} is invalid {}",
format!("Invalid header value for Return - value: {} is invalid {}",
hdr_value, e))
}
}
}
#[cfg(any(feature = "client", feature = "server"))]
impl std::convert::TryFrom<hyper::header::HeaderValue> for header::IntoHeaderValue<SpecialModelName> {
impl std::convert::TryFrom<hyper::header::HeaderValue> for header::IntoHeaderValue<Return> {
type Error = String;
fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result<Self, Self::Error> {
match hdr_value.to_str() {
std::result::Result::Ok(value) => {
match <SpecialModelName as std::str::FromStr>::from_str(value) {
match <Return as std::str::FromStr>::from_str(value) {
std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)),
std::result::Result::Err(err) => std::result::Result::Err(
format!("Unable to convert header value '{}' into SpecialModelName - {}",
format!("Unable to convert header value '{}' into Return - {}",
value, err))
}
},
@@ -4975,7 +4975,7 @@ impl std::convert::TryFrom<hyper::header::HeaderValue> for header::IntoHeaderVal
}
impl SpecialModelName {
impl Return {
/// Helper function to allow us to convert this model to an XML string.
/// Will panic if serialisation fails.
#[allow(dead_code)]