diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java index f456ac9f17a..92d66ddee8f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java @@ -26,6 +26,7 @@ import io.swagger.v3.oas.models.media.FileSchema; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.XML; import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.servers.Server; import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.*; @@ -65,6 +66,11 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { private static final String uuidType = "uuid::Uuid"; private static final String bytesType = "swagger::ByteArray"; + private static final String xmlMimeType = "application/xml"; + private static final String octetMimeType = "application/octet-stream"; + private static final String plainMimeType = "text/plain"; + private static final String jsonMimeType = "application/json"; + public RustServerCodegen() { super(); @@ -485,11 +491,11 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } private boolean isMimetypeXml(String mimetype) { - return mimetype.toLowerCase(Locale.ROOT).startsWith("application/xml"); + return mimetype.toLowerCase(Locale.ROOT).startsWith(xmlMimeType); } private boolean isMimetypePlainText(String mimetype) { - return mimetype.toLowerCase(Locale.ROOT).startsWith("text/plain"); + return mimetype.toLowerCase(Locale.ROOT).startsWith(plainMimeType); } private boolean isMimetypeHtmlText(String mimetype) { @@ -505,7 +511,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } private boolean isMimetypeOctetStream(String mimetype) { - return mimetype.toLowerCase(Locale.ROOT).startsWith("application/octet-stream"); + return mimetype.toLowerCase(Locale.ROOT).startsWith(octetMimeType); } private boolean isMimetypePlain(String mimetype) { @@ -563,36 +569,17 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { processParam(param, op); } - List consumes = new ArrayList(); - - boolean consumesPlainText = false; - boolean consumesXml = false; - // if "consumes" is defined (per operation or using global definition) - if (consumes != null && !consumes.isEmpty()) { - consumes.addAll(getConsumesInfo(this.openAPI, operation)); - List> c = new ArrayList>(); - for (String mimeType : consumes) { - Map mediaType = new HashMap(); - - if (isMimetypeXml(mimeType)) { - additionalProperties.put("usesXml", true); - consumesXml = true; - } else if (isMimetypePlain(mimeType)) { - consumesPlainText = true; - } else if (isMimetypeWwwFormUrlEncoded(mimeType)) { - additionalProperties.put("usesUrlEncodedForm", true); - } - - mediaType.put("mediaType", mimeType); - c.add(mediaType); - } - op.consumes = c; - op.hasConsumes = true; - } - - - List produces = new ArrayList(getProducesInfo(this.openAPI, operation)); + // We keep track of the 'default' model type for this API. If there are + // *any* XML responses, then we set the default to XML, otherwise we + // let the default be JSON. It would be odd for an API to want to use + // both XML and JSON on a single operation, and if we don't know + // anything then JSON is a more modern (ergo reasonable) choice. + boolean defaultsToXml = false; + // Determine the types that this operation produces. `getProducesInfo` + // simply lists all the types, and then we add the correct imports to + // the generated library. + List produces = new ArrayList(getProducesInfo(openAPI, operation)); boolean producesXml = false; boolean producesPlainText = false; if (produces != null && !produces.isEmpty()) { @@ -602,6 +589,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { if (isMimetypeXml(mimeType)) { additionalProperties.put("usesXml", true); + defaultsToXml = true; producesXml = true; } else if (isMimetypePlain(mimeType)) { producesPlainText = true; @@ -621,32 +609,132 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { param.vendorExtensions.put("typeName", toModelName(param.baseName)); } + // Set for deduplication of response IDs + Set responseIds = new HashSet(); + for (CodegenResponse rsp : op.responses) { + + // Get the original API response so we get process the schema + // directly. + ApiResponse original; + if (rsp.code == "0") { + original = operation.getResponses().get("default"); + } else { + original = operation.getResponses().get(rsp.code); + } String[] words = rsp.message.split("[^A-Za-z ]"); + + // Create a unique responseID for this response. String responseId; + if (rsp.vendorExtensions.containsKey("x-responseId")) { + // If it's been specified directly, use that. responseId = (String) rsp.vendorExtensions.get("x-responseId"); } else if (words.length != 0) { + // If there's a description, build it from the description. responseId = camelize(words[0].replace(" ", "_")); } else { + // Otherwise fall back to the http response code. responseId = "Status" + rsp.code; } + + // Deduplicate response IDs that would otherwise contain the same + // text. We rely on the ID being unique, but since we form it from + // the raw description field we can't require that the spec writer + // provides unique descriptions. + int idTieBreaker = 2; + while (responseIds.contains(responseId)) { + String trial = String.format(Locale.ROOT, "%s_%d", responseId, idTieBreaker); + if (!responseIds.contains(trial)) { + responseId = trial; + } else { + idTieBreaker++; + } + } + + responseIds.add(responseId); + rsp.vendorExtensions.put("x-responseId", responseId); rsp.vendorExtensions.put("x-uppercaseResponseId", underscore(responseId).toUpperCase(Locale.ROOT)); rsp.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT)); if (rsp.dataType != null) { rsp.vendorExtensions.put("uppercase_data_type", (rsp.dataType.replace("models::", "")).toUpperCase(Locale.ROOT)); - // Default to producing json if nothing else is specified + // Get the mimetype which is produced by this response. Note + // that although in general responses produces a set of + // different mimetypes currently we only support 1 per + // response. + String firstProduces = null; + + if (original.getContent() != null) { + for (String mimetype : original.getContent().keySet()) { + firstProduces = mimetype; + break; + } + } + + // The output mime type. This allows us to do sensible fallback + // to JSON/XML rather than using only the default operation + // mimetype. + String outputMime; + + if (firstProduces == null) { + if (producesXml) { + outputMime = xmlMimeType; + } else if (producesPlainText) { + if (rsp.dataType.equals(bytesType)) { + outputMime = octetMimeType; + } else { + outputMime = plainMimeType; + } + } else { + outputMime = jsonMimeType; + } + } else { + // If we know exactly what mimetype this response is + // going to produce, then use that. If we have not found + // anything, then we'll fall back to the 'producesXXX' + // definitions we worked out above for the operation as a + // whole. + if (isMimetypeXml(firstProduces)) { + producesXml = true; + producesPlainText = false; + } else if (isMimetypePlain(firstProduces)) { + producesXml = false; + producesPlainText = true; + } else { + producesXml = false; + producesPlainText = false; + } + + outputMime = firstProduces; + } + + rsp.vendorExtensions.put("mimeType", outputMime); + + // Write out the type of data we actually expect this response + // to make. if (producesXml) { rsp.vendorExtensions.put("producesXml", true); - } else if (producesPlainText && rsp.dataType.equals(bytesType)) { - rsp.vendorExtensions.put("producesPlainText", true); + } else if (producesPlainText) { + // Plain text means that there is not structured data in + // this response. So it'll either be a UTF-8 encoded string + // 'plainText' or some generic 'bytes'. + // + // Note that we don't yet distinguish between string/binary + // and string/bytes - that is we don't auto-detect whether + // base64 encoding should be done. They both look like + // 'producesBytes'. + if (rsp.dataType.equals(bytesType)) { + rsp.vendorExtensions.put("producesBytes", true); + } else { + rsp.vendorExtensions.put("producesPlainText", true); + } } else { rsp.vendorExtensions.put("producesJson", true); - // If the data type is just "object", then ensure that the Rust data type - // is "serde_json::Value". This allows us to define APIs that - // can return arbitrary JSON bodies. + // If the data type is just "object", then ensure that the + // Rust data type is "serde_json::Value". This allows us + // to define APIs that can return arbitrary JSON bodies. if (rsp.dataType.equals("object")) { rsp.dataType = "serde_json::Value"; } @@ -686,7 +774,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { Map operations = (Map) objs.get("operations"); List operationList = (List) operations.get("operation"); - for (CodegenOperation op : operationList) { boolean consumesPlainText = false; boolean consumesXml = false; diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache index 9c1bd23e0c9..ab4173052de 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache @@ -491,24 +491,30 @@ impl Api for Client where .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| {{#vendorExtensions}} -{{#producesPlainText}} - Ok(swagger::ByteArray(body.to_vec())) -{{/producesPlainText}}{{^producesPlainText}} - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| -{{#producesXml}} - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::<{{{dataType}}}>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) -{{/producesXml}}{{#producesJson}} - serde_json::from_str::<{{{dataType}}}>(body) - .map_err(|e| e.into()) -{{/producesJson}} - ) -{{/producesPlainText}}{{/vendorExtensions}} - ) + {{#producesBytes}} + Ok(swagger::ByteArray(body.to_vec())) + {{/producesBytes}} + {{^producesBytes}} + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + {{#producesXml}} + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::<{{{dataType}}}>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + {{/producesXml}} + {{#producesJson}} + serde_json::from_str::<{{{dataType}}}>(body) + .map_err(|e| e.into()) + {{/producesJson}} + {{#producesPlainText}} + Ok(body.to_string()) + {{/producesPlainText}} + ) + {{/producesBytes}} +{{/vendorExtensions}} + ) .map(move |body| { {{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body: body, {{/-first}}{{{name}}}: response_{{{name}}}{{^-last}}, {{/-last}}{{#-last}} }{{/-last}}{{/headers}} }) diff --git a/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache b/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache index b8492bebf98..7df7d28f46e 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache @@ -7,7 +7,7 @@ pub mod responses { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}} lazy_static! { /// Create Mime objects for the response content types for {{{operationId}}} - pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}: Mime = "{{{mediaType}}}".parse().unwrap(); + pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}: Mime = "{{{mimeType}}}".parse().unwrap();{{/vendorExtensions}} } {{/dataType}}{{/-first}}{{/produces}}{{/responses}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} } diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache index 1806ac1208b..40579a07a4b 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache @@ -444,18 +444,28 @@ where response.headers_mut().set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone())); {{/dataType}}{{/-first}}{{/produces}} {{#dataType}} -{{#vendorExtensions}}{{#producesXml}}{{^has_namespace}} +{{#vendorExtensions}} + {{#producesXml}} + {{^has_namespace}} let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); -{{/has_namespace}}{{#has_namespace}} + {{/has_namespace}} + {{#has_namespace}} let mut namespaces = BTreeMap::new(); // An empty string is used to indicate a global namespace in xmltree. namespaces.insert("".to_string(), {{{dataType}}}::NAMESPACE.to_string()); let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize"); -{{/has_namespace}}{{/producesXml}}{{#producesJson}} + {{/has_namespace}} + {{/producesXml}} + {{#producesJson}} let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); -{{/producesJson}}{{#producesPlainText}} + {{/producesJson}} + {{#producesBytes}} let body = body.0; -{{/producesPlainText}}{{/vendorExtensions}} + {{/producesBytes}} + {{#producesPlainText}} + let body = body; + {{/producesPlainText}} +{{/vendorExtensions}} response.set_body(body); {{/dataType}} }, diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml index 2e558056871..619a49d1c50 100644 --- a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml @@ -45,6 +45,56 @@ paths: description: 'OK' '400': description: Bad Request + /multiget: + get: + summary: Get some stuff. + responses: + 200: + description: JSON rsp + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + 201: + description: XML rsp + content: + application/xml: + schema: + type: object + properties: + foo: + type: string + 202: + description: octet rsp + content: + application/octet-stream: + schema: + type: string + format: binary + 203: + description: string rsp + content: + text/plain: + schema: + type: string + 204: + description: Duplicate Response long text. One. + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + 205: + description: Duplicate Response long text. Two. + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + 206: + description: Duplicate Response long text. Three. + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" /xml_other: post: requestBody: diff --git a/samples/server/petstore/rust-server/output/openapi-v3/README.md b/samples/server/petstore/rust-server/output/openapi-v3/README.md index d51e1c48832..248f4335fac 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/README.md +++ b/samples/server/petstore/rust-server/output/openapi-v3/README.md @@ -61,6 +61,7 @@ cargo run --example server To run a client, follow one of the following simple steps: ``` +cargo run --example client MultigetGet cargo run --example client MultipleAuthSchemeGet cargo run --example client ReadonlyAuthSchemeGet cargo run --example client RequiredOctetStreamPut @@ -104,6 +105,7 @@ All URIs are relative to *http://localhost* Method | HTTP request | Description ------------- | ------------- | ------------- +[****](docs/default_api.md#) | **GET** /multiget | Get some stuff. [****](docs/default_api.md#) | **GET** /multiple_auth_scheme | [****](docs/default_api.md#) | **GET** /readonly_auth_scheme | [****](docs/default_api.md#) | **PUT** /required_octet_stream | @@ -122,6 +124,7 @@ Method | HTTP request | Description - [AnotherXmlInner](docs/AnotherXmlInner.md) - [AnotherXmlObject](docs/AnotherXmlObject.md) - [DuplicateXmlObject](docs/DuplicateXmlObject.md) + - [InlineResponse201](docs/InlineResponse201.md) - [UuidObject](docs/UuidObject.md) - [XmlArray](docs/XmlArray.md) - [XmlInner](docs/XmlInner.md) diff --git a/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml b/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml index e903c1c2fe5..8181f26db03 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml +++ b/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml @@ -30,6 +30,53 @@ paths: description: OK 400: description: Bad Request + /multiget: + get: + responses: + 200: + content: + application/json: + schema: + $ref: '#/components/schemas/anotherXmlObject' + description: JSON rsp + 201: + content: + application/xml: + schema: + $ref: '#/components/schemas/inline_response_201' + description: XML rsp + 202: + content: + application/octet-stream: + schema: + format: binary + type: string + description: octet rsp + 203: + content: + text/plain: + schema: + type: string + description: string rsp + 204: + content: + application/json: + schema: + $ref: '#/components/schemas/anotherXmlObject' + description: Duplicate Response long text. One. + 205: + content: + application/json: + schema: + $ref: '#/components/schemas/anotherXmlObject' + description: Duplicate Response long text. Two. + 206: + content: + application/json: + schema: + $ref: '#/components/schemas/anotherXmlObject' + description: Duplicate Response long text. Three. + summary: Get some stuff. /xml_other: post: requestBody: @@ -186,6 +233,8 @@ components: name: snake_another_xml_inner anotherXmlObject: description: An XML object + example: + inner_string: inner_string properties: inner_string: type: string @@ -193,6 +242,10 @@ components: xml: name: snake_another_xml_object namespace: http://foo.bar + inline_response_201: + properties: + foo: + type: string securitySchemes: authScheme: flows: diff --git a/samples/server/petstore/rust-server/output/openapi-v3/docs/InlineResponse201.md b/samples/server/petstore/rust-server/output/openapi-v3/docs/InlineResponse201.md new file mode 100644 index 00000000000..142fba46356 --- /dev/null +++ b/samples/server/petstore/rust-server/output/openapi-v3/docs/InlineResponse201.md @@ -0,0 +1,10 @@ +# InlineResponse201 + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**foo** | **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) + + diff --git a/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md b/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md index 82b8c773ff4..1322f643838 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md +++ b/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md @@ -4,6 +4,7 @@ All URIs are relative to *http://localhost* Method | HTTP request | Description ------------- | ------------- | ------------- +****](default_api.md#) | **GET** /multiget | Get some stuff. ****](default_api.md#) | **GET** /multiple_auth_scheme | ****](default_api.md#) | **GET** /readonly_auth_scheme | ****](default_api.md#) | **PUT** /required_octet_stream | @@ -16,6 +17,28 @@ Method | HTTP request | Description ****](default_api.md#) | **PUT** /xml | +# **** +> models::AnotherXmlObject () +Get some stuff. + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::AnotherXmlObject**](anotherXmlObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/octet-stream, application/xml, text/plain, + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **** > (ctx, ) diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/client.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/client.rs index dcbe006993a..a6de3fc9bc2 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/client.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/client.rs @@ -19,6 +19,7 @@ use tokio_core::reactor; #[allow(unused_imports)] use openapi_v3::{ApiNoContext, ContextWrapperExt, ApiError, + MultigetGetResponse, MultipleAuthSchemeGetResponse, ReadonlyAuthSchemeGetResponse, RequiredOctetStreamPutResponse, @@ -37,6 +38,7 @@ fn main() { .arg(Arg::with_name("operation") .help("Sets the operation to run") .possible_values(&[ + "MultigetGet", "MultipleAuthSchemeGet", "ReadonlyAuthSchemeGet", "RequiredOctetStreamPut", @@ -87,6 +89,11 @@ fn main() { match matches.value_of("operation") { + Some("MultigetGet") => { + let result = core.run(client.multiget_get()); + println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has).get().clone()); + }, + Some("MultipleAuthSchemeGet") => { let result = core.run(client.multiple_auth_scheme_get()); println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has).get().clone()); diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/server_lib/server.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/server_lib/server.rs index 56c76018177..9d845aaeed2 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/server_lib/server.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/server_lib/server.rs @@ -11,6 +11,7 @@ use swagger::{Has, XSpanIdString}; use uuid; use openapi_v3::{Api, ApiError, + MultigetGetResponse, MultipleAuthSchemeGetResponse, ReadonlyAuthSchemeGetResponse, RequiredOctetStreamPutResponse, @@ -37,6 +38,13 @@ impl Server { impl Api for Server where C: Has{ + /// Get some stuff. + fn multiget_get(&self, context: &C) -> Box> { + let context = context.clone(); + println!("multiget_get() - X-Span-ID: {:?}", context.get().0.clone()); + Box::new(futures::failed("Generic failure".into())) + } + fn multiple_auth_scheme_get(&self, context: &C) -> Box> { let context = context.clone(); diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs index b67f0353b29..98d7205ada5 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs @@ -37,6 +37,7 @@ use swagger; use swagger::{ApiError, XSpanId, XSpanIdString, Has, AuthData}; use {Api, + MultigetGetResponse, MultipleAuthSchemeGetResponse, ReadonlyAuthSchemeGetResponse, RequiredOctetStreamPutResponse, @@ -252,6 +253,187 @@ impl Api for Client where F: Future + 'static, C: Has + Has>{ + fn multiget_get(&self, context: &C) -> Box> { + let mut uri = format!( + "{}/multiget", + self.base_path + ); + + let mut query_string = self::url::form_urlencoded::Serializer::new("".to_owned()); + + + let query_string_str = query_string.finish(); + if !query_string_str.is_empty() { + uri += "?"; + uri += &query_string_str; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build URI: {}", err))))), + }; + + let mut request = hyper::Request::new(hyper::Method::Get, uri); + + + request.headers_mut().set(XSpanId((context as &Has).get().0.clone())); + Box::new(self.client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 200 => { + let body = response.body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) + .map(move |body| { + MultigetGetResponse::JSONRsp(body) + }) + ) as Box> + }, + 201 => { + let body = response.body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) + .map(move |body| { + MultigetGetResponse::XMLRsp(body) + }) + ) as Box> + }, + 202 => { + let body = response.body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + Ok(swagger::ByteArray(body.to_vec())) + ) + .map(move |body| { + MultigetGetResponse::OctetRsp(body) + }) + ) as Box> + }, + 203 => { + let body = response.body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + Ok(body.to_string()) + ) + ) + .map(move |body| { + MultigetGetResponse::StringRsp(body) + }) + ) as Box> + }, + 204 => { + let body = response.body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) + .map(move |body| { + MultigetGetResponse::DuplicateResponseLongText(body) + }) + ) as Box> + }, + 205 => { + let body = response.body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) + .map(move |body| { + MultigetGetResponse::DuplicateResponseLongText_2(body) + }) + ) as Box> + }, + 206 => { + let body = response.body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) + .map(move |body| { + MultigetGetResponse::DuplicateResponseLongText_3(body) + }) + ) as Box> + }, + code => { + let headers = response.headers().clone(); + Box::new(response.body() + .take(100) + .concat2() + .then(move |body| + future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(ref body) => match str::from_utf8(body) { + Ok(body) => Cow::from(body), + Err(e) => Cow::from(format!("", e)), + }, + Err(e) => Cow::from(format!("", e)), + }))) + ) + ) as Box> + } + } + })) + + } + fn multiple_auth_scheme_get(&self, context: &C) -> Box> { let mut uri = format!( "{}/multiple_auth_scheme", @@ -503,16 +685,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { ResponsesWithHeadersGetResponse::Success{ body: body, success_info: response_success_info } }) @@ -600,16 +779,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { UuidGetResponse::DuplicateResponseLongText(body) }) diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs index 255d779db32..ea2d2b92a1e 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs @@ -51,6 +51,37 @@ pub const BASE_PATH: &'static str = ""; pub const API_VERSION: &'static str = "1.0.7"; +#[derive(Debug, PartialEq)] +pub enum MultigetGetResponse { + /// JSON rsp + JSONRsp + (models::AnotherXmlObject) + , + /// XML rsp + XMLRsp + (models::InlineResponse201) + , + /// octet rsp + OctetRsp + (swagger::ByteArray) + , + /// string rsp + StringRsp + (String) + , + /// Duplicate Response long text. One. + DuplicateResponseLongText + (models::AnotherXmlObject) + , + /// Duplicate Response long text. Two. + DuplicateResponseLongText_2 + (models::AnotherXmlObject) + , + /// Duplicate Response long text. Three. + DuplicateResponseLongText_3 + (models::AnotherXmlObject) +} + #[derive(Debug, PartialEq)] pub enum MultipleAuthSchemeGetResponse { /// Check that limiting to multiple required auth schemes works @@ -142,6 +173,9 @@ pub enum XmlPutResponse { /// API pub trait Api { + /// Get some stuff. + fn multiget_get(&self, context: &C) -> Box>; + fn multiple_auth_scheme_get(&self, context: &C) -> Box>; @@ -177,6 +211,9 @@ pub trait Api { /// API without a `Context` pub trait ApiNoContext { + /// Get some stuff. + fn multiget_get(&self) -> Box>; + fn multiple_auth_scheme_get(&self) -> Box>; @@ -223,6 +260,11 @@ impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { + /// Get some stuff. + fn multiget_get(&self) -> Box> { + self.api().multiget_get(&self.context()) + } + fn multiple_auth_scheme_get(&self) -> Box> { self.api().multiple_auth_scheme_get(&self.context()) diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/mimetypes.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/mimetypes.rs index 3f70e612d01..28f79f4ed2b 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/mimetypes.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/mimetypes.rs @@ -5,6 +5,41 @@ pub mod responses { // The macro is called per-operation to beat the recursion limit + lazy_static! { + /// Create Mime objects for the response content types for MultigetGet + pub static ref MULTIGET_GET_JSON_RSP: Mime = "application/json".parse().unwrap(); + } + + lazy_static! { + /// Create Mime objects for the response content types for MultigetGet + pub static ref MULTIGET_GET_XML_RSP: Mime = "application/xml".parse().unwrap(); + } + + lazy_static! { + /// Create Mime objects for the response content types for MultigetGet + pub static ref MULTIGET_GET_OCTET_RSP: Mime = "application/octet-stream".parse().unwrap(); + } + + lazy_static! { + /// Create Mime objects for the response content types for MultigetGet + pub static ref MULTIGET_GET_STRING_RSP: Mime = "text/plain".parse().unwrap(); + } + + lazy_static! { + /// Create Mime objects for the response content types for MultigetGet + pub static ref MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT: Mime = "application/json".parse().unwrap(); + } + + lazy_static! { + /// Create Mime objects for the response content types for MultigetGet + pub static ref MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_2: Mime = "application/json".parse().unwrap(); + } + + lazy_static! { + /// Create Mime objects for the response content types for MultigetGet + pub static ref MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_3: Mime = "application/json".parse().unwrap(); + } + lazy_static! { /// Create Mime objects for the response content types for ResponsesWithHeadersGet pub static ref RESPONSES_WITH_HEADERS_GET_SUCCESS: Mime = "application/json".parse().unwrap(); diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs index 081175d56fb..b3adc1f3ad1 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs @@ -218,6 +218,32 @@ impl DuplicateXmlObject { } } +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "conversion", derive(LabelledGeneric))] +pub struct InlineResponse201 { + #[serde(rename = "foo")] + #[serde(skip_serializing_if="Option::is_none")] + pub foo: Option, + +} + +impl InlineResponse201 { + pub fn new() -> InlineResponse201 { + InlineResponse201 { + foo: None, + } + } +} + +impl InlineResponse201 { + /// 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") + } +} + /// Test a model containing a UUID #[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)] #[cfg_attr(feature = "conversion", derive(LabelledGeneric))] diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs index 2298f08c707..61a5361fc09 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs @@ -35,6 +35,7 @@ use swagger::{ApiError, XSpanId, XSpanIdString, Has, RequestParser}; use swagger::auth::Scopes; use {Api, + MultigetGetResponse, MultipleAuthSchemeGetResponse, ReadonlyAuthSchemeGetResponse, RequiredOctetStreamPutResponse, @@ -58,6 +59,7 @@ mod paths { lazy_static! { pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/multiget$", r"^/multiple_auth_scheme$", r"^/readonly_auth_scheme$", r"^/required_octet_stream$", @@ -68,14 +70,15 @@ mod paths { r"^/xml_other$" ]).unwrap(); } - pub static ID_MULTIPLE_AUTH_SCHEME: usize = 0; - pub static ID_READONLY_AUTH_SCHEME: usize = 1; - pub static ID_REQUIRED_OCTET_STREAM: usize = 2; - pub static ID_RESPONSES_WITH_HEADERS: usize = 3; - pub static ID_UUID: usize = 4; - pub static ID_XML: usize = 5; - pub static ID_XML_EXTRA: usize = 6; - pub static ID_XML_OTHER: usize = 7; + pub static ID_MULTIGET: usize = 0; + pub static ID_MULTIPLE_AUTH_SCHEME: usize = 1; + pub static ID_READONLY_AUTH_SCHEME: usize = 2; + pub static ID_REQUIRED_OCTET_STREAM: usize = 3; + pub static ID_RESPONSES_WITH_HEADERS: usize = 4; + pub static ID_UUID: usize = 5; + pub static ID_XML: usize = 6; + pub static ID_XML_EXTRA: usize = 7; + pub static ID_XML_OTHER: usize = 8; } pub struct NewService { @@ -141,6 +144,124 @@ where // Please update both places if changing how this code is autogenerated. match &method { + // MultigetGet - GET /multiget + &hyper::Method::Get if path.matched(paths::ID_MULTIGET) => { + Box::new({ + {{ + Box::new(api_impl.multiget_get(&context) + .then(move |result| { + let mut response = Response::new(); + response.headers_mut().set(XSpanId((&context as &Has).get().0.to_string())); + + match result { + Ok(rsp) => match rsp { + MultigetGetResponse::JSONRsp + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + response.headers_mut().set(ContentType(mimetypes::responses::MULTIGET_GET_JSON_RSP.clone())); + + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + response.set_body(body); + }, + MultigetGetResponse::XMLRsp + + (body) + + + => { + response.set_status(StatusCode::try_from(201).unwrap()); + + response.headers_mut().set(ContentType(mimetypes::responses::MULTIGET_GET_XML_RSP.clone())); + + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + response.set_body(body); + }, + MultigetGetResponse::OctetRsp + + (body) + + + => { + response.set_status(StatusCode::try_from(202).unwrap()); + + response.headers_mut().set(ContentType(mimetypes::responses::MULTIGET_GET_OCTET_RSP.clone())); + + let body = body.0; + response.set_body(body); + }, + MultigetGetResponse::StringRsp + + (body) + + + => { + response.set_status(StatusCode::try_from(203).unwrap()); + + response.headers_mut().set(ContentType(mimetypes::responses::MULTIGET_GET_STRING_RSP.clone())); + + let body = body; + response.set_body(body); + }, + MultigetGetResponse::DuplicateResponseLongText + + (body) + + + => { + response.set_status(StatusCode::try_from(204).unwrap()); + + response.headers_mut().set(ContentType(mimetypes::responses::MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT.clone())); + + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + response.set_body(body); + }, + MultigetGetResponse::DuplicateResponseLongText_2 + + (body) + + + => { + response.set_status(StatusCode::try_from(205).unwrap()); + + response.headers_mut().set(ContentType(mimetypes::responses::MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_2.clone())); + + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + response.set_body(body); + }, + MultigetGetResponse::DuplicateResponseLongText_3 + + (body) + + + => { + response.set_status(StatusCode::try_from(206).unwrap()); + + response.headers_mut().set(ContentType(mimetypes::responses::MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_3.clone())); + + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + response.set_body(body); + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + response.set_status(StatusCode::InternalServerError); + response.set_body("An internal error occurred"); + }, + } + + future::ok(response) + } + )) + }} + }) as Box> + }, + // MultipleAuthSchemeGet - GET /multiple_auth_scheme &hyper::Method::Get if path.matched(paths::ID_MULTIPLE_AUTH_SCHEME) => { { @@ -339,9 +460,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::RESPONSES_WITH_HEADERS_GET_SUCCESS.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, ResponsesWithHeadersGetResponse::PreconditionFailed @@ -397,9 +516,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::UUID_GET_DUPLICATE_RESPONSE_LONG_TEXT.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -771,6 +888,9 @@ impl RequestParser for ApiRequestParser { let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); match request.method() { + // MultigetGet - GET /multiget + &hyper::Method::Get if path.matched(paths::ID_MULTIGET) => Ok("MultigetGet"), + // MultipleAuthSchemeGet - GET /multiple_auth_scheme &hyper::Method::Get if path.matched(paths::ID_MULTIPLE_AUTH_SCHEME) => Ok("MultipleAuthSchemeGet"), diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs index d7a48cd205a..045a7903c62 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs @@ -319,16 +319,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { TestSpecialTagsResponse::SuccessfulOperation(body) }) @@ -403,16 +400,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { FakeOuterBooleanSerializeResponse::OutputBoolean(body) }) @@ -486,16 +480,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { FakeOuterCompositeSerializeResponse::OutputComposite(body) }) @@ -569,16 +560,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { FakeOuterNumberSerializeResponse::OutputNumber(body) }) @@ -652,16 +640,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { FakeOuterStringSerializeResponse::OutputString(body) }) @@ -796,16 +781,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { TestClientModelResponse::SuccessfulOperation(body) }) @@ -1210,16 +1192,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { TestClassnameResponse::SuccessfulOperation(body) }) @@ -1452,17 +1431,15 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) .map(move |body| { FindPetsByStatusResponse::SuccessfulOperation(body) }) @@ -1549,17 +1526,15 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) .map(move |body| { FindPetsByTagsResponse::SuccessfulOperation(body) }) @@ -1646,17 +1621,15 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) .map(move |body| { GetPetByIdResponse::SuccessfulOperation(body) }) @@ -1976,16 +1949,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { UploadFileResponse::SuccessfulOperation(body) }) @@ -2133,16 +2103,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::>(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::>(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { GetInventoryResponse::SuccessfulOperation(body) }) @@ -2207,17 +2174,15 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) .map(move |body| { GetOrderByIdResponse::SuccessfulOperation(body) }) @@ -2304,17 +2269,15 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) .map(move |body| { PlaceOrderResponse::SuccessfulOperation(body) }) @@ -2654,17 +2617,15 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) .map(move |body| { GetUserByNameResponse::SuccessfulOperation(body) }) @@ -2759,17 +2720,15 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) + ) + ) .map(move |body| { LoginUserResponse::SuccessfulOperation{ body: body, x_rate_limit: response_x_rate_limit, x_expires_after: response_x_expires_after } }) diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/mimetypes.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/mimetypes.rs index e947e94b363..b32609c12a7 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/mimetypes.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/mimetypes.rs @@ -42,17 +42,17 @@ pub mod responses { lazy_static! { /// Create Mime objects for the response content types for FindPetsByStatus - pub static ref FIND_PETS_BY_STATUS_SUCCESSFUL_OPERATION: Mime = "application/json".parse().unwrap(); + pub static ref FIND_PETS_BY_STATUS_SUCCESSFUL_OPERATION: Mime = "application/xml".parse().unwrap(); } lazy_static! { /// Create Mime objects for the response content types for FindPetsByTags - pub static ref FIND_PETS_BY_TAGS_SUCCESSFUL_OPERATION: Mime = "application/json".parse().unwrap(); + pub static ref FIND_PETS_BY_TAGS_SUCCESSFUL_OPERATION: Mime = "application/xml".parse().unwrap(); } lazy_static! { /// Create Mime objects for the response content types for GetPetById - pub static ref GET_PET_BY_ID_SUCCESSFUL_OPERATION: Mime = "application/json".parse().unwrap(); + pub static ref GET_PET_BY_ID_SUCCESSFUL_OPERATION: Mime = "application/xml".parse().unwrap(); } lazy_static! { @@ -67,22 +67,22 @@ pub mod responses { lazy_static! { /// Create Mime objects for the response content types for GetOrderById - pub static ref GET_ORDER_BY_ID_SUCCESSFUL_OPERATION: Mime = "application/json".parse().unwrap(); + pub static ref GET_ORDER_BY_ID_SUCCESSFUL_OPERATION: Mime = "application/xml".parse().unwrap(); } lazy_static! { /// Create Mime objects for the response content types for PlaceOrder - pub static ref PLACE_ORDER_SUCCESSFUL_OPERATION: Mime = "application/json".parse().unwrap(); + pub static ref PLACE_ORDER_SUCCESSFUL_OPERATION: Mime = "application/xml".parse().unwrap(); } lazy_static! { /// Create Mime objects for the response content types for GetUserByName - pub static ref GET_USER_BY_NAME_SUCCESSFUL_OPERATION: Mime = "application/json".parse().unwrap(); + pub static ref GET_USER_BY_NAME_SUCCESSFUL_OPERATION: Mime = "application/xml".parse().unwrap(); } lazy_static! { /// Create Mime objects for the response content types for LoginUser - pub static ref LOGIN_USER_SUCCESSFUL_OPERATION: Mime = "application/json".parse().unwrap(); + pub static ref LOGIN_USER_SUCCESSFUL_OPERATION: Mime = "application/xml".parse().unwrap(); } } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs index d37730a9a0e..abe6c8a8f3c 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs @@ -258,9 +258,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::TEST_SPECIAL_TAGS_SUCCESSFUL_OPERATION.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -325,9 +323,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::FAKE_OUTER_BOOLEAN_SERIALIZE_OUTPUT_BOOLEAN.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -392,9 +388,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::FAKE_OUTER_COMPOSITE_SERIALIZE_OUTPUT_COMPOSITE.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -459,9 +453,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::FAKE_OUTER_NUMBER_SERIALIZE_OUTPUT_NUMBER.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -526,9 +518,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::FAKE_OUTER_STRING_SERIALIZE_OUTPUT_STRING.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -671,9 +661,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::TEST_CLIENT_MODEL_SUCCESSFUL_OPERATION.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -986,9 +974,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::TEST_CLASSNAME_SUCCESSFUL_OPERATION.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -1232,9 +1218,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::FIND_PETS_BY_STATUS_SUCCESSFUL_OPERATION.clone())); - let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, FindPetsByStatusResponse::InvalidStatusValue @@ -1313,9 +1297,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::FIND_PETS_BY_TAGS_SUCCESSFUL_OPERATION.clone())); - let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, FindPetsByTagsResponse::InvalidTagValue @@ -1386,9 +1368,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::GET_PET_BY_ID_SUCCESSFUL_OPERATION.clone())); - let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, GetPetByIdResponse::InvalidIDSupplied @@ -1711,9 +1691,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::UPLOAD_FILE_SUCCESSFUL_OPERATION.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -1822,9 +1800,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::GET_INVENTORY_SUCCESSFUL_OPERATION.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -1879,9 +1855,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::GET_ORDER_BY_ID_SUCCESSFUL_OPERATION.clone())); - let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, GetOrderByIdResponse::InvalidIDSupplied @@ -1961,9 +1935,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::PLACE_ORDER_SUCCESSFUL_OPERATION.clone())); - let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, PlaceOrderResponse::InvalidOrder @@ -2273,9 +2245,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::GET_USER_BY_NAME_SUCCESSFUL_OPERATION.clone())); - let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, GetUserByNameResponse::InvalidUsernameSupplied @@ -2358,9 +2328,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::LOGIN_USER_SUCCESSFUL_OPERATION.clone())); - let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, LoginUserResponse::InvalidUsername diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs index 64b47aa5f24..c273afb2df3 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs @@ -406,16 +406,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { FileResponseGetResponse::Success(body) }) @@ -484,16 +481,12 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + Ok(body.to_string()) + ) + ) .map(move |body| { HtmlPostResponse::Success(body) }) @@ -558,16 +551,13 @@ impl Api for Client where .concat2() .map_err(|e| ApiError(format!("Failed to read response: {}", e))) .and_then(|body| - - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - - ) + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) .map(move |body| { RawJsonGetResponse::Success(body) }) diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs index eae8b97db41..addb7430403 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs @@ -244,9 +244,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::FILE_RESPONSE_GET_SUCCESS.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, }, @@ -300,9 +298,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::HTML_POST_SUCCESS.clone())); - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - + let body = body; response.set_body(body); }, }, @@ -345,9 +341,7 @@ where response.headers_mut().set(ContentType(mimetypes::responses::RAW_JSON_GET_SUCCESS.clone())); - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - response.set_body(body); }, },