diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RustServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RustServerCodegen.java old mode 100755 new mode 100644 index e345def9add..af22591445f --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RustServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RustServerCodegen.java @@ -34,6 +34,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { protected String packageName; protected String packageVersion; protected String externCrateName; + protected Map> pathSetMap = new HashMap>(); public RustServerCodegen() { super(); @@ -155,8 +156,9 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); supportingFiles.add(new SupportingFile("lib.mustache", "src", "lib.rs")); supportingFiles.add(new SupportingFile("models.mustache", "src", "models.rs")); - supportingFiles.add(new SupportingFile("server.mustache", "src", "server.rs")); - supportingFiles.add(new SupportingFile("client.mustache", "src", "client.rs")); + supportingFiles.add(new SupportingFile("server-mod.mustache", "src/server", "mod.rs")); + supportingFiles.add(new SupportingFile("server-auth.mustache", "src/server", "auth.rs")); + supportingFiles.add(new SupportingFile("client-mod.mustache", "src/client", "mod.rs")); supportingFiles.add(new SupportingFile("mimetypes.mustache", "src", "mimetypes.rs")); supportingFiles.add(new SupportingFile("example-server.mustache", "examples", "server.rs")); supportingFiles.add(new SupportingFile("example-client.mustache", "examples", "client.rs")); @@ -448,75 +450,58 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { return mimetype.toLowerCase().startsWith("text/plain"); } + boolean isMimetypeWwwFormUrlEncoded(String mimetype) { + return mimetype.toLowerCase().startsWith("application/x-www-form-urlencoded"); + } + @Override public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions, Swagger swagger) { CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger); + + // The Rust code will need to contain a series of regular expressions. + // For performance, we'll construct these at start-of-day and re-use + // them. That means we need labels for them. + // + // Construct a Rust constant (uppercase) token name, and ensure it's + // unique using a numeric tie-breaker if required. + String basePathId = sanitizeName(op.path.replace("/", "_").replace("{", "").replace("}", "").replaceAll("^_", "")).toUpperCase(); + String pathId = basePathId; + int pathIdTiebreaker = 2; + boolean found = false; + while (pathSetMap.containsKey(pathId)) { + Map pathSetEntry = pathSetMap.get(pathId); + if (pathSetEntry.get("path").equals(op.path)) { + found = true; + break; + } + pathId = basePathId + pathIdTiebreaker; + pathIdTiebreaker++; + } + + // Save off the regular expression and path details in the + // "pathSetMap", which we'll add to the source document that will be + // processed by the templates. + if (!found) { + Map pathSetEntry = new HashMap(); + pathSetEntry.put("path", op.path); + pathSetEntry.put("PATH_ID", pathId); + if (!op.pathParams.isEmpty()) { + pathSetEntry.put("hasPathParams", "true"); + } + // Don't prefix with '^' so that the templates can put the + // basePath on the front. + pathSetEntry.put("pathRegEx", op.path.replace("{", "(?P<").replace("}", ">[^/?#]*)") + "$"); + pathSetMap.put(pathId, pathSetEntry); + } + op.vendorExtensions.put("operation_id", underscore(op.operationId)); op.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase()); op.vendorExtensions.put("path", op.path.replace("{", ":").replace("}", "")); + op.vendorExtensions.put("PATH_ID", pathId); + op.vendorExtensions.put("hasPathParams", !op.pathParams.isEmpty()); op.vendorExtensions.put("HttpMethod", Character.toUpperCase(op.httpMethod.charAt(0)) + op.httpMethod.substring(1).toLowerCase()); - op.vendorExtensions.put("httpmethod", op.httpMethod.toLowerCase()); for (CodegenParameter param : op.allParams) { - String example = null; - - if (param.isString) { - if (param.dataFormat != null && param.dataFormat.equals("byte")) { - param.vendorExtensions.put("formatString", "\\\"{:?}\\\""); - example = "swagger::ByteArray(\"" + ((param.example != null) ? param.example : "") + "\".to_string().into_bytes())"; - } else { - param.vendorExtensions.put("formatString", "\\\"{}\\\""); - example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()"; - } - } else if (param.isPrimitiveType) { - if ((param.isByteArray) || - (param.isBinary)) { - // Binary primitive types don't implement `Display`. - param.vendorExtensions.put("formatString", "{:?}"); - example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))"; - } else { - param.vendorExtensions.put("formatString", "{}"); - example = (param.example != null) ? param.example : ""; - } - } else if (param.isListContainer) { - param.vendorExtensions.put("formatString", "{:?}"); - example = (param.example != null) ? param.example : "&Vec::new()"; - } else if (param.isFile) { - param.vendorExtensions.put("formatString", "{:?}"); - op.vendorExtensions.put("hasFile", true); - additionalProperties.put("apiHasFile", true); - example = "Box::new(stream::once(Ok(b\"hello\".to_vec()))) as Box + Send>"; - } else { - param.vendorExtensions.put("formatString", "{:?}"); - if (param.example != null) { - example = "serde_json::from_str::<" + param.dataType + ">(\"" + param.example + "\").expect(\"Failed to parse JSON example\")"; - } - } - - if (param.required) { - if (example != null) { - param.vendorExtensions.put("example", example); - } else if (param.isListContainer) { - // Use the empty list if we don't have an example - param.vendorExtensions.put("example", "&Vec::new()"); - } - else { - // If we don't have an example that we can provide, we need to disable the client example, as it won't build. - param.vendorExtensions.put("example", "???"); - op.vendorExtensions.put("noClientExample", Boolean.TRUE); - } - } else if ((param.dataFormat != null)&&((param.dataFormat.equals("date-time")) || (param.dataFormat.equals("date")))) { - param.vendorExtensions.put("formatString", "{:?}"); - param.vendorExtensions.put("example", "None"); - } else { - // Not required, so override the format string and example - param.vendorExtensions.put("formatString", "{:?}"); - if (param.isFile) { - // Optional file types are wrapped in a future - param.vendorExtensions.put("example", (example != null) ? "Box::new(future::ok(Some(" + example + "))) as Box + Send>" : "None"); - } else { - param.vendorExtensions.put("example", (example != null) ? "Some(" + example + ")" : "None"); - } - } + processParam(param, op); } List consumes = new ArrayList(); @@ -544,6 +529,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { consumesXml = true; } else if (isMimetypePlainText(mimeType)) { consumesPlainText = true; + } else if (isMimetypeWwwFormUrlEncoded(mimeType)) { + additionalProperties.put("usesUrlEncodedForm", true); } mediaType.put("mediaType", mimeType); @@ -587,7 +574,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } if (op.bodyParam != null) { - if (paramHasXmlNamespace(op.bodyParam, definitions)){ op.bodyParam.vendorExtensions.put("has_namespace", "true"); } @@ -607,6 +593,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } for (CodegenParameter param : op.bodyParams) { + processParam(param, op); if (paramHasXmlNamespace(param, definitions)){ param.vendorExtensions.put("has_namespace", "true"); @@ -624,9 +611,18 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } } for (CodegenParameter param : op.headerParams) { + // If a header uses UUIDs, we need to import the UUID package. + if (param.dataType.equals("uuid::Uuid")) { + additionalProperties.put("apiUsesUuid", true); + } + processParam(param, op); + // Give header params a name in camel case. CodegenParameters don't have a nameInCamelCase property. param.vendorExtensions.put("typeName", toModelName(param.baseName)); } + for (CodegenParameter param : op.formParams) { + processParam(param, op); + } for (CodegenResponse rsp : op.responses) { String[] words = rsp.message.split("[^A-Za-z ]"); String responseId; @@ -673,10 +669,16 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } } for (CodegenProperty header : rsp.headers) { + if (header.datatype.equals("uuid::Uuid")) { + additionalProperties.put("apiUsesUuid", true); + } header.nameInCamelCase = toModelName(header.baseName); } } for (CodegenProperty header : op.responseHeaders) { + if (header.datatype.equals("uuid::Uuid")) { + additionalProperties.put("apiUsesUuid", true); + } header.nameInCamelCase = toModelName(header.baseName); } @@ -860,6 +862,27 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { LOGGER.error(e.getMessage(), e); } } + + // We previously built a mapping from path to path ID and regular + // expression - see fromOperation for details. Sort it and add an + // index, and then add it to the objects that we're about to pass to + // the templates to process. + List>> pathSetEntryList = new ArrayList(pathSetMap.entrySet()); + Collections.sort(pathSetEntryList, new Comparator>>() { + public int compare(Map.Entry> a, Map.Entry> b) { + return a.getValue().get("path").compareTo(b.getValue().get("path")); + } + }); + List pathSet = new ArrayList>(); + int index = 0; + for (Map.Entry> pathSetEntry : pathSetEntryList) { + Map pathSetEntryValue = pathSetEntry.getValue(); + pathSetEntryValue.put("index", Integer.toString(index)); + index++; + pathSet.add(pathSetEntryValue); + } + objs.put("pathSet", pathSet); + return super.postProcessSupportingFileData(objs); } @@ -1029,4 +1052,67 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } return false; } + + private void processParam(CodegenParameter param, CodegenOperation op) { + String example = null; + + if (param.isString) { + if (param.dataFormat != null && param.dataFormat.equals("byte")) { + param.vendorExtensions.put("formatString", "\\\"{:?}\\\""); + example = "swagger::ByteArray(\"" + ((param.example != null) ? param.example : "") + "\".to_string().into_bytes())"; + } else { + param.vendorExtensions.put("formatString", "\\\"{}\\\""); + example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()"; + } + } else if (param.isPrimitiveType) { + if ((param.isByteArray) || + (param.isBinary)) { + // Binary primitive types don't implement `Display`. + param.vendorExtensions.put("formatString", "{:?}"); + example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))"; + } else { + param.vendorExtensions.put("formatString", "{}"); + example = (param.example != null) ? param.example : ""; + } + } else if (param.isListContainer) { + param.vendorExtensions.put("formatString", "{:?}"); + example = (param.example != null) ? param.example : "&Vec::new()"; + } else if (param.isFile) { + param.vendorExtensions.put("formatString", "{:?}"); + op.vendorExtensions.put("hasFile", true); + additionalProperties.put("apiHasFile", true); + example = "Box::new(stream::once(Ok(b\"hello\".to_vec()))) as Box + Send>"; + } else { + param.vendorExtensions.put("formatString", "{:?}"); + if (param.example != null) { + example = "serde_json::from_str::<" + param.dataType + ">(\"" + param.example + "\").expect(\"Failed to parse JSON example\")"; + } + } + + if (param.required) { + if (example != null) { + param.vendorExtensions.put("example", example); + } else if (param.isListContainer) { + // Use the empty list if we don't have an example + param.vendorExtensions.put("example", "&Vec::new()"); + } + else { + // If we don't have an example that we can provide, we need to disable the client example, as it won't build. + param.vendorExtensions.put("example", "???"); + op.vendorExtensions.put("noClientExample", Boolean.TRUE); + } + } else if ((param.dataFormat != null)&&((param.dataFormat.equals("date-time")) || (param.dataFormat.equals("date")))) { + param.vendorExtensions.put("formatString", "{:?}"); + param.vendorExtensions.put("example", "None"); + } else { + // Not required, so override the format string and example + param.vendorExtensions.put("formatString", "{:?}"); + if (param.isFile) { + // Optional file types are wrapped in a future + param.vendorExtensions.put("example", (example != null) ? "Box::new(future::ok(Some(" + example + "))) as Box + Send>" : "None"); + } else { + param.vendorExtensions.put("example", (example != null) ? "Some(" + example + ")" : "None"); + } + } + } } diff --git a/modules/swagger-codegen/src/main/resources/rust-server/Cargo.mustache b/modules/swagger-codegen/src/main/resources/rust-server/Cargo.mustache index 9e5b566b787..6735b7fdeff 100644 --- a/modules/swagger-codegen/src/main/resources/rust-server/Cargo.mustache +++ b/modules/swagger-codegen/src/main/resources/rust-server/Cargo.mustache @@ -9,32 +9,37 @@ license = "Unlicense" [features] default = ["client", "server"] -client = ["serde_json", {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "hyper-openssl", "uuid"{{#apiHasFile}}, "multipart"{{/apiHasFile}}] -server = ["serde_json", {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "iron", "router", "bodyparser", "urlencoded", "uuid"{{#apiHasFile}}, "multipart"{{/apiHasFile}}] +client = ["serde_json", {{#usesUrlEncodedForm}}"serde_urlencoded", {{/usesUrlEncodedForm}} {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"{{#apiHasFile}}, "multipart"{{/apiHasFile}}] +server = ["serde_json", {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"{{#apiHasFile}}, "multipart"{{/apiHasFile}}] [dependencies] # Required by example server. # chrono = { version = "0.4", features = ["serde"] } futures = "0.1" -hyper = {version = "0.10", optional = true} -hyper-openssl = {version = "0.2", optional = true } -iron = {version = "0.5", optional = true} -swagger = "0.7" +hyper = {version = "0.11", optional = true} +hyper-tls = {version = "0.1.2", optional = true} +swagger = "0.9" # Not required by example server. # -bodyparser = {version = "0.7", optional = true} -url = "1.5" lazy_static = "0.2" log = "0.3.0" -multipart = {version = "0.13", optional = true} -router = {version = "0.5", optional = true} +mime = "0.3.3" +multipart = {version = "0.13.3", optional = true} +native-tls = {version = "0.1.4", optional = true} +openssl = {version = "0.9.14", optional = true} +percent-encoding = {version = "1.0.0", optional = true} +regex = {version = "0.2", optional = true} serde = "1.0" serde_derive = "1.0" serde_ignored = {version = "0.0.4", optional = true} serde_json = {version = "1.0", optional = true} -urlencoded = {version = "0.5", optional = true} +serde_urlencoded = {version = "0.5.1", optional = true} +tokio-core = {version = "0.1.6", optional = true} +tokio-proto = {version = "0.1.1", optional = true} +tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]} +url = {version = "1.5", optional = true} uuid = {version = "0.5", optional = true, features = ["serde", "v4"]} # ToDo: this should be updated to point at the official crate once # https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream diff --git a/modules/swagger-codegen/src/main/resources/rust-server/client-mod.mustache b/modules/swagger-codegen/src/main/resources/rust-server/client-mod.mustache new file mode 100644 index 00000000000..9ed53c0b807 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/rust-server/client-mod.mustache @@ -0,0 +1,437 @@ +#![allow(unused_extern_crates)] +extern crate tokio_core; +extern crate native_tls; +extern crate hyper_tls; +extern crate openssl; +extern crate mime; +extern crate chrono; +extern crate url; +{{#apiHasFile}}extern crate multipart;{{/apiHasFile}} +{{#usesUrlEncodedForm}}extern crate serde_urlencoded;{{/usesUrlEncodedForm}} + +{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}} +{{#apiHasFile}}use self::multipart::client::lazy::Multipart;{{/apiHasFile}} +use hyper; +use hyper::header::{Headers, ContentType}; +use hyper::Uri; +use self::url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; +use futures; +use futures::{Future, Stream}; +use futures::{future, stream}; +use self::tokio_core::reactor::Handle; +use std::borrow::Cow; +use std::io::{Read, Error, ErrorKind}; +use std::error; +use std::fmt; +use std::path::Path; +use std::sync::Arc; +use std::str; +use std::str::FromStr; + +use mimetypes; + +use serde_json; +{{#usesXml}}use serde_xml_rs;{{/usesXml}} + +#[allow(unused_imports)] +use std::collections::{HashMap, BTreeMap}; +#[allow(unused_imports)] +use swagger; + +use swagger::{Context, ApiError, XSpanId}; + +use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, + {{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + }; +use models; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = Uri::from_str(input)?; + + let scheme = uri.scheme().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or_else(|| ClientInitError::MissingHost)?; + let port = uri.port().map(|x| format!(":{}", x)).unwrap_or_default(); + Ok(format!("{}://{}{}", scheme, host, port)) +} + +/// A client that implements the API by making HTTP calls out to a server. +#[derive(Clone)] +pub struct Client { + hyper_client: Arc Box, Response=hyper::Response, Error=hyper::Error, Future=hyper::client::FutureResponse>> + Sync + Send>, + handle: Arc, + base_path: String, +} + +impl fmt::Debug for Client { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Client { + + /// Create an HTTP client. + /// + /// # Arguments + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + pub fn try_new_http(handle: Handle, base_path: &str) -> Result { + let http_connector = swagger::http_connector(); + Self::try_new_with_connector::( + handle, + base_path, + Some("http"), + http_connector, + ) + } + + /// Create a client with a TLS connection to the server. + /// + /// # Arguments + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + pub fn try_new_https( + handle: Handle, + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = swagger::https_connector(ca_certificate); + Self::try_new_with_connector::>( + handle, + base_path, + Some("https"), + https_connector, + ) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + pub fn try_new_https_mutual( + handle: Handle, + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: C, + ) -> Result + where + CA: AsRef, + K: AsRef, + C: AsRef, + { + let https_connector = + swagger::https_mutual_connector(ca_certificate, client_key, client_certificate); + Self::try_new_with_connector::>( + handle, + base_path, + Some("https"), + https_connector, + ) + } + + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with + /// `swagger::{http_connector, https_connector, https_mutual_connector}`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector_fn` - Function which returns an implementation of `hyper::client::Connect` + pub fn try_new_with_connector( + handle: Handle, + base_path: &str, + protocol: Option<&'static str>, + connector_fn: Box C + Send + Sync>, + ) -> Result + where + C: hyper::client::Connect + hyper::client::Service, + { + let hyper_client = { + move |handle: &Handle| -> Box< + hyper::client::Service< + Request = hyper::Request, + Response = hyper::Response, + Error = hyper::Error, + Future = hyper::client::FutureResponse, + >, + > { + let connector = connector_fn(handle); + Box::new(hyper::Client::configure().connector(connector).build( + handle, + )) + } + }; + + Ok(Client { + hyper_client: Arc::new(hyper_client), + handle: Arc::new(handle), + base_path: into_base_path(base_path, protocol)?, + }) + } + + /// Constructor for creating a `Client` by passing in a pre-made `hyper` client. + /// + /// One should avoid relying on this function if possible, since it adds a dependency on the underlying transport + /// implementation, which it would be better to abstract away. Therefore, using this function may lead to a loss of + /// code generality, which may make it harder to move the application to a serverless environment, for example. + /// + /// The reason for this function's existence is to support legacy test code, which did mocking at the hyper layer. + /// This is not a recommended way to write new tests. If other reasons are found for using this function, they + /// should be mentioned here. + pub fn try_new_with_hyper_client(hyper_client: Arc Box, Response=hyper::Response, Error=hyper::Error, Future=hyper::client::FutureResponse>> + Sync + Send>, + handle: Handle, + base_path: &str) + -> Result + { + Ok(Client { + hyper_client: hyper_client, + handle: Arc::new(handle), + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Api for Client { +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} + fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, param_{{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &Context) -> Box> { +{{#queryParams}}{{#-first}} + // Query parameters +{{/-first}}{{#required}} let query_{{paramName}} = format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=param_{{paramName}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}); +{{/required}}{{^required}} let query_{{paramName}} = param_{{paramName}}.map_or_else(String::new, |query| format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=query{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}})); +{{/required}}{{/queryParams}} + + let uri = format!( + "{}{{basePathWithoutHost}}{{path}}{{#queryParams}}{{#-first}}?{{/-first}}{{=<% %>=}}{<% paramName %>}<%={{ }}=%>{{/queryParams}}", + self.base_path{{#pathParams}}, {{baseName}}=utf8_percent_encode(¶m_{{paramName}}.to_string(), PATH_SEGMENT_ENCODE_SET){{/pathParams}}{{#queryParams}}, + {{paramName}}=utf8_percent_encode(&query_{{paramName}}, QUERY_ENCODE_SET){{/queryParams}} + ); + + 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::{{#vendorExtensions}}{{HttpMethod}}{{/vendorExtensions}}, uri); + +{{#vendorExtensions}}{{#hasFile}} // Form data body + let mut multipart = Multipart::new(); + + // Helper function to convert a Stream into a String. The String can then be used to build the HTTP body. + fn convert_stream_to_string(stream: Box, Error=Error> + Send>) -> Result { + + stream.concat2() + .wait() + .map_err(|e| ApiError(format!("Unable to collect stream: {}", e))) + .and_then(|body| String::from_utf8(body) + .map_err(|e| ApiError(format!("Failed to convert utf8 stream to String: {}", e)))) + }{{/hasFile}}{{/vendorExtensions}}{{#formParams}}{{#isFile}} + +{{^required}} if let Ok(Some(param_{{paramName}})) = param_{{paramName}}.wait() { {{/required}} +{{^required}} {{/required}} match convert_stream_to_string(param_{{paramName}}) { +{{^required}} {{/required}} Ok(param_{{paramName}}) => { + // Add file to multipart form. + multipart.add_text("{{paramName}}", param_{{paramName}}); + }, +{{^required}} {{/required}} Err(err) => return Box::new(futures::done(Err(err))), +{{^required}} {{/required}} } + {{^required}}}{{/required}}{{/isFile}}{{/formParams}}{{#vendorExtensions}}{{#hasFile}} + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))), + }; + + let mut body_string = String::new(); + let body = fields.to_body().read_to_string(&mut body_string); + let boundary = fields.boundary(); + let multipart_header = match mime::Mime::from_str(&format!("multipart/form-data;boundary={}", boundary)) { + Ok(multipart_header) => multipart_header, + Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build multipart header: {:?}", err))))), + };{{/hasFile}}{{^hasFile}}{{#formParams}}{{#-first}} let params = &[{{/-first}} + ("{{baseName}}", {{#vendorExtensions}}{{#required}}Some({{#isString}}param_{{paramName}}{{/isString}}{{^isString}}format!("{:?}", param_{{paramName}}){{/isString}}){{/required}}{{^required}}{{#isString}}param_{{paramName}}{{/isString}}{{^isString}}param_{{paramName}}.map(|param| format!("{:?}", param)){{/isString}}{{/required}}),{{/vendorExtensions}}{{#-last}} + ]; + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}.clone())); + request.set_body(body.into_bytes());{{/-last}}{{/formParams}}{{/hasFile}}{{/vendorExtensions}}{{#bodyParam}}{{#-first}} + // Body parameter +{{/-first}}{{#vendorExtensions}}{{#required}}{{#consumesPlainText}} let body = param_{{paramName}};{{/consumesPlainText}}{{#consumesXml}} +{{^has_namespace}} let body = serde_xml_rs::to_string(¶m_{{paramName}}).expect("impossible to fail to serialize");{{/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(), models::namespaces::{{uppercase_data_type}}.clone()); + let body = serde_xml_rs::to_string_with_namespaces(¶m_{{paramName}}, namespaces).expect("impossible to fail to serialize");{{/has_namespace}}{{/consumesXml}}{{#consumesJson}} + let body = serde_json::to_string(¶m_{{paramName}}).expect("impossible to fail to serialize");{{/consumesJson}} +{{/required}}{{^required}}{{#consumesPlainText}} let body = param_{{paramName}}; +{{/consumesPlainText}}{{^consumesPlainText}} let body = param_{{paramName}}.map(|ref body| { +{{#consumesXml}} +{{^has_namespace}} serde_xml_rs::to_string(body).expect("impossible to fail to serialize"){{/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(), models::namespaces::{{uppercase_data_type}}.clone()); + serde_xml_rs::to_string_with_namespaces(body, namespaces).expect("impossible to fail to serialize"){{/has_namespace}}{{/consumesXml}}{{#consumesJson}} + serde_json::to_string(body).expect("impossible to fail to serialize"){{/consumesJson}} + });{{/consumesPlainText}}{{/required}}{{/vendorExtensions}}{{/bodyParam}} + +{{#bodyParam}}{{^required}}if let Some(body) = body { + {{/required}} request.set_body(body.into_bytes()); +{{^required}} }{{/required}} + + request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}.clone())); +{{/bodyParam}} + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); +{{#authMethods}}{{#isBasic}} context.auth_data.as_ref().map(|auth_data| { + if let &swagger::AuthData::Basic(ref basic_header) = auth_data { + request.headers_mut().set(hyper::header::Authorization( + basic_header.clone(), + )) + } + });{{/isBasic}}{{/authMethods}}{{#headerParams}}{{#-first}} + // Header parameters +{{/-first}}{{^isMapContainer}} header! { (Request{{vendorExtensions.typeName}}, "{{baseName}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} } +{{#required}} request.headers_mut().set(Request{{vendorExtensions.typeName}}(param_{{paramName}}{{#isListContainer}}.clone(){{/isListContainer}})); +{{/required}}{{^required}} param_{{paramName}}.map(|header| request.headers_mut().set(Request{{vendorExtensions.typeName}}(header{{#isListContainer}}.clone(){{/isListContainer}}))); +{{/required}}{{/isMapContainer}}{{#isMapContainer}} let param_{{paramName}}: Option<{{{dataType}}}> = None; +{{/isMapContainer}}{{/headerParams}} + +{{#vendorExtensions}}{{#hasFile}} + request.headers_mut().set(ContentType(multipart_header)); + request.set_body(body_string.into_bytes()); +{{/hasFile}}{{/vendorExtensions}} + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { +{{#responses}} + {{code}} => { +{{#headers}} header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{datatype}}}] } + let response_{{name}} = match response.headers().get::() { + Some(response_{{name}}) => response_{{name}}.0.clone(), + None => return Box::new(future::err(ApiError(String::from("Required response header {{baseName}} for response {{code}} was not found.")))) as Box>, + }; +{{/headers}} + {{^isFile}}let body = response.body();{{/isFile}}{{#isFile}}let body = Box::new(response.body() + .map(|chunk| chunk.to_vec()) + .map_err(|_| + Error::new(ErrorKind::Other, "Received error reading response.") + ));{{/isFile}} + Box::new( +{{#dataType}}{{^isFile}} + 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| +{{#vendorExtensions}}{{#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}}{{/vendorExtensions}} + )) + .map(move |body| +{{/isFile}}{{#isFile}} + future::ok( +{{/isFile}} + {{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body: body, {{/-first}}{{name}}: response_{{name}}{{^-last}}, {{/-last}}{{#-last}} }{{/-last}}{{/headers}} + ) +{{/dataType}}{{^dataType}} + future::ok( + {{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{#headers}}{{#-first}}{ {{/-first}}{{^-first}}, {{/-first}}{{name}}: response_{{name}}{{#-last}} }{{/-last}}{{/headers}} + ) +{{/dataType}} + ) as Box> + }, +{{/responses}} + 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> + } + } + })) + + } +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +} + +#[derive(Debug)] +pub enum ClientInitError { + InvalidScheme, + InvalidUri(hyper::error::UriError), + MissingHost, + SslError(openssl::error::ErrorStack) +} + +impl From for ClientInitError { + fn from(err: hyper::error::UriError) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl From for ClientInitError { + fn from(err: openssl::error::ErrorStack) -> ClientInitError { + ClientInitError::SslError(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (self as &fmt::Debug).fmt(f) + } +} + +impl error::Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} diff --git a/modules/swagger-codegen/src/main/resources/rust-server/client.mustache b/modules/swagger-codegen/src/main/resources/rust-server/client.mustache deleted file mode 100644 index 2d9e7b18d5e..00000000000 --- a/modules/swagger-codegen/src/main/resources/rust-server/client.mustache +++ /dev/null @@ -1,342 +0,0 @@ -#![allow(unused_extern_crates)] -extern crate hyper_openssl; -extern crate chrono; -extern crate url; -{{#apiHasFile}}extern crate multipart;{{/apiHasFile}} - -{{#apiHasFile}}use multipart::client::lazy::Multipart;{{/apiHasFile}} -use hyper; -use hyper::client::IntoUrl; -use hyper::mime; -use hyper::header::{Headers, ContentType}; -use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value}; -use hyper::Url; -use self::hyper_openssl::openssl; -use self::url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; -use futures; -use futures::{Future, Stream}; -use futures::{future, stream}; -use std::borrow::Cow; -use std::io::{Read, Error}; -use std::error; -use std::fmt; -use std::path::Path; -use std::sync::Arc; -use std::str; - -use mimetypes; - -use serde_json; -{{#usesXml}}use serde_xml_rs;{{/usesXml}} - -#[allow(unused_imports)] -use std::collections::{HashMap, BTreeMap}; -#[allow(unused_imports)] -use swagger; - -use swagger::{Context, ApiError, XSpanId}; - -use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, - {{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} - }; -use models; - -/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. -fn into_base_path(input: T, correct_scheme: Option<&'static str>) -> Result { - // First convert to Url, since a base path is a subset of Url. - let url = input.into_url()?; - - let scheme = url.scheme(); - - // Check the scheme if necessary - if let Some(correct_scheme) = correct_scheme { - if scheme != correct_scheme { - return Err(ClientInitError::InvalidScheme); - } - } - - let host = url.host().ok_or_else(|| ClientInitError::MissingHost)?; - let port = url.port().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}", scheme, host, port)) -} - -/// A client that implements the API by making HTTP calls out to a server. -#[derive(Clone)] -pub struct Client { - base_path: String, - hyper_client: Arc hyper::client::Client + Sync + Send>, -} - -impl fmt::Debug for Client { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Client {{ base_path: {} }}", self.base_path) - } -} - -impl Client { - pub fn try_new_http(base_path: T) -> Result - where T: IntoUrl - { - Ok(Client { - base_path: into_base_path(base_path, Some("http"))?, - hyper_client: Arc::new(hyper::client::Client::new), - }) - } - - pub fn try_new_https(base_path: T, - ca_certificate: CA) - -> Result - where T: IntoUrl, - CA: AsRef - { - let ca_certificate = ca_certificate.as_ref().to_owned(); - - let https_hyper_client = move || { - // SSL implementation - let mut ssl = openssl::ssl::SslConnectorBuilder::new(openssl::ssl::SslMethod::tls()).unwrap(); - - // Server authentication - ssl.set_ca_file(ca_certificate.clone()).unwrap(); - - let ssl = hyper_openssl::OpensslClient::from(ssl.build()); - let connector = hyper::net::HttpsConnector::new(ssl); - hyper::client::Client::with_connector(connector) - }; - - Ok(Client { - base_path: into_base_path(base_path, Some("https"))?, - hyper_client: Arc::new(https_hyper_client), - }) - } - - pub fn try_new_https_mutual(base_path: T, - ca_certificate: CA, - client_key: K, - client_certificate: C) - -> Result - where T: IntoUrl, - CA: AsRef, - K: AsRef, - C: AsRef - { - let ca_certificate = ca_certificate.as_ref().to_owned(); - let client_key = client_key.as_ref().to_owned(); - let client_certificate = client_certificate.as_ref().to_owned(); - - let https_mutual_hyper_client = move || { - // SSL implementation - let mut ssl = openssl::ssl::SslConnectorBuilder::new(openssl::ssl::SslMethod::tls()).unwrap(); - - // Server authentication - ssl.set_ca_file(ca_certificate.clone()).unwrap(); - - // Client authentication - ssl.set_private_key_file(client_key.clone(), openssl::x509::X509_FILETYPE_PEM).unwrap(); - ssl.set_certificate_chain_file(client_certificate.clone()).unwrap(); - ssl.check_private_key().unwrap(); - - let ssl = hyper_openssl::OpensslClient::from(ssl.build()); - let connector = hyper::net::HttpsConnector::new(ssl); - hyper::client::Client::with_connector(connector) - }; - - Ok(Client { - base_path: into_base_path(base_path, Some("https"))?, - hyper_client: Arc::new(https_mutual_hyper_client) - }) - } - - /// Constructor for creating a `Client` by passing in a pre-made `hyper` client. - /// - /// One should avoid relying on this function if possible, since it adds a dependency on the underlying transport - /// implementation, which it would be better to abstract away. Therefore, using this function may lead to a loss of - /// code generality, which may make it harder to move the application to a serverless environment, for example. - /// - /// The reason for this function's existence is to support legacy test code, which did mocking at the hyper layer. - /// This is not a recommended way to write new tests. If other reasons are found for using this function, they - /// should be mentioned here. - pub fn try_new_with_hyper_client(base_path: T, - hyper_client: Arc hyper::client::Client + Sync + Send>) - -> Result - where T: IntoUrl - { - Ok(Client { - base_path: into_base_path(base_path, None)?, - hyper_client: hyper_client - }) - } -} - -impl Api for Client { -{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} - fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, param_{{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &Context) -> Box + Send> { -{{#queryParams}}{{#-first}} - // Query parameters -{{/-first}}{{#required}} let query_{{paramName}} = format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=param_{{paramName}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}); -{{/required}}{{^required}} let query_{{paramName}} = param_{{paramName}}.map_or_else(String::new, |query| format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=query{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}})); -{{/required}}{{/queryParams}} - - let url = format!( - "{}{{basePathWithoutHost}}{{path}}{{#queryParams}}{{#-first}}?{{/-first}}{{=<% %>=}}{<% paramName %>}<%={{ }}=%>{{/queryParams}}", - self.base_path{{#pathParams}}, {{baseName}}=utf8_percent_encode(¶m_{{paramName}}.to_string(), PATH_SEGMENT_ENCODE_SET){{/pathParams}}{{#queryParams}}, - {{paramName}}=utf8_percent_encode(&query_{{paramName}}, QUERY_ENCODE_SET){{/queryParams}} - ); - -{{#vendorExtensions}}{{#hasFile}} // Form data body - let mut multipart = Multipart::new();{{/hasFile}}{{/vendorExtensions}}{{#formParams}}{{#isFile}} - -{{^required}} if let Ok(Some(param_{{paramName}})) = param_{{paramName}}.wait() { {{/required}} -{{^required}} {{/required}} match convert_stream_to_string(param_{{paramName}}) { -{{^required}} {{/required}} Ok(param_{{paramName}}) => { - // Add file to multipart form. - multipart.add_text("{{paramName}}", param_{{paramName}}); - }, -{{^required}} {{/required}} Err(err) => return Box::new(futures::done(Err(err))), -{{^required}} {{/required}} } - {{^required}}}{{/required}}{{/isFile}}{{/formParams}}{{#vendorExtensions}}{{#hasFile}} - - let mut fields = match multipart.prepare() { - Ok(fields) => fields, - Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))), - }; - - let mut body_string = String::new(); - let body = fields.to_body().read_to_string(&mut body_string); - let boundary = fields.boundary(); - let multipart_header = Mime(TopLevel::Multipart, SubLevel::FormData, vec![(Attr::Boundary, Value::Ext(boundary.to_string()))]);{{/hasFile}}{{/vendorExtensions}}{{#bodyParam}}{{#-first}} - // Body parameter -{{/-first}}{{#vendorExtensions}}{{#required}}{{#consumesPlainText}} let body = param_{{paramName}};{{/consumesPlainText}}{{#consumesXml}} -{{^has_namespace}} let body = serde_xml_rs::to_string(¶m_{{paramName}}).expect("impossible to fail to serialize");{{/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(), models::namespaces::{{uppercase_data_type}}.clone()); - let body = serde_xml_rs::to_string_with_namespaces(¶m_{{paramName}}, namespaces).expect("impossible to fail to serialize");{{/has_namespace}}{{/consumesXml}}{{#consumesJson}} - let body = serde_json::to_string(¶m_{{paramName}}).expect("impossible to fail to serialize");{{/consumesJson}} -{{/required}}{{^required}}{{#consumesPlainText}} let body = param_{{paramName}}; -{{/consumesPlainText}}{{^consumesPlainText}} let body = param_{{paramName}}.map(|ref body| { -{{#consumesXml}} -{{^has_namespace}} serde_xml_rs::to_string(body).expect("impossible to fail to serialize"){{/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(), models::namespaces::{{uppercase_data_type}}.clone()); - serde_xml_rs::to_string_with_namespaces(body, namespaces).expect("impossible to fail to serialize"){{/has_namespace}}{{/consumesXml}}{{#consumesJson}} - serde_json::to_string(body).expect("impossible to fail to serialize"){{/consumesJson}} - });{{/consumesPlainText}}{{/required}}{{/vendorExtensions}}{{/bodyParam}} - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::{{#vendorExtensions}}{{HttpMethod}}{{/vendorExtensions}}, &url); - let mut custom_headers = hyper::header::Headers::new(); - -{{#bodyParam}}{{#required}} let request = request.body(&body); -{{/required}}{{^required}} let request = match body { - Some(ref body) => request.body(body), - None => request, - }; -{{/required}} - - custom_headers.set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}.clone())); -{{/bodyParam}} - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); -{{#headerParams}}{{#-first}} - // Header parameters -{{/-first}}{{^isMapContainer}} header! { (Request{{vendorExtensions.typeName}}, "{{baseName}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} } -{{#required}} custom_headers.set(Request{{vendorExtensions.typeName}}(param_{{paramName}}{{#isListContainer}}.clone(){{/isListContainer}})); -{{/required}}{{^required}} param_{{paramName}}.map(|header| custom_headers.set(Request{{vendorExtensions.typeName}}(header{{#isListContainer}}.clone(){{/isListContainer}}))); -{{/required}}{{/isMapContainer}}{{#isMapContainer}} let param_{{paramName}}: Option<{{{dataType}}}> = None; -{{/isMapContainer}}{{/headerParams}} - - let request = request.headers(custom_headers);{{#vendorExtensions}}{{#hasFile}} - let request = request.header(ContentType(multipart_header)) - .body(&body_string); -{{/hasFile}}{{/vendorExtensions}} - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result<{{operationId}}Response, ApiError> { - match response.status.to_u16() { -{{#responses}} - {{code}} => { -{{#dataType}}{{^isFile}} let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;{{#vendorExtensions}}{{#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 - let body = serde_xml_rs::from_str::<{{{dataType}}}>(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?;{{/producesXml}}{{#producesPlainText}} - let body = buf;{{/producesPlainText}}{{#producesJson}} - let body = serde_json::from_str::<{{{dataType}}}>(&buf)?;{{/producesJson}}{{/vendorExtensions}}{{/isFile}}{{#isFile}} - let mut buf = Vec::new(); - response.read_to_end(&mut buf).map_err(|e| ApiError(format!("Received error reading response: {}", e)))?; - let body = Box::new(stream::once(Ok(buf)));{{/isFile}}{{/dataType}} -{{#headers}} header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{datatype}}}] } - let response_{{name}} = response.headers.get::().ok_or_else(|| "Required response header {{baseName}} for response {{code}} was not found.")?; -{{/headers}} - -{{#dataType}} Ok({{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body: body, {{/-first}}{{name}}: response_{{name}}.0.clone(){{^-last}}, {{/-last}}{{#-last}} }{{/-last}}{{/headers}}) -{{/dataType}}{{^dataType}} Ok({{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{#headers}}{{#-first}}{ {{/-first}}{{^-first}}, {{/-first}}{{name}}: response_{{name}}.0.clone(){{#-last}} }{{/-last}}{{/headers}}) -{{/dataType}} - }, -{{/responses}} - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - }{{#vendorExtensions}}{{#hasFile}} - - // Helper function to convert a Stream into a String. The String can then be used to build the HTTP body. - fn convert_stream_to_string(stream: Box, Error=Error> + Send>) -> Result { - - stream.fold(Vec::new(), |mut body, chunk| { - body.extend(chunk.iter()); - future::ok::,Error>(body) - }).wait() - .map_err(|e| ApiError(format!("Unable to fold stream: {}", e))) - .and_then(|body| String::from_utf8(body) - .map_err(|e| ApiError(format!("Failed to convert utf8 stream to String: {}", e)))) - }{{/hasFile}}{{/vendorExtensions}} - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } -{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} -} - -#[derive(Debug)] -pub enum ClientInitError { - InvalidScheme, - InvalidUrl(hyper::error::ParseError), - MissingHost, - SslError(openssl::error::ErrorStack) -} - -impl From for ClientInitError { - fn from(err: hyper::error::ParseError) -> ClientInitError { - ClientInitError::InvalidUrl(err) - } -} - -impl From for ClientInitError { - fn from(err: openssl::error::ErrorStack) -> ClientInitError { - ClientInitError::SslError(err) - } -} - -impl fmt::Display for ClientInitError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - (self as &fmt::Debug).fmt(f) - } -} - -impl error::Error for ClientInitError { - fn description(&self) -> &str { - "Failed to produce a hyper client." - } -} diff --git a/modules/swagger-codegen/src/main/resources/rust-server/example-client.mustache b/modules/swagger-codegen/src/main/resources/rust-server/example-client.mustache index e5b59e5c4f9..2245ae47562 100644 --- a/modules/swagger-codegen/src/main/resources/rust-server/example-client.mustache +++ b/modules/swagger-codegen/src/main/resources/rust-server/example-client.mustache @@ -8,9 +8,11 @@ extern crate swagger; #[allow(unused_extern_crates)] extern crate uuid; extern crate clap; +extern crate tokio_core; #[allow(unused_imports)] use futures::{Future, future, Stream, stream}; +use tokio_core::reactor; #[allow(unused_imports)] use {{externCrateName}}::{ApiNoContext, ContextWrapperExt, ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, @@ -42,18 +44,19 @@ fn main() { .help("Port to contact")) .get_matches(); + let mut core = reactor::Core::new().unwrap(); let is_https = matches.is_present("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if is_https { + let client = if matches.is_present("https") { // Using Simple HTTPS - {{externCrateName}}::Client::try_new_https(&base_url, "examples/ca.pem") + {{externCrateName}}::Client::try_new_https(core.handle(), &base_url, "examples/ca.pem") .expect("Failed to create HTTPS client") } else { // Using HTTP - {{externCrateName}}::Client::try_new_http(&base_url) + {{externCrateName}}::Client::try_new_http(core.handle(), &base_url) .expect("Failed to create HTTP client") }; @@ -64,7 +67,7 @@ fn main() { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#vendorExtensions}}{{#noClientExample}}// Disabled because there's no example. // {{/noClientExample}}Some("{{operationId}}") => { - {{#noClientExample}}// {{/noClientExample}} let result = client.{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{^-first}}, {{/-first}}{{#vendorExtensions}}{{{example}}}{{/vendorExtensions}}{{/allParams}}).wait(); + {{#noClientExample}}// {{/noClientExample}} let result = core.run(client.{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{^-first}}, {{/-first}}{{#vendorExtensions}}{{{example}}}{{/vendorExtensions}}{{/allParams}})); {{#vendorExtensions}}{{#noClientExample}}// {{/noClientExample}}{{/vendorExtensions}} println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); {{#vendorExtensions}}{{#noClientExample}}// {{/noClientExample}}{{/vendorExtensions}} }, {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} diff --git a/modules/swagger-codegen/src/main/resources/rust-server/example-server.mustache b/modules/swagger-codegen/src/main/resources/rust-server/example-server.mustache index 007384b33fe..ee99d434bb3 100644 --- a/modules/swagger-codegen/src/main/resources/rust-server/example-server.mustache +++ b/modules/swagger-codegen/src/main/resources/rust-server/example-server.mustache @@ -6,8 +6,11 @@ // extern crate ; extern crate {{externCrateName}}; extern crate swagger; -extern crate iron; -extern crate hyper_openssl; +extern crate hyper; +extern crate openssl; +extern crate native_tls; +extern crate tokio_proto; +extern crate tokio_tls; extern crate clap; // Imports required by server library. @@ -17,19 +20,20 @@ extern crate futures; extern crate chrono; #[macro_use] extern crate error_chain; +{{#apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}} -use hyper_openssl::OpensslServer; -use hyper_openssl::openssl::x509::X509_FILETYPE_PEM; -use hyper_openssl::openssl::ssl::{SslAcceptorBuilder, SslMethod}; -use hyper_openssl::openssl::error::ErrorStack; +use openssl::x509::X509_FILETYPE_PEM; +use openssl::ssl::{SslAcceptorBuilder, SslMethod}; +use openssl::error::ErrorStack; +use hyper::server::Http; +use tokio_proto::TcpServer; use clap::{App, Arg}; -use iron::{Iron, Chain}; -use swagger::auth::AllowAllMiddleware; +use swagger::auth::AllowAllAuthenticator; mod server_lib; -/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -fn ssl() -> Result { +// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +fn ssl() -> Result { let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?; // Server authentication @@ -37,7 +41,7 @@ fn ssl() -> Result { ssl.set_certificate_chain_file("examples/server-chain.pem")?; ssl.check_private_key()?; - Ok(OpensslServer::from(ssl.build())) + Ok(ssl) } /// Create custom server, wire it to the autogenerated router, @@ -49,20 +53,22 @@ fn main() { .help("Whether to use HTTPS or not")) .get_matches(); - let server = server_lib::server().unwrap(); - let router = {{externCrateName}}::router(server); - - let mut chain = Chain::new(router); - chain.link_before({{externCrateName}}::server::ExtractAuthData); - // add authentication middlewares into the chain here - // for the purpose of this example, pretend we have authenticated a user - chain.link_before(AllowAllMiddleware::new("cosmo")); + let service_fn = + {{externCrateName}}::server::auth::NewService::new( + AllowAllAuthenticator::new( + server_lib::NewService, + "cosmo" + ) + ); + let addr = "127.0.0.1:{{serverPort}}".parse().expect("Failed to parse bind address"); if matches.is_present("https") { - // Using Simple HTTPS - Iron::new(chain).https("localhost:{{serverPort}}", ssl().expect("Failed to load SSL keys")).expect("Failed to start HTTPS server"); + let ssl = ssl().expect("Failed to load SSL keys"); + let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl); + let tls_acceptor = builder.build().expect("Failed to build TLS acceptor"); + TcpServer::new(tokio_tls::proto::Server::new(Http::new(), tls_acceptor), addr).serve(service_fn); } else { // Using HTTP - Iron::new(chain).http("localhost:{{serverPort}}").expect("Failed to start HTTP server"); + TcpServer::new(Http::new(), addr).serve(service_fn); } } diff --git a/modules/swagger-codegen/src/main/resources/rust-server/example-server_lib.mustache b/modules/swagger-codegen/src/main/resources/rust-server/example-server_lib.mustache index 7e85ec86199..d02d0525b47 100644 --- a/modules/swagger-codegen/src/main/resources/rust-server/example-server_lib.mustache +++ b/modules/swagger-codegen/src/main/resources/rust-server/example-server_lib.mustache @@ -7,8 +7,20 @@ mod errors { } pub use self::errors::*; +use std::io; +use hyper; +use {{externCrateName}}; -/// Instantiate a new server. -pub fn server() -> Result { - Ok(server::Server {}) +pub struct NewService; + +impl hyper::server::NewService for NewService { + type Request = (hyper::Request, {{externCrateName}}::Context); + type Response = hyper::Response; + type Error = hyper::Error; + type Instance = {{externCrateName}}::server::Service; + + /// Instantiate a new server. + fn new_service(&self) -> io::Result { + Ok({{externCrateName}}::server::Service::new(server::Server)) + } } diff --git a/modules/swagger-codegen/src/main/resources/rust-server/example-server_server.mustache b/modules/swagger-codegen/src/main/resources/rust-server/example-server_server.mustache index 8b8bf033927..fdb7ceaf541 100644 --- a/modules/swagger-codegen/src/main/resources/rust-server/example-server_server.mustache +++ b/modules/swagger-codegen/src/main/resources/rust-server/example-server_server.mustache @@ -7,6 +7,7 @@ use chrono; {{#apiHasFile}}use futures::Stream;{{/apiHasFile}} use std::collections::HashMap; {{#apiHasFile}}use std::io::Error;{{/apiHasFile}} +{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}} use swagger; use {{externCrateName}}::{Api, ApiError, Context{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, @@ -20,7 +21,7 @@ pub struct Server; impl Api for Server { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#summary}} /// {{{summary}}}{{/summary}} - fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &Context) -> Box + Send> { + fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &Context) -> Box> { let context = context.clone(); println!("{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{^isFile}}{{#vendorExtensions}}{{{formatString}}}{{/vendorExtensions}}{{#hasMore}}, {{/hasMore}}{{/isFile}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}{{^isFile}}, {{paramName}}{{/isFile}}{{/allParams}}, context.x_span_id.unwrap_or(String::from("")).clone());{{#allParams}}{{#isFile}} let _ = {{paramName}}; //Suppresses unused param warning{{/isFile}}{{/allParams}} diff --git a/modules/swagger-codegen/src/main/resources/rust-server/lib.mustache b/modules/swagger-codegen/src/main/resources/rust-server/lib.mustache index 0ab6543fcfc..e01f1496731 100644 --- a/modules/swagger-codegen/src/main/resources/rust-server/lib.mustache +++ b/modules/swagger-codegen/src/main/resources/rust-server/lib.mustache @@ -3,10 +3,10 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; +{{#apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}} {{#usesXml}}extern crate serde_xml_rs;{{/usesXml}} extern crate futures; extern crate chrono; -{{#apiHasFile}}extern crate multipart;{{/apiHasFile}} #[macro_use] extern crate lazy_static; #[macro_use] @@ -32,6 +32,8 @@ mod mimetypes; pub use swagger::{ApiError, Context, ContextWrapper}; +pub const BASE_PATH: &'static str = "{{basePathWithoutHost}}"; + {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{^isResponseFile}} #[derive(Debug, PartialEq)] @@ -48,7 +50,7 @@ pub enum {{operationId}}Response { pub trait Api { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#summary}} /// {{{summary}}}{{/summary}} - fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &Context) -> Box + Send>; + fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &Context) -> Box>; {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} } @@ -56,7 +58,7 @@ pub trait Api { pub trait ApiNoContext { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#summary}} /// {{{summary}}}{{/summary}} - fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}) -> Box + Send>; + fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}) -> Box>; {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} } @@ -75,7 +77,7 @@ impl<'a, T: Api + Sized> ContextWrapperExt<'a> for T { impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#summary}} /// {{{summary}}}{{/summary}} - fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}) -> Box + Send> { + fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}) -> Box> { self.api().{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{paramName}}, {{/allParams}}&self.context()) } {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} @@ -93,6 +95,6 @@ pub mod server; // Re-export router() as a top-level name #[cfg(feature = "server")] -pub use self::server::router; +pub use self::server::Service; pub mod models; diff --git a/modules/swagger-codegen/src/main/resources/rust-server/mimetypes.mustache b/modules/swagger-codegen/src/main/resources/rust-server/mimetypes.mustache index 744374ca995..047c7c7fbbc 100644 --- a/modules/swagger-codegen/src/main/resources/rust-server/mimetypes.mustache +++ b/modules/swagger-codegen/src/main/resources/rust-server/mimetypes.mustache @@ -15,7 +15,11 @@ pub mod requests { use hyper::mime::*; {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}} /// Create Mime objects for the request content types for {{operationId}} lazy_static! { - pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}Application/Json{{/consumes}}".parse().unwrap(); + pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}".parse().unwrap(); } -{{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +{{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}}{{^hasFile}} /// Create Mime objects for the request content types for {{operationId}} + lazy_static! { + pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}".parse().unwrap(); + } +{{/hasFile}}{{/-first}}{{/formParams}}{{/vendorExtensions}}{{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} } diff --git a/modules/swagger-codegen/src/main/resources/rust-server/models.mustache b/modules/swagger-codegen/src/main/resources/rust-server/models.mustache old mode 100755 new mode 100644 diff --git a/modules/swagger-codegen/src/main/resources/rust-server/server-auth.mustache b/modules/swagger-codegen/src/main/resources/rust-server/server-auth.mustache new file mode 100644 index 00000000000..5f2884cf8aa --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/rust-server/server-auth.mustache @@ -0,0 +1,95 @@ +use std::io; +use hyper; +use hyper::{Request, Response, Error, StatusCode}; +use server::url::form_urlencoded; +use swagger::auth::{Authorization, AuthData, Scopes}; +use Api; + +pub struct NewService where T: hyper::server::NewService), Response=Response, Error=Error> { + inner: T, +} + +impl NewService where T: hyper::server::NewService), Response=Response, Error=Error> + 'static { + pub fn new(inner: T) -> NewService { + NewService{inner} + } +} + +impl hyper::server::NewService for NewService where T: hyper::server::NewService), Response=Response, Error=Error> + 'static { + type Request = Request; + type Response = Response; + type Error = Error; + type Instance = Service; + + fn new_service(&self) -> Result { + self.inner.new_service().map(|s| Service::new(s)) + } +} + +/// Middleware to extract authentication data from request +pub struct Service where T: hyper::server::Service), Response=Response, Error=Error> { + inner: T, +} + +impl Service where T: hyper::server::Service), Response=Response, Error=Error> { + pub fn new(inner: T) -> Service { + Service{inner} + } +} + +impl hyper::server::Service for Service where T: hyper::server::Service), Response=Response, Error=Error> { + type Request = Request; + type Response = Response; + type Error = Error; + type Future = T::Future; + + fn call(&self, req: Self::Request) -> Self::Future { + {{#authMethods}} + {{#isBasic}} + { + use hyper::header::{Authorization, Basic, Bearer}; + use std::ops::Deref; + if let Some(basic) = req.headers().get::>().cloned() { + let auth_data = AuthData::Basic(basic.deref().clone()); + return self.inner.call((req, Some(auth_data))); + } + } + {{/isBasic}} + {{#isOAuth}} + { + use hyper::header::{Authorization, Basic, Bearer}; + use std::ops::Deref; + if let Some(bearer) = req.headers().get::>().cloned() { + let auth_data = AuthData::Bearer(bearer.deref().clone()); + return self.inner.call((req, Some(auth_data))); + } + } + {{/isOAuth}} + {{#isApiKey}} + {{#isKeyInHeader}} + { + header! { (ApiKey{{-index}}, "{{keyParamName}}") => [String] } + if let Some(header) = req.headers().get::().cloned() { + let auth_data = AuthData::ApiKey(header.0); + return self.inner.call((req, Some(auth_data))); + } + } + {{/isKeyInHeader}} + {{#isKeyInQuery}} + { + let key = form_urlencoded::parse(req.query().unwrap_or_default().as_bytes()) + .filter(|e| e.0 == "api_key_query") + .map(|e| e.1.clone().into_owned()) + .nth(0); + if let Some(key) = key { + let auth_data = AuthData::ApiKey(key); + return self.inner.call((req, Some(auth_data))); + } + } + {{/isKeyInQuery}} + {{/isApiKey}} + {{/authMethods}} + + return self.inner.call((req, None)); + } +} diff --git a/modules/swagger-codegen/src/main/resources/rust-server/server-mod.mustache b/modules/swagger-codegen/src/main/resources/rust-server/server-mod.mustache new file mode 100644 index 00000000000..6b564f05546 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/rust-server/server-mod.mustache @@ -0,0 +1,449 @@ +#![allow(unused_extern_crates)] +extern crate serde_ignored; +extern crate tokio_core; +extern crate native_tls; +extern crate hyper_tls; +extern crate openssl; +extern crate mime; +{{^apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}} +extern crate chrono; +{{#apiHasFile}}extern crate multipart;{{/apiHasFile}} +extern crate percent_encoding; +extern crate url; + +{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}} +use std::sync::Arc; +use futures::{Future, future, Stream, stream}; +use hyper; +use hyper::{Request, Response, Error, StatusCode}; +use hyper::header::{Headers, ContentType}; +use self::url::form_urlencoded; +use mimetypes; +{{#apiHasFile}}use self::multipart::server::Multipart; +use self::multipart::server::save::SaveResult;{{/apiHasFile}} + +use serde_json; +{{#usesXml}}use serde_xml_rs;{{/usesXml}} + +#[allow(unused_imports)] +use std::collections::{HashMap, BTreeMap}; +#[allow(unused_imports)] +use swagger; +use std::io; + +#[allow(unused_imports)] +use std::collections::BTreeSet; + +pub use swagger::auth::Authorization; +use swagger::{ApiError, Context, XSpanId}; +use swagger::auth::Scopes; + +use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, + {{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + }; +#[allow(unused_imports)] +use models; + +pub mod auth; + +header! { (Warning, "Warning") => [String] } + +mod paths { + extern crate regex; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(&[ +{{#pathSet}} + r"^{{basePathWithoutHost}}{{{pathRegEx}}}"{{^-last}},{{/-last}} +{{/pathSet}} + ]).unwrap(); + } +{{#pathSet}} + pub static ID_{{PATH_ID}}: usize = {{index}}; +{{#hasPathParams}} + lazy_static! { + pub static ref REGEX_{{PATH_ID}}: regex::Regex = regex::Regex::new(r"^{{basePathWithoutHost}}{{{pathRegEx}}}").unwrap(); + } +{{/hasPathParams}} +{{/pathSet}} +} + +pub struct NewService { + api_impl: Arc, +} + +impl NewService where T: Api + Clone + 'static { + pub fn new>>(api_impl: U) -> NewService { + NewService{api_impl: api_impl.into()} + } +} + +impl hyper::server::NewService for NewService where T: Api + Clone + 'static { + type Request = (Request, Context); + type Response = Response; + type Error = Error; + type Instance = Service; + + fn new_service(&self) -> Result { + Ok(Service::new(self.api_impl.clone())) + } +} + +pub struct Service { + api_impl: Arc, +} + +impl Service where T: Api + Clone + 'static { + pub fn new>>(api_impl: U) -> Service { + Service{api_impl: api_impl.into()} + } +} + +impl hyper::server::Service for Service where T: Api + Clone + 'static { + type Request = (Request, Context); + type Response = Response; + type Error = Error; + type Future = Box>; + + fn call(&self, (req, mut context): Self::Request) -> Self::Future { + let api_impl = self.api_impl.clone(); + let (method, uri, _, headers, body) = req.deconstruct(); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + match &method { +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} + // {{operationId}} - {{httpMethod}} {{path}} + &hyper::Method::{{vendorExtensions.HttpMethod}} if path.matched(paths::ID_{{vendorExtensions.PATH_ID}}) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } +{{#hasAuthMethods}} + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + {{#authMethods}} + {{#isOAuth}} + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + {{#scopes}} + "{{scope}}".to_string(), // {{description}} + {{/scopes}} + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + {{/isOAuth}} + {{/authMethods}} + } +{{/hasAuthMethods}} + +{{#vendorExtensions}}{{#hasPathParams}} + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_{{PATH_ID}} + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE {{PATH_ID}} in set but failed match against \"{}\"", path, paths::REGEX_{{PATH_ID}}.as_str()) + ); +{{/hasPathParams}}{{/vendorExtensions}} +{{#pathParams}} + let param_{{paramName}} = match percent_encoding::percent_decode(path_params["{{baseName}}"].as_bytes()).decode_utf8() { + Ok(param_{{paramName}}) => match param_{{paramName}}.parse::<{{{dataType}}}>() { + Ok(param_{{paramName}}) => param_{{paramName}}, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter {{baseName}}: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{baseName}}"])))) + }; +{{/pathParams}} +{{#headerParams}}{{#-first}} + // Header parameters +{{/-first}} + header! { (Request{{vendorExtensions.typeName}}, "{{baseName}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} } +{{#required}} + let param_{{paramName}} = match headers.get::() { + Some(param_{{paramName}}) => param_{{paramName}}.0.clone(), + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing or invalid required header {{baseName}}"))), + }; +{{/required}} +{{^required}} + let param_{{paramName}} = headers.get::().map(|header| header.0.clone()); +{{/required}}{{/headerParams}} + +{{#queryParams}}{{#-first}} + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); +{{/-first}} + let param_{{paramName}} = query_params.iter().filter(|e| e.0 == "{{baseName}}").map(|e| e.1.to_owned()) +{{#isListContainer}} + .filter_map(|param_{{paramName}}| param_{{paramName}}.parse::<{{{baseType}}}>().ok()) + .collect::>(); +{{^required}} + let param_{{paramName}} = if !param_{{paramName}}.is_empty() { + Some(param_{{paramName}}) + } else { + None + }; +{{/required}} +{{/isListContainer}}{{^isListContainer}} + .nth(0); +{{#required}} + let param_{{paramName}} = match param_{{paramName}} { + Some(param_{{paramName}}) => match param_{{paramName}}.parse::<{{{dataType}}}>() { + Ok(param_{{paramName}}) => param_{{paramName}}, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse query parameter {{baseName}} - doesn't match schema: {}", e)))), + }, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required query parameter {{baseName}}"))), + }; +{{/required}}{{^required}} + let param_{{paramName}} = param_{{paramName}}.and_then(|param_{{paramName}}| param_{{paramName}}.parse::<{{{baseType}}}>().ok()); +{{/required}} +{{/isListContainer}} +{{/queryParams}} + +{{#bodyParams}}{{#-first}} + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { +{{#vendorExtensions}}{{^consumesPlainText}} + let mut unused_elements = Vec::new(); +{{/consumesPlainText}} + let param_{{paramName}}: Option<{{{dataType}}}> = if !body.is_empty() { +{{#consumesXml}} + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); +{{/consumesXml}}{{#consumesJson}} + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); +{{/consumesJson}}{{^consumesPlainText}} + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_{{paramName}}) => param_{{paramName}}, +{{#required}} + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{baseName}} - doesn't match schema: {}", e)))), +{{/required}}{{^required}} + Err(_) => None, +{{/required}} + } +{{/consumesPlainText}}{{#consumesPlainText}} + match String::from_utf8(body.to_vec()) { + Ok(param_{{paramName}}) => Some(param_{{paramName}}), + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{baseName}} - not valid UTF-8: {}", e)))), + } +{{/consumesPlainText}}{{/vendorExtensions}} + } else { + None + }; +{{#required}} + let param_{{paramName}} = match param_{{paramName}} { + Some(param_{{paramName}}) => param_{{paramName}}, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter {{baseName}}"))), + }; +{{/required}} +{{/-first}}{{/bodyParams}} +{{^bodyParams}}{{#vendorExtensions}}{{#hasFile}} + let boundary = match multipart_boundary(&headers) { + Some(boundary) => boundary.to_string(), + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Couldn't find valid multipart body"))), + }; + + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() { + SaveResult::Full(entries) => { + entries + }, + _ => { + return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Unable to process all message parts")))) + }, + }; +{{#formParams}}{{#-first}} + // Form parameters +{{/-first}} + let param_{{paramName}} = entries.fields.remove("{{paramName}}"); + let param_{{paramName}} = match param_{{paramName}} { + Some(entry) => +{{#isFile}} + {{^required}}Some({{/required}}Box::new(stream::once(Ok(entry.as_bytes().to_vec()))) as Box, Error=io::Error> + Send>{{^required}}){{/required}}, +{{/isFile}}{{^isFile}} + match entry.parse::<{{{dataType}}}>() { + Ok(entry) => {{^required}}Some({{/required}}entry{{^required}}){{/required}}, +{{#required}} + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse form parameter {{baseName}} - doesn't match schema: {}", e)))), +{{/required}}{{^required}} + Err(_) => None, +{{/required}} + }, +{{/isFile}} +{{#required}} + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Missing required form parameter {{paramName}}")))), +{{/required}}{{^required}} + None => None, +{{/required}} + }; +{{^required}}{{#isFile}} let param_{{paramName}} = Box::new(future::ok(param_{{paramName}}));{{/isFile}}{{/required}} +{{/formParams}} +{{/hasFile}}{{^hasFile}} + Box::new(({ + {{ +{{#formParams}}{{#-first}} + // Form parameters +{{/-first}} + let param_{{paramName}} = {{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}} +{{/formParams}} +{{/hasFile}}{{/vendorExtensions}}{{/bodyParams}} + Box::new(api_impl.{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}param_{{paramName}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}}&context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); +{{#bodyParams}}{{#vendorExtensions}}{{^consumesPlainText}} + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } +{{/consumesPlainText}}{{/vendorExtensions}}{{/bodyParams}} + match result { + Ok(rsp) => match rsp { +{{#responses}} + {{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}} +{{#dataType}}{{^headers}} + (body) +{{/headers}}{{#headers}} +{{#-first}} + { + body, +{{/-first}} + {{name}}{{^-last}}, {{/-last}} +{{#-last}} + } +{{/-last}} +{{/headers}}{{/dataType}} +{{^dataType}}{{#headers}}{{#-first}} + { +{{/-first}} + {{name}}{{^-last}}, {{/-last}} +{{#-last}} + } +{{/-last}} +{{/headers}}{{/dataType}} + => { +{{^isFile}} response.set_status(StatusCode::try_from({{code}}).unwrap()); +{{#headers}} + header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{datatype}}}] } + response.headers_mut().set(Response{{nameInCamelCase}}({{name}})); +{{/headers}} +{{#produces}}{{#-first}}{{#dataType}} + response.headers_mut().set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone())); +{{/dataType}}{{/-first}}{{/produces}} +{{#dataType}} +{{#vendorExtensions}}{{#producesXml}}{{^has_namespace}} + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); +{{/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(), models::namespaces::{{uppercase_data_type}}.clone()); + let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize"); +{{/has_namespace}}{{/producesXml}}{{#producesJson}} + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); +{{/producesJson}}{{/vendorExtensions}} + response.set_body(body); +{{/dataType}}{{/isFile}}{{#isFile}} + let body = body.fold(Vec::new(), | mut body, chunk| { + body.extend(chunk.iter()); + future::ok::, io::Error>(body) + }) + // Block whilst waiting for the stream to complete + .wait(); + + match body { + // If no error occurred then create successful hyper response + Ok(vec) => { + response.set_status(StatusCode::try_from({{code}}).unwrap()); + +{{#headers}} + header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{datatype}}}] } + response.headers_mut().set(Response{{nameInCamelCase}}({{name}})); +{{/headers}}{{#produces}}{{#-first}}{{#dataType}} + response.headers_mut().set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone())); +{{/dataType}}{{/-first}}{{/produces}} + response.set_body(vec); + }, + // It's possible that errors were received in the stream, if this is the case then we can't return a success response to the client and instead must return an internal error. + Err(e) => { + response.set_status(StatusCode::InternalServerError); + response.set_body("An internal error occurred"); + } + } +{{/isFile}} + }, +{{/responses}} + }, + 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) + } + )) +{{^bodyParams}}{{#vendorExtensions}}{{^hasFile}} + }} + })) as Box> +{{/hasFile}}{{#hasFile}} + as Box> + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read multipart body")))), + } + }) + ) +{{/hasFile}}{{/vendorExtensions}}{{/bodyParams}} +{{#bodyParams}}{{#-first}} + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter {{baseName}}: {}", e)))), + } + }) + ) as Box> +{{/-first}}{{/bodyParams}} + }, + +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + _ => Box::new(future::ok(Response::new().with_status(StatusCode::NotFound))) as Box>, + } + } +} + +{{#apiHasFile}} +/// Utility function to get the multipart boundary marker (if any) from the Headers. +fn multipart_boundary<'a>(headers: &'a Headers) -> Option<&'a str> { + headers.get::().and_then(|content_type| { + let ContentType(ref mime) = *content_type; + if mime.type_() == mime::MULTIPART && mime.subtype() == mime::FORM_DATA { + mime.get_param(mime::BOUNDARY).map(|x| x.as_str()) + } else { + None + } + }) +} +{{/apiHasFile}} diff --git a/modules/swagger-codegen/src/main/resources/rust-server/server.mustache b/modules/swagger-codegen/src/main/resources/rust-server/server.mustache deleted file mode 100644 index edce03389f7..00000000000 --- a/modules/swagger-codegen/src/main/resources/rust-server/server.mustache +++ /dev/null @@ -1,340 +0,0 @@ -#![allow(unused_extern_crates)] -extern crate serde_ignored; -extern crate iron; -extern crate router; -extern crate bodyparser; -extern crate urlencoded; -extern crate uuid; -extern crate chrono; -{{#apiHasFile}}extern crate multipart;{{/apiHasFile}} - -use futures::Future; -use futures::future; -use futures::{stream, Stream}; -use hyper; -use hyper::header::{Headers, ContentType}; -use self::iron::prelude::*; -use self::iron::{status, modifiers, BeforeMiddleware}; -use self::iron::url::percent_encoding::percent_decode; -use self::router::Router; -use self::urlencoded::UrlEncodedQuery; -use mimetypes; -{{#apiHasFile}}use multipart::server::{Multipart, SaveResult};{{/apiHasFile}} - -use serde_json; -{{#usesXml}}use serde_xml_rs;{{/usesXml}} - -#[allow(unused_imports)] -use std::collections::{HashMap, BTreeMap}; -#[allow(unused_imports)] -use swagger; -use std::io::Error; - -#[allow(unused_imports)] -use std::collections::BTreeSet; - -pub use swagger::auth::Authorization; -use swagger::auth::{AuthData, Scopes}; -use swagger::{ApiError, Context, XSpanId}; - -use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, - {{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} - }; -#[allow(unused_imports)] -use models; - -header! { (Warning, "Warning") => [String] } - -/// Create a new router for `Api` -pub fn router(api: T) -> Router where T: Api + Send + Sync + Clone + 'static { - let mut router = Router::new(); - add_routes(&mut router, api); - router -} - -/// Add routes for `Api` to a provided router. -/// -/// Note that these routes are added straight onto the router. This means that if the router -/// already has a route for an endpoint which clashes with those provided by this API, then the -/// old route will be lost. -/// -/// It is generally a bad idea to add routes in this way to an existing router, which may have -/// routes on it for other APIs. Distinct APIs should be behind distinct paths to encourage -/// separation of interfaces, which this function does not enforce. APIs should not overlap. -/// -/// Alternative approaches include: -/// -/// - generate an `iron::middleware::Handler` (usually a `router::Router` or -/// `iron::middleware::chain`) for each interface, and add those handlers inside an existing -/// router, mounted at different paths - so the interfaces are separated by path -/// - use a different instance of `iron::Iron` for each interface - so the interfaces are -/// separated by the address/port they listen on -/// -/// This function exists to allow legacy code, which doesn't separate its APIs properly, to make -/// use of this crate. -#[deprecated(note="APIs should not overlap - only for use in legacy code.")] -pub fn route(router: &mut Router, api: T) where T: Api + Send + Sync + Clone + 'static { - add_routes(router, api) -} - -/// Add routes for `Api` to a provided router -fn add_routes(router: &mut Router, api: T) where T: Api + Send + Sync + Clone + 'static { -{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} - let api_clone = api.clone(); - router.{{#vendorExtensions}}{{httpmethod}}{{/vendorExtensions}}( - "{{#vendorExtensions}}{{basePathWithoutHost}}{{path}}{{/vendorExtensions}}", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - {{#hasAuthMethods}} - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - {{#authMethods}} - {{#isOAuth}} - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - {{#scopes}} - "{{scope}}".to_string(), // {{description}} - {{/scopes}} - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - {{/isOAuth}} - {{/authMethods}} - {{/hasAuthMethods}} - -{{#pathParams}}{{#-first}} - // Path parameters -{{/-first}} let param_{{paramName}} = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("{{baseName}}").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter {{baseName}}".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter {{baseName}}: {}", e))))? - }; -{{/pathParams}} -{{#headerParams}}{{#-first}} - // Header parameters -{{/-first}} header! { (Request{{vendorExtensions.typeName}}, "{{baseName}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} } -{{#required}} let param_{{paramName}} = req.headers.get::().ok_or_else(|| Response::with((status::BadRequest, "Missing or invalid required header {{baseName}}".to_string())))?.0.clone(); -{{/required}}{{^required}} let param_{{paramName}} = req.headers.get::().map(|header| header.0.clone()); -{{/required}}{{/headerParams}} -{{#queryParams}}{{#-first}} - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = req.get::().unwrap_or_default(); -{{/-first}} let param_{{paramName}} = query_params.get("{{baseName}}") -{{#required}} .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter {{baseName}}".to_string())))? -{{#isListContainer}} .iter().flat_map(|x| x.parse::<{{{baseType}}}>()).collect::>(); -{{/isListContainer}}{{^isListContainer}} .first().ok_or_else(|| Response::with((status::BadRequest, "Required query parameter {{baseName}} was empty".to_string())))? - .parse::<{{{dataType}}}>().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse query parameter {{baseName}} - doesn't match schema: {}", e))))?; -{{/isListContainer}}{{/required}}{{^required}}{{#isListContainer}} .map(|list| list.iter().flat_map(|x| x.parse::<{{{baseType}}}>()).collect::>()); -{{/isListContainer}}{{^isListContainer}} .and_then(|list| list.first()).and_then(|x| x.parse::<{{{dataType}}}>().ok()); -{{/isListContainer}}{{/required}}{{/queryParams}} -{{#bodyParams}}{{#-first}} // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. -{{/-first}}{{#required}} - let param_{{paramName}} = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter {{baseName}} - not valid UTF-8: {}", e))))?; -{{/required}}{{^required}} - let param_{{paramName}} = req.get::().unwrap_or(None); -{{/required}}{{#vendorExtensions}}{{^consumesPlainText}} - let mut unused_elements = Vec::new(); - - let param_{{paramName}} = if let Some(param_{{paramName}}_raw) = param_{{paramName}} { {{#consumesXml}} - let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(param_{{paramName}}_raw.as_bytes());{{/consumesXml}}{{#consumesJson}} - let deserializer = &mut serde_json::Deserializer::from_str(¶m_{{paramName}}_raw);{{/consumesJson}} - - let param_{{paramName}}: Option<{{{dataType}}}> = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }){{#required}}.map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter {{baseName}} - doesn't match schema: {}", e))))?{{/required}}{{^required}}.unwrap_or(None){{/required}}; - - param_{{paramName}} - } else { - None - };{{/consumesPlainText}}{{/vendorExtensions}}{{#required}} - let param_{{paramName}} = param_{{paramName}}.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter {{baseName}}".to_string())))?{{/required}}; - -{{/bodyParams}} -{{#formParams}} - {{#-first}} - // Form parameters -{{/-first}}{{/formParams}}{{#vendorExtensions}}{{#hasFile}} - // Expecting a multipart form, extract and parse it now. - let mut entries = match Multipart::from_request(req) { - Ok(mut multipart) => { - - match multipart.save().temp() { - SaveResult::Full(entries) => { - Ok(entries) - }, - _ => { - Err(Response::with((status::InternalServerError, format!("Unable to process all message parts")))) - }, - } - }, - Err(e) => { - // Unable to parse as multipart - Err(Response::with((status::BadRequest, format!("Couldn't parse body as multipart")))) - } - }?; - -{{/hasFile}}{{/vendorExtensions}}{{#allParams}}{{#isFormParam}}{{#isFile}} - - let param_{{paramName}} = entries.fields.remove("{{paramName}}"); - - let param_{{paramName}} = match param_{{paramName}} { - Some(body) => { - Ok({let bytes = body.as_bytes(); - {{^required}}Some({{/required}} - Box::new(stream::once(Ok(bytes.to_vec()))) as Box, Error=Error> + Send> - {{^required}}){{/required}}} - ) - } - None => {Err(Response::with((status::BadRequest, format!("Body part not found!"))))} - }?; -{{/isFile}} - let param_{{paramName}} = {{#isFile}}{{^required}}Box::new(future::ok({{/required}}param_{{paramName}}{{^required}})){{/required}};{{/isFile}}{{^isFile}}{{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}}{{/isFile}} - {{/isFormParam}} -{{/allParams}} - - match api.{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}param_{{paramName}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}}context).wait() { - Ok(rsp) => match rsp { -{{#responses}} - {{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{#dataType}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body{{/-first}}{{/headers}}{{/dataType}}{{#headers}}{{#-first}}{{^dataType}}{ {{/dataType}}{{#dataType}}, {{/dataType}}{{/-first}}{{^-first}}, {{/-first}}{{name}}{{#-last}} }{{/-last}}{{/headers}} => { -{{^isFile}} -{{#dataType}}{{#vendorExtensions}}{{#producesPlainText}} let body_string = body; -{{/producesPlainText}}{{#producesXml}} -{{^has_namespace}} let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");{{/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(), models::namespaces::{{uppercase_data_type}}.clone()); - let body_string = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize");{{/has_namespace}}{{/producesXml}}{{#producesJson}} - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize");{{/producesJson}}{{/vendorExtensions}}{{/dataType}} - - let mut response = Response::with((status::Status::from_u16({{code}}){{#dataType}}, body_string{{/dataType}}));{{/isFile}}{{#isFile}} body.fold(Vec::new(), |mut body, chunk| { - body.extend(chunk.iter()); - future::ok::, Error>(body) - }) - - // Block whilst waiting for the stream to complete - .wait() - - // It's possible that errors were received in the stream, if this is the case then we can't return a success response to the client and instead must return an internal error. - .map_err(|_| Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - - // Assuming no errors then create an Iron response. - .map(|rsp| { - let mut response = Response::new(); - response.status = Some(status::Status::from_u16({{code}})); - response.body = Some(Box::new(rsp)); -{{/isFile}} -{{#headers}}{{#isFile}} {{/isFile}} header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{datatype}}}] } -{{#isFile}} {{/isFile}} response.headers.set(Response{{nameInCamelCase}}({{name}})); -{{/headers}} - {{#produces}}{{#-first}} -{{#dataType}}{{#isFile}} {{/isFile}} response.headers.set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone()));{{/dataType}} -{{/-first}}{{/produces}} -{{#isFile}} {{/isFile}} context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); -{{#bodyParams}}{{#vendorExtensions}}{{^consumesPlainText}} if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - }{{/consumesPlainText}}{{/vendorExtensions}}{{/bodyParams}} - {{^isFile}}Ok(response){{/isFile}}{{#isFile}} response - }){{/isFile}} - }, -{{/responses}} - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "{{operationId}}"); -{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} -} - -/// Middleware to extract authentication data from request -pub struct ExtractAuthData; - -impl BeforeMiddleware for ExtractAuthData { - fn before(&self, req: &mut Request) -> IronResult<()> { - {{#authMethods}} - {{#isBasic}} - { - use hyper::header::{Authorization, Basic, Bearer}; - use std::ops::Deref; - if let Some(basic) = req.headers.get::>() { - req.extensions.insert::(AuthData::Basic(basic.deref().clone())); - return Ok(()); - } - } - {{/isBasic}} - {{#isOAuth}} - { - use hyper::header::{Authorization, Basic, Bearer}; - use std::ops::Deref; - if let Some(bearer) = req.headers.get::>() { - req.extensions.insert::(AuthData::Bearer(bearer.deref().clone())); - return Ok(()); - } - } - {{/isOAuth}} - {{#isApiKey}} - {{#isKeyInHeader}} - { - header! { (ApiKey{{-index}}, "{{keyParamName}}") => [String] } - if let Some(header) = req.headers.get::() { - req.extensions.insert::(AuthData::ApiKey(header.0.clone())); - return Ok(()); - } - } - {{/isKeyInHeader}} - {{#isKeyInQuery}} - { - let header = match req.get_ref::() { - Ok(query) => query.get("{{keyParamName}}").map(|v| v[0].clone()), - _ => None - }; - if let Some(key) = header { - req.extensions.insert::(AuthData::ApiKey(key)); - return Ok(()); - } - } - {{/isKeyInQuery}} - {{/isApiKey}} - {{/authMethods}} - - Ok(()) - } -} diff --git a/modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml b/modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml index bf15aa2900f..e56c581f22f 100644 --- a/modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml +++ b/modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml @@ -471,7 +471,7 @@ paths: X-Expires-After: type: string format: date-time - description: date in UTC when toekn expires + description: date in UTC when token expires '400': description: Invalid username/password supplied /user/logout: @@ -919,6 +919,24 @@ paths: responses: '200': description: successful operation + /fake/body-with-query-params: + put: + operationId: testBodyWithQueryParams + parameters: + - name: body + in: body + required: true + schema: + $ref: '#/definitions/User' + - name: query + in: query + required: true + type: string + consumes: + - application/json + responses: + '200': + description: Success /another-fake/dummy: patch: tags: diff --git a/samples/client/petstore/rust2/examples/server_lib/server.rs b/samples/client/petstore/rust2/examples/server_lib/server.rs deleted file mode 100644 index 17ed199a74e..00000000000 --- a/samples/client/petstore/rust2/examples/server_lib/server.rs +++ /dev/null @@ -1,294 +0,0 @@ -//! Server implementation of petstore_api. - -#![allow(unused_imports)] - -use futures::{self, Future}; -use chrono; -use futures::Stream; -use std::collections::HashMap; -use std::io::Error; -use swagger; - -use petstore_api::{Api, ApiError, Context, - TestSpecialTagsResponse, - GetXmlFeaturesResponse, - PostPlainTextResponse, - PostXmlFeaturesResponse, - PutPlainTextResponse, - FakeOuterBooleanSerializeResponse, - FakeOuterCompositeSerializeResponse, - FakeOuterNumberSerializeResponse, - FakeOuterStringSerializeResponse, - TestClientModelResponse, - TestEndpointParametersResponse, - TestEnumParametersResponse, - TestJsonFormDataResponse, - TestClassnameResponse, - AddPetResponse, - DeletePetResponse, - FindPetsByStatusResponse, - FindPetsByTagsResponse, - GetPetByIdResponse, - UpdatePetResponse, - UpdatePetWithFormResponse, - UploadFileResponse, - DeleteOrderResponse, - GetInventoryResponse, - GetOrderByIdResponse, - PlaceOrderResponse, - CreateUserResponse, - CreateUsersWithArrayInputResponse, - CreateUsersWithListInputResponse, - DeleteUserResponse, - GetUserByNameResponse, - LoginUserResponse, - LogoutUserResponse, - UpdateUserResponse -}; -use petstore_api::models; - -#[derive(Copy, Clone)] -pub struct Server; - -impl Api for Server { - - /// To test special tags - fn test_special_tags(&self, body: models::Client, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("test_special_tags({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Get some XML - fn get_xml_features(&self, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("get_xml_features() - X-Span-ID: {:?}", context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Post some plaintext - fn post_plain_text(&self, message: String, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("post_plain_text(\"{}\") - X-Span-ID: {:?}", message, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Post some xml - fn post_xml_features(&self, xml_object: models::XmlObject, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("post_xml_features({:?}) - X-Span-ID: {:?}", xml_object, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Put some optional plaintext - fn put_plain_text(&self, message: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("put_plain_text({:?}) - X-Span-ID: {:?}", message, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - - fn fake_outer_boolean_serialize(&self, body: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("fake_outer_boolean_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - - fn fake_outer_composite_serialize(&self, body: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("fake_outer_composite_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - - fn fake_outer_number_serialize(&self, body: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("fake_outer_number_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - - fn fake_outer_string_serialize(&self, body: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("fake_outer_string_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// To test \"client\" model - fn test_client_model(&self, body: models::Client, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("test_client_model({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("test_endpoint_parameters({}, {}, \"{}\", \"{:?}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// To test enum parameters - fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_form_string_array, enum_form_string, enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// test json serialization of form data - fn test_json_form_data(&self, param: String, param2: String, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("test_json_form_data(\"{}\", \"{}\") - X-Span-ID: {:?}", param, param2, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// To test class name in snake case - fn test_classname(&self, body: models::Client, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("test_classname({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Add a new pet to the store - fn add_pet(&self, body: models::Pet, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("add_pet({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Deletes a pet - fn delete_pet(&self, pet_id: i64, api_key: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("delete_pet({}, {:?}) - X-Span-ID: {:?}", pet_id, api_key, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Finds Pets by status - fn find_pets_by_status(&self, status: &Vec, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("find_pets_by_status({:?}) - X-Span-ID: {:?}", status, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Finds Pets by tags - fn find_pets_by_tags(&self, tags: &Vec, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("find_pets_by_tags({:?}) - X-Span-ID: {:?}", tags, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Find pet by ID - fn get_pet_by_id(&self, pet_id: i64, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("get_pet_by_id({}) - X-Span-ID: {:?}", pet_id, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Update an existing pet - fn update_pet(&self, body: models::Pet, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("update_pet({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Updates a pet in the store with form data - fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("update_pet_with_form({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, name, status, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// uploads an image - fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("upload_file({}, {:?}, ) - X-Span-ID: {:?}", pet_id, additional_metadata, context.x_span_id.unwrap_or(String::from("")).clone()); - let _ = file; //Suppresses unused param warning - Box::new(futures::failed("Generic failure".into())) - } - - /// Delete purchase order by ID - fn delete_order(&self, order_id: String, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("delete_order(\"{}\") - X-Span-ID: {:?}", order_id, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Returns pet inventories by status - fn get_inventory(&self, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("get_inventory() - X-Span-ID: {:?}", context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Find purchase order by ID - fn get_order_by_id(&self, order_id: i64, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("get_order_by_id({}) - X-Span-ID: {:?}", order_id, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Place an order for a pet - fn place_order(&self, body: models::Order, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("place_order({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Create user - fn create_user(&self, body: models::User, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("create_user({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Creates list of users with given input array - fn create_users_with_array_input(&self, body: &Vec, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("create_users_with_array_input({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Creates list of users with given input array - fn create_users_with_list_input(&self, body: &Vec, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("create_users_with_list_input({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Delete user - fn delete_user(&self, username: String, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("delete_user(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Get user by user name - fn get_user_by_name(&self, username: String, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("get_user_by_name(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Logs user into the system - fn login_user(&self, username: String, password: String, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("login_user(\"{}\", \"{}\") - X-Span-ID: {:?}", username, password, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Logs out current logged in user session - fn logout_user(&self, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("logout_user() - X-Span-ID: {:?}", context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - - /// Updated user - fn update_user(&self, username: String, body: models::User, context: &Context) -> Box + Send> { - let context = context.clone(); - println!("update_user(\"{}\", {:?}) - X-Span-ID: {:?}", username, body, context.x_span_id.unwrap_or(String::from("")).clone()); - Box::new(futures::failed("Generic failure".into())) - } - -} diff --git a/samples/server/petstore/rust-server/.swagger-codegen/VERSION b/samples/server/petstore/rust-server/.swagger-codegen/VERSION index cc6612c36e0..855ff9501eb 100644 --- a/samples/server/petstore/rust-server/.swagger-codegen/VERSION +++ b/samples/server/petstore/rust-server/.swagger-codegen/VERSION @@ -1 +1 @@ -2.3.0 \ No newline at end of file +2.4.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/rust-server/Cargo.toml b/samples/server/petstore/rust-server/Cargo.toml index f44d3cc5916..9725e6790a1 100644 --- a/samples/server/petstore/rust-server/Cargo.toml +++ b/samples/server/petstore/rust-server/Cargo.toml @@ -7,32 +7,37 @@ license = "Unlicense" [features] default = ["client", "server"] -client = ["serde_json", "serde-xml-rs", "serde_ignored", "hyper", "hyper-openssl", "uuid", "multipart"] -server = ["serde_json", "serde-xml-rs", "serde_ignored", "hyper", "iron", "router", "bodyparser", "urlencoded", "uuid", "multipart"] +client = ["serde_json", "serde_urlencoded", "serde-xml-rs", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid", "multipart"] +server = ["serde_json", "serde-xml-rs", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid", "multipart"] [dependencies] # Required by example server. # chrono = { version = "0.4", features = ["serde"] } futures = "0.1" -hyper = {version = "0.10", optional = true} -hyper-openssl = {version = "0.2", optional = true } -iron = {version = "0.5", optional = true} -swagger = "0.7" +hyper = {version = "0.11", optional = true} +hyper-tls = {version = "0.1.2", optional = true} +swagger = "0.9" # Not required by example server. # -bodyparser = {version = "0.7", optional = true} -url = "1.5" lazy_static = "0.2" log = "0.3.0" -multipart = {version = "0.13", optional = true} -router = {version = "0.5", optional = true} +mime = "0.3.3" +multipart = {version = "0.13.3", optional = true} +native-tls = {version = "0.1.4", optional = true} +openssl = {version = "0.9.14", optional = true} +percent-encoding = {version = "1.0.0", optional = true} +regex = {version = "0.2", optional = true} serde = "1.0" serde_derive = "1.0" serde_ignored = {version = "0.0.4", optional = true} serde_json = {version = "1.0", optional = true} -urlencoded = {version = "0.5", optional = true} +serde_urlencoded = {version = "0.5.1", optional = true} +tokio-core = {version = "0.1.6", optional = true} +tokio-proto = {version = "0.1.1", optional = true} +tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]} +url = {version = "1.5", optional = true} uuid = {version = "0.5", optional = true, features = ["serde", "v4"]} # ToDo: this should be updated to point at the official crate once # https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream diff --git a/samples/server/petstore/rust-server/README.md b/samples/server/petstore/rust-server/README.md index f8bdb0ab4d1..ef6c5119a7f 100644 --- a/samples/server/petstore/rust-server/README.md +++ b/samples/server/petstore/rust-server/README.md @@ -13,7 +13,7 @@ To see how to make this your own, look here: [README](https://github.com/swagger-api/swagger-codegen/blob/master/README.md) - API version: 1.0.0 -- Build date: 2018-01-07T09:31:52.377-08:00 +- Build date: 2018-02-06T14:00:33.084Z This autogenerated project defines an API crate `petstore_api` which contains: * An `Api` trait defining the API in Rust. diff --git a/samples/server/petstore/rust-server/api/swagger.yaml b/samples/server/petstore/rust-server/api/swagger.yaml index 128267b767d..ac262f706ac 100644 --- a/samples/server/petstore/rust-server/api/swagger.yaml +++ b/samples/server/petstore/rust-server/api/swagger.yaml @@ -70,8 +70,9 @@ paths: operation_id: "add_pet" uppercase_operation_id: "ADD_PET" path: "/pet" + PATH_ID: "PET" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" noClientExample: true put: tags: @@ -122,8 +123,9 @@ paths: operation_id: "update_pet" uppercase_operation_id: "UPDATE_PET" path: "/pet" + PATH_ID: "PET" + hasPathParams: false HttpMethod: "Put" - httpmethod: "put" noClientExample: true /pet/findByStatus: get: @@ -175,8 +177,9 @@ paths: operation_id: "find_pets_by_status" uppercase_operation_id: "FIND_PETS_BY_STATUS" path: "/pet/findByStatus" + PATH_ID: "PET_FINDBYSTATUS" + hasPathParams: false HttpMethod: "Get" - httpmethod: "get" /pet/findByTags: get: tags: @@ -224,8 +227,9 @@ paths: operation_id: "find_pets_by_tags" uppercase_operation_id: "FIND_PETS_BY_TAGS" path: "/pet/findByTags" + PATH_ID: "PET_FINDBYTAGS" + hasPathParams: false HttpMethod: "Get" - httpmethod: "get" /pet/{petId}: get: tags: @@ -270,8 +274,9 @@ paths: operation_id: "get_pet_by_id" uppercase_operation_id: "GET_PET_BY_ID" path: "/pet/:petId" + PATH_ID: "PET_PETID" + hasPathParams: true HttpMethod: "Get" - httpmethod: "get" post: tags: - "pet" @@ -319,8 +324,9 @@ paths: operation_id: "update_pet_with_form" uppercase_operation_id: "UPDATE_PET_WITH_FORM" path: "/pet/:petId" + PATH_ID: "PET_PETID" + hasPathParams: true HttpMethod: "Post" - httpmethod: "post" delete: tags: - "pet" @@ -358,8 +364,9 @@ paths: operation_id: "delete_pet" uppercase_operation_id: "DELETE_PET" path: "/pet/:petId" + PATH_ID: "PET_PETID" + hasPathParams: true HttpMethod: "Delete" - httpmethod: "delete" /pet/{petId}/uploadImage: post: tags: @@ -413,8 +420,9 @@ paths: operation_id: "upload_file" uppercase_operation_id: "UPLOAD_FILE" path: "/pet/:petId/uploadImage" + PATH_ID: "PET_PETID_UPLOADIMAGE" + hasPathParams: true HttpMethod: "Post" - httpmethod: "post" hasFile: true /store/inventory: get: @@ -444,8 +452,9 @@ paths: operation_id: "get_inventory" uppercase_operation_id: "GET_INVENTORY" path: "/store/inventory" + PATH_ID: "STORE_INVENTORY" + hasPathParams: false HttpMethod: "Get" - httpmethod: "get" /store/order: post: tags: @@ -488,8 +497,9 @@ paths: operation_id: "place_order" uppercase_operation_id: "PLACE_ORDER" path: "/store/order" + PATH_ID: "STORE_ORDER" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" noClientExample: true /store/order/{order_id}: get: @@ -536,8 +546,9 @@ paths: operation_id: "get_order_by_id" uppercase_operation_id: "GET_ORDER_BY_ID" path: "/store/order/:order_id" + PATH_ID: "STORE_ORDER_ORDER_ID" + hasPathParams: true HttpMethod: "Get" - httpmethod: "get" delete: tags: - "store" @@ -570,8 +581,9 @@ paths: operation_id: "delete_order" uppercase_operation_id: "DELETE_ORDER" path: "/store/order/:order_id" + PATH_ID: "STORE_ORDER_ORDER_ID" + hasPathParams: true HttpMethod: "Delete" - httpmethod: "delete" /user: post: tags: @@ -605,8 +617,9 @@ paths: operation_id: "create_user" uppercase_operation_id: "CREATE_USER" path: "/user" + PATH_ID: "USER" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" noClientExample: true /user/createWithArray: post: @@ -641,8 +654,9 @@ paths: operation_id: "create_users_with_array_input" uppercase_operation_id: "CREATE_USERS_WITH_ARRAY_INPUT" path: "/user/createWithArray" + PATH_ID: "USER_CREATEWITHARRAY" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" /user/createWithList: post: tags: @@ -676,8 +690,9 @@ paths: operation_id: "create_users_with_list_input" uppercase_operation_id: "CREATE_USERS_WITH_LIST_INPUT" path: "/user/createWithList" + PATH_ID: "USER_CREATEWITHLIST" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" /user/login: get: tags: @@ -716,7 +731,7 @@ paths: X-Expires-After: type: "string" format: "date-time" - description: "date in UTC when toekn expires" + description: "date in UTC when token expires" x-responseId: "SuccessfulOperation" x-uppercaseResponseId: "SUCCESSFUL_OPERATION" uppercase_operation_id: "LOGIN_USER" @@ -730,8 +745,9 @@ paths: operation_id: "login_user" uppercase_operation_id: "LOGIN_USER" path: "/user/login" + PATH_ID: "USER_LOGIN" + hasPathParams: false HttpMethod: "Get" - httpmethod: "get" /user/logout: get: tags: @@ -752,8 +768,9 @@ paths: operation_id: "logout_user" uppercase_operation_id: "LOGOUT_USER" path: "/user/logout" + PATH_ID: "USER_LOGOUT" + hasPathParams: false HttpMethod: "Get" - httpmethod: "get" /user/{username}: get: tags: @@ -795,8 +812,9 @@ paths: operation_id: "get_user_by_name" uppercase_operation_id: "GET_USER_BY_NAME" path: "/user/:username" + PATH_ID: "USER_USERNAME" + hasPathParams: true HttpMethod: "Get" - httpmethod: "get" put: tags: - "user" @@ -841,8 +859,9 @@ paths: operation_id: "update_user" uppercase_operation_id: "UPDATE_USER" path: "/user/:username" + PATH_ID: "USER_USERNAME" + hasPathParams: true HttpMethod: "Put" - httpmethod: "put" noClientExample: true delete: tags: @@ -875,8 +894,9 @@ paths: operation_id: "delete_user" uppercase_operation_id: "DELETE_USER" path: "/user/:username" + PATH_ID: "USER_USERNAME" + hasPathParams: true HttpMethod: "Delete" - httpmethod: "delete" /fake_classname_test: patch: tags: @@ -916,8 +936,9 @@ paths: operation_id: "test_classname" uppercase_operation_id: "TEST_CLASSNAME" path: "/fake_classname_test" + PATH_ID: "FAKE_CLASSNAME_TEST" + hasPathParams: false HttpMethod: "Patch" - httpmethod: "patch" noClientExample: true /fake: get: @@ -1042,8 +1063,9 @@ paths: operation_id: "test_enum_parameters" uppercase_operation_id: "TEST_ENUM_PARAMETERS" path: "/fake" + PATH_ID: "FAKE" + hasPathParams: false HttpMethod: "Get" - httpmethod: "get" post: tags: - "fake" @@ -1195,8 +1217,9 @@ paths: operation_id: "test_endpoint_parameters" uppercase_operation_id: "TEST_ENDPOINT_PARAMETERS" path: "/fake" + PATH_ID: "FAKE" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" patch: tags: - "fake" @@ -1234,8 +1257,9 @@ paths: operation_id: "test_client_model" uppercase_operation_id: "TEST_CLIENT_MODEL" path: "/fake" + PATH_ID: "FAKE" + hasPathParams: false HttpMethod: "Patch" - httpmethod: "patch" noClientExample: true /fake/outer/number: post: @@ -1270,8 +1294,9 @@ paths: operation_id: "fake_outer_number_serialize" uppercase_operation_id: "FAKE_OUTER_NUMBER_SERIALIZE" path: "/fake/outer/number" + PATH_ID: "FAKE_OUTER_NUMBER" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" /fake/outer/string: post: tags: @@ -1305,8 +1330,9 @@ paths: operation_id: "fake_outer_string_serialize" uppercase_operation_id: "FAKE_OUTER_STRING_SERIALIZE" path: "/fake/outer/string" + PATH_ID: "FAKE_OUTER_STRING" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" /fake/outer/boolean: post: tags: @@ -1340,8 +1366,9 @@ paths: operation_id: "fake_outer_boolean_serialize" uppercase_operation_id: "FAKE_OUTER_BOOLEAN_SERIALIZE" path: "/fake/outer/boolean" + PATH_ID: "FAKE_OUTER_BOOLEAN" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" /fake/outer/composite: post: tags: @@ -1375,8 +1402,9 @@ paths: operation_id: "fake_outer_composite_serialize" uppercase_operation_id: "FAKE_OUTER_COMPOSITE_SERIALIZE" path: "/fake/outer/composite" + PATH_ID: "FAKE_OUTER_COMPOSITE" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" /fake/jsonFormData: get: tags: @@ -1410,8 +1438,9 @@ paths: operation_id: "test_json_form_data" uppercase_operation_id: "TEST_JSON_FORM_DATA" path: "/fake/jsonFormData" + PATH_ID: "FAKE_JSONFORMDATA" + hasPathParams: false HttpMethod: "Get" - httpmethod: "get" /fake/inline-additionalProperties: post: tags: @@ -1446,8 +1475,46 @@ paths: operation_id: "test_inline_additional_properties" uppercase_operation_id: "TEST_INLINE_ADDITIONAL_PROPERTIES" path: "/fake/inline-additionalProperties" + PATH_ID: "FAKE_INLINE_ADDITIONALPROPERTIES" + hasPathParams: false HttpMethod: "Post" - httpmethod: "post" + noClientExample: true + /fake/body-with-query-params: + put: + operationId: "testBodyWithQueryParams" + consumes: + - "application/json" + parameters: + - in: "body" + name: "body" + required: true + schema: + $ref: "#/definitions/User" + uppercase_data_type: "USER" + refName: "User" + formatString: "{:?}" + example: "???" + model_key: "OuterBoolean" + uppercase_operation_id: "TEST_BODY_WITH_QUERY_PARAMS" + consumesJson: true + - name: "query" + in: "query" + required: true + type: "string" + formatString: "\\\"{}\\\"" + example: "\"query_example\".to_string()" + responses: + 200: + description: "Success" + x-responseId: "Success" + x-uppercaseResponseId: "SUCCESS" + uppercase_operation_id: "TEST_BODY_WITH_QUERY_PARAMS" + operation_id: "test_body_with_query_params" + uppercase_operation_id: "TEST_BODY_WITH_QUERY_PARAMS" + path: "/fake/body-with-query-params" + PATH_ID: "FAKE_BODY_WITH_QUERY_PARAMS" + hasPathParams: false + HttpMethod: "Put" noClientExample: true /another-fake/dummy: patch: @@ -1487,8 +1554,9 @@ paths: operation_id: "test_special_tags" uppercase_operation_id: "TEST_SPECIAL_TAGS" path: "/another-fake/dummy" + PATH_ID: "ANOTHER_FAKE_DUMMY" + hasPathParams: false HttpMethod: "Patch" - httpmethod: "patch" noClientExample: true securityDefinitions: petstore_auth: diff --git a/samples/server/petstore/rust-server/examples/client.rs b/samples/server/petstore/rust-server/examples/client.rs index e0bb1d1bc97..2b2f69d1179 100644 --- a/samples/server/petstore/rust-server/examples/client.rs +++ b/samples/server/petstore/rust-server/examples/client.rs @@ -8,13 +8,16 @@ extern crate swagger; #[allow(unused_extern_crates)] extern crate uuid; extern crate clap; +extern crate tokio_core; #[allow(unused_imports)] use futures::{Future, future, Stream, stream}; +use tokio_core::reactor; #[allow(unused_imports)] use petstore_api::{ApiNoContext, ContextWrapperExt, ApiError, TestSpecialTagsResponse, + TestBodyWithQueryParamsResponse, FakeOuterBooleanSerializeResponse, FakeOuterCompositeSerializeResponse, FakeOuterNumberSerializeResponse, @@ -93,18 +96,19 @@ fn main() { .help("Port to contact")) .get_matches(); + let mut core = reactor::Core::new().unwrap(); let is_https = matches.is_present("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if is_https { + let client = if matches.is_present("https") { // Using Simple HTTPS - petstore_api::Client::try_new_https(&base_url, "examples/ca.pem") + petstore_api::Client::try_new_https(core.handle(), &base_url, "examples/ca.pem") .expect("Failed to create HTTPS client") } else { // Using HTTP - petstore_api::Client::try_new_http(&base_url) + petstore_api::Client::try_new_http(core.handle(), &base_url) .expect("Failed to create HTTP client") }; @@ -115,165 +119,171 @@ fn main() { // Disabled because there's no example. // Some("TestSpecialTags") => { - // let result = client.test_special_tags(???).wait(); + // let result = core.run(client.test_special_tags(???)); + // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); + // }, + + // Disabled because there's no example. + // Some("TestBodyWithQueryParams") => { + // let result = core.run(client.test_body_with_query_params(???, "query_example".to_string())); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, Some("FakeOuterBooleanSerialize") => { - let result = client.fake_outer_boolean_serialize(None).wait(); + let result = core.run(client.fake_outer_boolean_serialize(None)); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("FakeOuterCompositeSerialize") => { - let result = client.fake_outer_composite_serialize(None).wait(); + let result = core.run(client.fake_outer_composite_serialize(None)); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("FakeOuterNumberSerialize") => { - let result = client.fake_outer_number_serialize(None).wait(); + let result = core.run(client.fake_outer_number_serialize(None)); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("FakeOuterStringSerialize") => { - let result = client.fake_outer_string_serialize(None).wait(); + let result = core.run(client.fake_outer_string_serialize(None)); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, // Disabled because there's no example. // Some("TestClientModel") => { - // let result = client.test_client_model(???).wait(); + // let result = core.run(client.test_client_model(???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, Some("TestEndpointParameters") => { - let result = client.test_endpoint_parameters(8.14, 1.2, "pattern_without_delimiter_example".to_string(), swagger::ByteArray(Vec::from("B")), Some(56), Some(56), Some(789), Some(3.4), Some("string_example".to_string()), Some(swagger::ByteArray(Vec::from("B"))), None, None, Some("password_example".to_string()), Some("callback_example".to_string())).wait(); + let result = core.run(client.test_endpoint_parameters(8.14, 1.2, "pattern_without_delimiter_example".to_string(), swagger::ByteArray(Vec::from("B")), Some(56), Some(56), Some(789), Some(3.4), Some("string_example".to_string()), Some(swagger::ByteArray(Vec::from("B"))), None, None, Some("password_example".to_string()), Some("callback_example".to_string()))); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("TestEnumParameters") => { - let result = client.test_enum_parameters(Some(&Vec::new()), Some("enum_form_string_example".to_string()), Some(&Vec::new()), Some("enum_header_string_example".to_string()), Some(&Vec::new()), Some("enum_query_string_example".to_string()), Some(56), Some(1.2)).wait(); + let result = core.run(client.test_enum_parameters(Some(&Vec::new()), Some("enum_form_string_example".to_string()), Some(&Vec::new()), Some("enum_header_string_example".to_string()), Some(&Vec::new()), Some("enum_query_string_example".to_string()), Some(56), Some(1.2))); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, // Disabled because there's no example. // Some("TestInlineAdditionalProperties") => { - // let result = client.test_inline_additional_properties(???).wait(); + // let result = core.run(client.test_inline_additional_properties(???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, Some("TestJsonFormData") => { - let result = client.test_json_form_data("param_example".to_string(), "param2_example".to_string()).wait(); + let result = core.run(client.test_json_form_data("param_example".to_string(), "param2_example".to_string())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, // Disabled because there's no example. // Some("TestClassname") => { - // let result = client.test_classname(???).wait(); + // let result = core.run(client.test_classname(???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, // Disabled because there's no example. // Some("AddPet") => { - // let result = client.add_pet(???).wait(); + // let result = core.run(client.add_pet(???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, Some("DeletePet") => { - let result = client.delete_pet(789, Some("api_key_example".to_string())).wait(); + let result = core.run(client.delete_pet(789, Some("api_key_example".to_string()))); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("FindPetsByStatus") => { - let result = client.find_pets_by_status(&Vec::new()).wait(); + let result = core.run(client.find_pets_by_status(&Vec::new())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("FindPetsByTags") => { - let result = client.find_pets_by_tags(&Vec::new()).wait(); + let result = core.run(client.find_pets_by_tags(&Vec::new())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("GetPetById") => { - let result = client.get_pet_by_id(789).wait(); + let result = core.run(client.get_pet_by_id(789)); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, // Disabled because there's no example. // Some("UpdatePet") => { - // let result = client.update_pet(???).wait(); + // let result = core.run(client.update_pet(???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, Some("UpdatePetWithForm") => { - let result = client.update_pet_with_form(789, Some("name_example".to_string()), Some("status_example".to_string())).wait(); + let result = core.run(client.update_pet_with_form(789, Some("name_example".to_string()), Some("status_example".to_string()))); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("UploadFile") => { - let result = client.upload_file(789, Some("additional_metadata_example".to_string()), Box::new(future::ok(Some(Box::new(stream::once(Ok(b"hello".to_vec()))) as Box + Send>))) as Box + Send>).wait(); + let result = core.run(client.upload_file(789, Some("additional_metadata_example".to_string()), Box::new(future::ok(Some(Box::new(stream::once(Ok(b"hello".to_vec()))) as Box + Send>))) as Box + Send>)); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("DeleteOrder") => { - let result = client.delete_order("order_id_example".to_string()).wait(); + let result = core.run(client.delete_order("order_id_example".to_string())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("GetInventory") => { - let result = client.get_inventory().wait(); + let result = core.run(client.get_inventory()); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("GetOrderById") => { - let result = client.get_order_by_id(789).wait(); + let result = core.run(client.get_order_by_id(789)); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, // Disabled because there's no example. // Some("PlaceOrder") => { - // let result = client.place_order(???).wait(); + // let result = core.run(client.place_order(???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, // Disabled because there's no example. // Some("CreateUser") => { - // let result = client.create_user(???).wait(); + // let result = core.run(client.create_user(???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, Some("CreateUsersWithArrayInput") => { - let result = client.create_users_with_array_input(&Vec::new()).wait(); + let result = core.run(client.create_users_with_array_input(&Vec::new())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("CreateUsersWithListInput") => { - let result = client.create_users_with_list_input(&Vec::new()).wait(); + let result = core.run(client.create_users_with_list_input(&Vec::new())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("DeleteUser") => { - let result = client.delete_user("username_example".to_string()).wait(); + let result = core.run(client.delete_user("username_example".to_string())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("GetUserByName") => { - let result = client.get_user_by_name("username_example".to_string()).wait(); + let result = core.run(client.get_user_by_name("username_example".to_string())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("LoginUser") => { - let result = client.login_user("username_example".to_string(), "password_example".to_string()).wait(); + let result = core.run(client.login_user("username_example".to_string(), "password_example".to_string())); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, Some("LogoutUser") => { - let result = client.logout_user().wait(); + let result = core.run(client.logout_user()); println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); }, // Disabled because there's no example. // Some("UpdateUser") => { - // let result = client.update_user("username_example".to_string(), ???).wait(); + // let result = core.run(client.update_user("username_example".to_string(), ???)); // println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from(""))); // }, diff --git a/samples/server/petstore/rust-server/examples/server.rs b/samples/server/petstore/rust-server/examples/server.rs index 85fe5c16c0d..65b48aced82 100644 --- a/samples/server/petstore/rust-server/examples/server.rs +++ b/samples/server/petstore/rust-server/examples/server.rs @@ -6,8 +6,11 @@ // extern crate ; extern crate petstore_api; extern crate swagger; -extern crate iron; -extern crate hyper_openssl; +extern crate hyper; +extern crate openssl; +extern crate native_tls; +extern crate tokio_proto; +extern crate tokio_tls; extern crate clap; // Imports required by server library. @@ -18,18 +21,19 @@ extern crate chrono; #[macro_use] extern crate error_chain; -use hyper_openssl::OpensslServer; -use hyper_openssl::openssl::x509::X509_FILETYPE_PEM; -use hyper_openssl::openssl::ssl::{SslAcceptorBuilder, SslMethod}; -use hyper_openssl::openssl::error::ErrorStack; + +use openssl::x509::X509_FILETYPE_PEM; +use openssl::ssl::{SslAcceptorBuilder, SslMethod}; +use openssl::error::ErrorStack; +use hyper::server::Http; +use tokio_proto::TcpServer; use clap::{App, Arg}; -use iron::{Iron, Chain}; -use swagger::auth::AllowAllMiddleware; +use swagger::auth::AllowAllAuthenticator; mod server_lib; -/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -fn ssl() -> Result { +// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +fn ssl() -> Result { let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?; // Server authentication @@ -37,7 +41,7 @@ fn ssl() -> Result { ssl.set_certificate_chain_file("examples/server-chain.pem")?; ssl.check_private_key()?; - Ok(OpensslServer::from(ssl.build())) + Ok(ssl) } /// Create custom server, wire it to the autogenerated router, @@ -49,20 +53,22 @@ fn main() { .help("Whether to use HTTPS or not")) .get_matches(); - let server = server_lib::server().unwrap(); - let router = petstore_api::router(server); - - let mut chain = Chain::new(router); - chain.link_before(petstore_api::server::ExtractAuthData); - // add authentication middlewares into the chain here - // for the purpose of this example, pretend we have authenticated a user - chain.link_before(AllowAllMiddleware::new("cosmo")); + let service_fn = + petstore_api::server::auth::NewService::new( + AllowAllAuthenticator::new( + server_lib::NewService, + "cosmo" + ) + ); + let addr = "127.0.0.1:80".parse().expect("Failed to parse bind address"); if matches.is_present("https") { - // Using Simple HTTPS - Iron::new(chain).https("localhost:80", ssl().expect("Failed to load SSL keys")).expect("Failed to start HTTPS server"); + let ssl = ssl().expect("Failed to load SSL keys"); + let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl); + let tls_acceptor = builder.build().expect("Failed to build TLS acceptor"); + TcpServer::new(tokio_tls::proto::Server::new(Http::new(), tls_acceptor), addr).serve(service_fn); } else { // Using HTTP - Iron::new(chain).http("localhost:80").expect("Failed to start HTTP server"); + TcpServer::new(Http::new(), addr).serve(service_fn); } } diff --git a/samples/server/petstore/rust-server/examples/server_lib/mod.rs b/samples/server/petstore/rust-server/examples/server_lib/mod.rs index 31964faedbe..ac79dc722b5 100644 --- a/samples/server/petstore/rust-server/examples/server_lib/mod.rs +++ b/samples/server/petstore/rust-server/examples/server_lib/mod.rs @@ -7,8 +7,20 @@ mod errors { } pub use self::errors::*; +use std::io; +use hyper; +use petstore_api; -/// Instantiate a new server. -pub fn server() -> Result { - Ok(server::Server {}) +pub struct NewService; + +impl hyper::server::NewService for NewService { + type Request = (hyper::Request, petstore_api::Context); + type Response = hyper::Response; + type Error = hyper::Error; + type Instance = petstore_api::server::Service; + + /// Instantiate a new server. + fn new_service(&self) -> io::Result { + Ok(petstore_api::server::Service::new(server::Server)) + } } diff --git a/samples/server/petstore/rust-server/examples/server_lib/server.rs b/samples/server/petstore/rust-server/examples/server_lib/server.rs index 54b01504c61..bb3a045dcbc 100644 --- a/samples/server/petstore/rust-server/examples/server_lib/server.rs +++ b/samples/server/petstore/rust-server/examples/server_lib/server.rs @@ -7,10 +7,12 @@ use chrono; use futures::Stream; use std::collections::HashMap; use std::io::Error; + use swagger; use petstore_api::{Api, ApiError, Context, TestSpecialTagsResponse, + TestBodyWithQueryParamsResponse, FakeOuterBooleanSerializeResponse, FakeOuterCompositeSerializeResponse, FakeOuterNumberSerializeResponse, @@ -50,133 +52,140 @@ pub struct Server; impl Api for Server { /// To test special tags - fn test_special_tags(&self, body: models::Client, context: &Context) -> Box + Send> { + fn test_special_tags(&self, body: models::Client, context: &Context) -> Box> { let context = context.clone(); println!("test_special_tags({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn fake_outer_boolean_serialize(&self, body: Option, context: &Context) -> Box + Send> { + fn test_body_with_query_params(&self, body: models::User, query: String, context: &Context) -> Box> { + let context = context.clone(); + println!("test_body_with_query_params({:?}, \"{}\") - X-Span-ID: {:?}", body, query, context.x_span_id.unwrap_or(String::from("")).clone()); + Box::new(futures::failed("Generic failure".into())) + } + + + fn fake_outer_boolean_serialize(&self, body: Option, context: &Context) -> Box> { let context = context.clone(); println!("fake_outer_boolean_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn fake_outer_composite_serialize(&self, body: Option, context: &Context) -> Box + Send> { + fn fake_outer_composite_serialize(&self, body: Option, context: &Context) -> Box> { let context = context.clone(); println!("fake_outer_composite_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn fake_outer_number_serialize(&self, body: Option, context: &Context) -> Box + Send> { + fn fake_outer_number_serialize(&self, body: Option, context: &Context) -> Box> { let context = context.clone(); println!("fake_outer_number_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn fake_outer_string_serialize(&self, body: Option, context: &Context) -> Box + Send> { + fn fake_outer_string_serialize(&self, body: Option, context: &Context) -> Box> { let context = context.clone(); println!("fake_outer_string_serialize({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// To test \"client\" model - fn test_client_model(&self, body: models::Client, context: &Context) -> Box + Send> { + fn test_client_model(&self, body: models::Client, context: &Context) -> Box> { let context = context.clone(); println!("test_client_model({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option, context: &Context) -> Box + Send> { + fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option, context: &Context) -> Box> { let context = context.clone(); println!("test_endpoint_parameters({}, {}, \"{}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// To test enum parameters - fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option, context: &Context) -> Box + Send> { + fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option, context: &Context) -> Box> { let context = context.clone(); println!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_form_string_array, enum_form_string, enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// test inline additionalProperties - fn test_inline_additional_properties(&self, param: object, context: &Context) -> Box + Send> { + fn test_inline_additional_properties(&self, param: object, context: &Context) -> Box> { let context = context.clone(); println!("test_inline_additional_properties({:?}) - X-Span-ID: {:?}", param, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// test json serialization of form data - fn test_json_form_data(&self, param: String, param2: String, context: &Context) -> Box + Send> { + fn test_json_form_data(&self, param: String, param2: String, context: &Context) -> Box> { let context = context.clone(); println!("test_json_form_data(\"{}\", \"{}\") - X-Span-ID: {:?}", param, param2, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// To test class name in snake case - fn test_classname(&self, body: models::Client, context: &Context) -> Box + Send> { + fn test_classname(&self, body: models::Client, context: &Context) -> Box> { let context = context.clone(); println!("test_classname({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Add a new pet to the store - fn add_pet(&self, body: models::Pet, context: &Context) -> Box + Send> { + fn add_pet(&self, body: models::Pet, context: &Context) -> Box> { let context = context.clone(); println!("add_pet({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Deletes a pet - fn delete_pet(&self, pet_id: i64, api_key: Option, context: &Context) -> Box + Send> { + fn delete_pet(&self, pet_id: i64, api_key: Option, context: &Context) -> Box> { let context = context.clone(); println!("delete_pet({}, {:?}) - X-Span-ID: {:?}", pet_id, api_key, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Finds Pets by status - fn find_pets_by_status(&self, status: &Vec, context: &Context) -> Box + Send> { + fn find_pets_by_status(&self, status: &Vec, context: &Context) -> Box> { let context = context.clone(); println!("find_pets_by_status({:?}) - X-Span-ID: {:?}", status, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Finds Pets by tags - fn find_pets_by_tags(&self, tags: &Vec, context: &Context) -> Box + Send> { + fn find_pets_by_tags(&self, tags: &Vec, context: &Context) -> Box> { let context = context.clone(); println!("find_pets_by_tags({:?}) - X-Span-ID: {:?}", tags, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Find pet by ID - fn get_pet_by_id(&self, pet_id: i64, context: &Context) -> Box + Send> { + fn get_pet_by_id(&self, pet_id: i64, context: &Context) -> Box> { let context = context.clone(); println!("get_pet_by_id({}) - X-Span-ID: {:?}", pet_id, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Update an existing pet - fn update_pet(&self, body: models::Pet, context: &Context) -> Box + Send> { + fn update_pet(&self, body: models::Pet, context: &Context) -> Box> { let context = context.clone(); println!("update_pet({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Updates a pet in the store with form data - fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option, context: &Context) -> Box + Send> { + fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option, context: &Context) -> Box> { let context = context.clone(); println!("update_pet_with_form({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, name, status, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// uploads an image - fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>, context: &Context) -> Box + Send> { + fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>, context: &Context) -> Box> { let context = context.clone(); println!("upload_file({}, {:?}, ) - X-Span-ID: {:?}", pet_id, additional_metadata, context.x_span_id.unwrap_or(String::from("")).clone()); let _ = file; //Suppresses unused param warning @@ -184,84 +193,84 @@ impl Api for Server { } /// Delete purchase order by ID - fn delete_order(&self, order_id: String, context: &Context) -> Box + Send> { + fn delete_order(&self, order_id: String, context: &Context) -> Box> { let context = context.clone(); println!("delete_order(\"{}\") - X-Span-ID: {:?}", order_id, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Returns pet inventories by status - fn get_inventory(&self, context: &Context) -> Box + Send> { + fn get_inventory(&self, context: &Context) -> Box> { let context = context.clone(); println!("get_inventory() - X-Span-ID: {:?}", context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Find purchase order by ID - fn get_order_by_id(&self, order_id: i64, context: &Context) -> Box + Send> { + fn get_order_by_id(&self, order_id: i64, context: &Context) -> Box> { let context = context.clone(); println!("get_order_by_id({}) - X-Span-ID: {:?}", order_id, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Place an order for a pet - fn place_order(&self, body: models::Order, context: &Context) -> Box + Send> { + fn place_order(&self, body: models::Order, context: &Context) -> Box> { let context = context.clone(); println!("place_order({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Create user - fn create_user(&self, body: models::User, context: &Context) -> Box + Send> { + fn create_user(&self, body: models::User, context: &Context) -> Box> { let context = context.clone(); println!("create_user({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Creates list of users with given input array - fn create_users_with_array_input(&self, body: &Vec, context: &Context) -> Box + Send> { + fn create_users_with_array_input(&self, body: &Vec, context: &Context) -> Box> { let context = context.clone(); println!("create_users_with_array_input({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Creates list of users with given input array - fn create_users_with_list_input(&self, body: &Vec, context: &Context) -> Box + Send> { + fn create_users_with_list_input(&self, body: &Vec, context: &Context) -> Box> { let context = context.clone(); println!("create_users_with_list_input({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Delete user - fn delete_user(&self, username: String, context: &Context) -> Box + Send> { + fn delete_user(&self, username: String, context: &Context) -> Box> { let context = context.clone(); println!("delete_user(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Get user by user name - fn get_user_by_name(&self, username: String, context: &Context) -> Box + Send> { + fn get_user_by_name(&self, username: String, context: &Context) -> Box> { let context = context.clone(); println!("get_user_by_name(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Logs user into the system - fn login_user(&self, username: String, password: String, context: &Context) -> Box + Send> { + fn login_user(&self, username: String, password: String, context: &Context) -> Box> { let context = context.clone(); println!("login_user(\"{}\", \"{}\") - X-Span-ID: {:?}", username, password, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Logs out current logged in user session - fn logout_user(&self, context: &Context) -> Box + Send> { + fn logout_user(&self, context: &Context) -> Box> { let context = context.clone(); println!("logout_user() - X-Span-ID: {:?}", context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) } /// Updated user - fn update_user(&self, username: String, body: models::User, context: &Context) -> Box + Send> { + fn update_user(&self, username: String, body: models::User, context: &Context) -> Box> { let context = context.clone(); println!("update_user(\"{}\", {:?}) - X-Span-ID: {:?}", username, body, context.x_span_id.unwrap_or(String::from("")).clone()); Box::new(futures::failed("Generic failure".into())) diff --git a/samples/server/petstore/rust-server/src/client.rs b/samples/server/petstore/rust-server/src/client.rs deleted file mode 100644 index 648ba2dd3b3..00000000000 --- a/samples/server/petstore/rust-server/src/client.rs +++ /dev/null @@ -1,1992 +0,0 @@ -#![allow(unused_extern_crates)] -extern crate hyper_openssl; -extern crate chrono; -extern crate url; -extern crate multipart; - -use multipart::client::lazy::Multipart; -use hyper; -use hyper::client::IntoUrl; -use hyper::mime; -use hyper::header::{Headers, ContentType}; -use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value}; -use hyper::Url; -use self::hyper_openssl::openssl; -use self::url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; -use futures; -use futures::{Future, Stream}; -use futures::{future, stream}; -use std::borrow::Cow; -use std::io::{Read, Error}; -use std::error; -use std::fmt; -use std::path::Path; -use std::sync::Arc; -use std::str; - -use mimetypes; - -use serde_json; -use serde_xml_rs; - -#[allow(unused_imports)] -use std::collections::{HashMap, BTreeMap}; -#[allow(unused_imports)] -use swagger; - -use swagger::{Context, ApiError, XSpanId}; - -use {Api, - TestSpecialTagsResponse, - FakeOuterBooleanSerializeResponse, - FakeOuterCompositeSerializeResponse, - FakeOuterNumberSerializeResponse, - FakeOuterStringSerializeResponse, - TestClientModelResponse, - TestEndpointParametersResponse, - TestEnumParametersResponse, - TestInlineAdditionalPropertiesResponse, - TestJsonFormDataResponse, - TestClassnameResponse, - AddPetResponse, - DeletePetResponse, - FindPetsByStatusResponse, - FindPetsByTagsResponse, - GetPetByIdResponse, - UpdatePetResponse, - UpdatePetWithFormResponse, - UploadFileResponse, - DeleteOrderResponse, - GetInventoryResponse, - GetOrderByIdResponse, - PlaceOrderResponse, - CreateUserResponse, - CreateUsersWithArrayInputResponse, - CreateUsersWithListInputResponse, - DeleteUserResponse, - GetUserByNameResponse, - LoginUserResponse, - LogoutUserResponse, - UpdateUserResponse - }; -use models; - -/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. -fn into_base_path(input: T, correct_scheme: Option<&'static str>) -> Result { - // First convert to Url, since a base path is a subset of Url. - let url = input.into_url()?; - - let scheme = url.scheme(); - - // Check the scheme if necessary - if let Some(correct_scheme) = correct_scheme { - if scheme != correct_scheme { - return Err(ClientInitError::InvalidScheme); - } - } - - let host = url.host().ok_or_else(|| ClientInitError::MissingHost)?; - let port = url.port().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}", scheme, host, port)) -} - -/// A client that implements the API by making HTTP calls out to a server. -#[derive(Clone)] -pub struct Client { - base_path: String, - hyper_client: Arc hyper::client::Client + Sync + Send>, -} - -impl fmt::Debug for Client { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Client {{ base_path: {} }}", self.base_path) - } -} - -impl Client { - pub fn try_new_http(base_path: T) -> Result - where T: IntoUrl - { - Ok(Client { - base_path: into_base_path(base_path, Some("http"))?, - hyper_client: Arc::new(hyper::client::Client::new), - }) - } - - pub fn try_new_https(base_path: T, - ca_certificate: CA) - -> Result - where T: IntoUrl, - CA: AsRef - { - let ca_certificate = ca_certificate.as_ref().to_owned(); - - let https_hyper_client = move || { - // SSL implementation - let mut ssl = openssl::ssl::SslConnectorBuilder::new(openssl::ssl::SslMethod::tls()).unwrap(); - - // Server authentication - ssl.set_ca_file(ca_certificate.clone()).unwrap(); - - let ssl = hyper_openssl::OpensslClient::from(ssl.build()); - let connector = hyper::net::HttpsConnector::new(ssl); - hyper::client::Client::with_connector(connector) - }; - - Ok(Client { - base_path: into_base_path(base_path, Some("https"))?, - hyper_client: Arc::new(https_hyper_client), - }) - } - - pub fn try_new_https_mutual(base_path: T, - ca_certificate: CA, - client_key: K, - client_certificate: C) - -> Result - where T: IntoUrl, - CA: AsRef, - K: AsRef, - C: AsRef - { - let ca_certificate = ca_certificate.as_ref().to_owned(); - let client_key = client_key.as_ref().to_owned(); - let client_certificate = client_certificate.as_ref().to_owned(); - - let https_mutual_hyper_client = move || { - // SSL implementation - let mut ssl = openssl::ssl::SslConnectorBuilder::new(openssl::ssl::SslMethod::tls()).unwrap(); - - // Server authentication - ssl.set_ca_file(ca_certificate.clone()).unwrap(); - - // Client authentication - ssl.set_private_key_file(client_key.clone(), openssl::x509::X509_FILETYPE_PEM).unwrap(); - ssl.set_certificate_chain_file(client_certificate.clone()).unwrap(); - ssl.check_private_key().unwrap(); - - let ssl = hyper_openssl::OpensslClient::from(ssl.build()); - let connector = hyper::net::HttpsConnector::new(ssl); - hyper::client::Client::with_connector(connector) - }; - - Ok(Client { - base_path: into_base_path(base_path, Some("https"))?, - hyper_client: Arc::new(https_mutual_hyper_client) - }) - } - - /// Constructor for creating a `Client` by passing in a pre-made `hyper` client. - /// - /// One should avoid relying on this function if possible, since it adds a dependency on the underlying transport - /// implementation, which it would be better to abstract away. Therefore, using this function may lead to a loss of - /// code generality, which may make it harder to move the application to a serverless environment, for example. - /// - /// The reason for this function's existence is to support legacy test code, which did mocking at the hyper layer. - /// This is not a recommended way to write new tests. If other reasons are found for using this function, they - /// should be mentioned here. - pub fn try_new_with_hyper_client(base_path: T, - hyper_client: Arc hyper::client::Client + Sync + Send>) - -> Result - where T: IntoUrl - { - Ok(Client { - base_path: into_base_path(base_path, None)?, - hyper_client: hyper_client - }) - } -} - -impl Api for Client { - - fn test_special_tags(&self, param_body: models::Client, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/another-fake/dummy", - self.base_path - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Patch, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::TEST_SPECIAL_TAGS.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(TestSpecialTagsResponse::SuccessfulOperation(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn fake_outer_boolean_serialize(&self, param_body: Option, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake/outer/boolean", - self.base_path - ); - - let body = param_body.map(|ref body| { - - serde_json::to_string(body).expect("impossible to fail to serialize") - }); - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = match body { - Some(ref body) => request.body(body), - None => request, - }; - - custom_headers.set(ContentType(mimetypes::requests::FAKE_OUTER_BOOLEAN_SERIALIZE.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(FakeOuterBooleanSerializeResponse::OutputBoolean(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn fake_outer_composite_serialize(&self, param_body: Option, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake/outer/composite", - self.base_path - ); - - let body = param_body.map(|ref body| { - - serde_json::to_string(body).expect("impossible to fail to serialize") - }); - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = match body { - Some(ref body) => request.body(body), - None => request, - }; - - custom_headers.set(ContentType(mimetypes::requests::FAKE_OUTER_COMPOSITE_SERIALIZE.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(FakeOuterCompositeSerializeResponse::OutputComposite(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn fake_outer_number_serialize(&self, param_body: Option, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake/outer/number", - self.base_path - ); - - let body = param_body.map(|ref body| { - - serde_json::to_string(body).expect("impossible to fail to serialize") - }); - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = match body { - Some(ref body) => request.body(body), - None => request, - }; - - custom_headers.set(ContentType(mimetypes::requests::FAKE_OUTER_NUMBER_SERIALIZE.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(FakeOuterNumberSerializeResponse::OutputNumber(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn fake_outer_string_serialize(&self, param_body: Option, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake/outer/string", - self.base_path - ); - - let body = param_body.map(|ref body| { - - serde_json::to_string(body).expect("impossible to fail to serialize") - }); - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = match body { - Some(ref body) => request.body(body), - None => request, - }; - - custom_headers.set(ContentType(mimetypes::requests::FAKE_OUTER_STRING_SERIALIZE.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(FakeOuterStringSerializeResponse::OutputString(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn test_client_model(&self, param_body: models::Client, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake", - self.base_path - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Patch, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::TEST_CLIENT_MODEL.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(TestClientModelResponse::SuccessfulOperation(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn test_endpoint_parameters(&self, param_number: f64, param_double: f64, param_pattern_without_delimiter: String, param_byte: swagger::ByteArray, param_integer: Option, param_int32: Option, param_int64: Option, param_float: Option, param_string: Option, param_binary: Option, param_date: Option>, param_date_time: Option>, param_password: Option, param_callback: Option, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake", - self.base_path - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 400 => { - - - Ok(TestEndpointParametersResponse::InvalidUsernameSupplied) - }, - 404 => { - - - Ok(TestEndpointParametersResponse::UserNotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn test_enum_parameters(&self, param_enum_form_string_array: Option<&Vec>, param_enum_form_string: Option, param_enum_header_string_array: Option<&Vec>, param_enum_header_string: Option, param_enum_query_string_array: Option<&Vec>, param_enum_query_string: Option, param_enum_query_integer: Option, param_enum_query_double: Option, context: &Context) -> Box + Send> { - - // Query parameters - let query_enum_query_string_array = param_enum_query_string_array.map_or_else(String::new, |query| format!("enum_query_string_array={enum_query_string_array}&", enum_query_string_array=query.join(","))); - let query_enum_query_string = param_enum_query_string.map_or_else(String::new, |query| format!("enum_query_string={enum_query_string}&", enum_query_string=query.to_string())); - let query_enum_query_integer = param_enum_query_integer.map_or_else(String::new, |query| format!("enum_query_integer={enum_query_integer}&", enum_query_integer=query.to_string())); - - - let url = format!( - "{}/v2/fake?{enum_query_string_array}{enum_query_string}{enum_query_integer}", - self.base_path, - enum_query_string_array=utf8_percent_encode(&query_enum_query_string_array, QUERY_ENCODE_SET), - enum_query_string=utf8_percent_encode(&query_enum_query_string, QUERY_ENCODE_SET), - enum_query_integer=utf8_percent_encode(&query_enum_query_integer, QUERY_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - // Header parameters - header! { (RequestEnumHeaderStringArray, "enum_header_string_array") => (String)* } - param_enum_header_string_array.map(|header| custom_headers.set(RequestEnumHeaderStringArray(header.clone()))); - header! { (RequestEnumHeaderString, "enum_header_string") => [String] } - param_enum_header_string.map(|header| custom_headers.set(RequestEnumHeaderString(header))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 400 => { - - - Ok(TestEnumParametersResponse::InvalidRequest) - }, - 404 => { - - - Ok(TestEnumParametersResponse::NotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn test_inline_additional_properties(&self, param_param: object, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake/inline-additionalProperties", - self.base_path - ); - - - let body = serde_json::to_string(¶m_param).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::TEST_INLINE_ADDITIONAL_PROPERTIES.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - - - Ok(TestInlineAdditionalPropertiesResponse::SuccessfulOperation) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn test_json_form_data(&self, param_param: String, param_param2: String, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake/jsonFormData", - self.base_path - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - - - Ok(TestJsonFormDataResponse::SuccessfulOperation) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn test_classname(&self, param_body: models::Client, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/fake_classname_test", - self.base_path - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Patch, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::TEST_CLASSNAME.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(TestClassnameResponse::SuccessfulOperation(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn add_pet(&self, param_body: models::Pet, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/pet", - self.base_path - ); - - - let body = serde_xml_rs::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::ADD_PET.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 405 => { - - - Ok(AddPetResponse::InvalidInput) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn delete_pet(&self, param_pet_id: i64, param_api_key: Option, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/pet/{petId}", - self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Delete, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - // Header parameters - header! { (RequestApiKey, "api_key") => [String] } - param_api_key.map(|header| custom_headers.set(RequestApiKey(header))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 400 => { - - - Ok(DeletePetResponse::InvalidPetValue) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn find_pets_by_status(&self, param_status: &Vec, context: &Context) -> Box + Send> { - - // Query parameters - let query_status = format!("status={status}&", status=param_status.join(",")); - - - let url = format!( - "{}/v2/pet/findByStatus?{status}", - self.base_path, - status=utf8_percent_encode(&query_status, QUERY_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - // 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 - let body = serde_xml_rs::from_str::>(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; - - Ok(FindPetsByStatusResponse::SuccessfulOperation(body)) - }, - 400 => { - - - Ok(FindPetsByStatusResponse::InvalidStatusValue) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn find_pets_by_tags(&self, param_tags: &Vec, context: &Context) -> Box + Send> { - - // Query parameters - let query_tags = format!("tags={tags}&", tags=param_tags.join(",")); - - - let url = format!( - "{}/v2/pet/findByTags?{tags}", - self.base_path, - tags=utf8_percent_encode(&query_tags, QUERY_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - // 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 - let body = serde_xml_rs::from_str::>(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; - - Ok(FindPetsByTagsResponse::SuccessfulOperation(body)) - }, - 400 => { - - - Ok(FindPetsByTagsResponse::InvalidTagValue) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn get_pet_by_id(&self, param_pet_id: i64, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/pet/{petId}", - self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - // 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 - let body = serde_xml_rs::from_str::(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; - - Ok(GetPetByIdResponse::SuccessfulOperation(body)) - }, - 400 => { - - - Ok(GetPetByIdResponse::InvalidIDSupplied) - }, - 404 => { - - - Ok(GetPetByIdResponse::PetNotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn update_pet(&self, param_body: models::Pet, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/pet", - self.base_path - ); - - - let body = serde_xml_rs::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Put, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::UPDATE_PET.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 400 => { - - - Ok(UpdatePetResponse::InvalidIDSupplied) - }, - 404 => { - - - Ok(UpdatePetResponse::PetNotFound) - }, - 405 => { - - - Ok(UpdatePetResponse::ValidationException) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn update_pet_with_form(&self, param_pet_id: i64, param_name: Option, param_status: Option, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/pet/{petId}", - self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 405 => { - - - Ok(UpdatePetWithFormResponse::InvalidInput) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn upload_file(&self, param_pet_id: i64, param_additional_metadata: Option, param_file: Box, Error=Error> + Send>>, Error=Error> + Send>, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/pet/{petId}/uploadImage", - self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - // Form data body - let mut multipart = Multipart::new(); - - if let Ok(Some(param_file)) = param_file.wait() { - match convert_stream_to_string(param_file) { - Ok(param_file) => { - // Add file to multipart form. - multipart.add_text("file", param_file); - }, - Err(err) => return Box::new(futures::done(Err(err))), - } - } - - let mut fields = match multipart.prepare() { - Ok(fields) => fields, - Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))), - }; - - let mut body_string = String::new(); - let body = fields.to_body().read_to_string(&mut body_string); - let boundary = fields.boundary(); - let multipart_header = Mime(TopLevel::Multipart, SubLevel::FormData, vec![(Attr::Boundary, Value::Ext(boundary.to_string()))]); - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - let request = request.header(ContentType(multipart_header)) - .body(&body_string); - - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::(&buf)?; - - Ok(UploadFileResponse::SuccessfulOperation(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - // Helper function to convert a Stream into a String. The String can then be used to build the HTTP body. - fn convert_stream_to_string(stream: Box, Error=Error> + Send>) -> Result { - - stream.fold(Vec::new(), |mut body, chunk| { - body.extend(chunk.iter()); - future::ok::,Error>(body) - }).wait() - .map_err(|e| ApiError(format!("Unable to fold stream: {}", e))) - .and_then(|body| String::from_utf8(body) - .map_err(|e| ApiError(format!("Failed to convert utf8 stream to String: {}", e)))) - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn delete_order(&self, param_order_id: String, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/store/order/{order_id}", - self.base_path, order_id=utf8_percent_encode(¶m_order_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Delete, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 400 => { - - - Ok(DeleteOrderResponse::InvalidIDSupplied) - }, - 404 => { - - - Ok(DeleteOrderResponse::OrderNotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn get_inventory(&self, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/store/inventory", - self.base_path - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - let body = serde_json::from_str::>(&buf)?; - - Ok(GetInventoryResponse::SuccessfulOperation(body)) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn get_order_by_id(&self, param_order_id: i64, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/store/order/{order_id}", - self.base_path, order_id=utf8_percent_encode(¶m_order_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - // 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 - let body = serde_xml_rs::from_str::(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; - - Ok(GetOrderByIdResponse::SuccessfulOperation(body)) - }, - 400 => { - - - Ok(GetOrderByIdResponse::InvalidIDSupplied) - }, - 404 => { - - - Ok(GetOrderByIdResponse::OrderNotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn place_order(&self, param_body: models::Order, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/store/order", - self.base_path - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::PLACE_ORDER.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - // 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 - let body = serde_xml_rs::from_str::(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; - - Ok(PlaceOrderResponse::SuccessfulOperation(body)) - }, - 400 => { - - - Ok(PlaceOrderResponse::InvalidOrder) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn create_user(&self, param_body: models::User, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/user", - self.base_path - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::CREATE_USER.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 0 => { - - - Ok(CreateUserResponse::SuccessfulOperation) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn create_users_with_array_input(&self, param_body: &Vec, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/user/createWithArray", - self.base_path - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::CREATE_USERS_WITH_ARRAY_INPUT.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 0 => { - - - Ok(CreateUsersWithArrayInputResponse::SuccessfulOperation) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn create_users_with_list_input(&self, param_body: &Vec, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/user/createWithList", - self.base_path - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Post, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::CREATE_USERS_WITH_LIST_INPUT.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 0 => { - - - Ok(CreateUsersWithListInputResponse::SuccessfulOperation) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn delete_user(&self, param_username: String, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/user/{username}", - self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Delete, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 400 => { - - - Ok(DeleteUserResponse::InvalidUsernameSupplied) - }, - 404 => { - - - Ok(DeleteUserResponse::UserNotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn get_user_by_name(&self, param_username: String, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/user/{username}", - self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - // 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 - let body = serde_xml_rs::from_str::(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; - - Ok(GetUserByNameResponse::SuccessfulOperation(body)) - }, - 400 => { - - - Ok(GetUserByNameResponse::InvalidUsernameSupplied) - }, - 404 => { - - - Ok(GetUserByNameResponse::UserNotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn login_user(&self, param_username: String, param_password: String, context: &Context) -> Box + Send> { - - // Query parameters - let query_username = format!("username={username}&", username=param_username.to_string()); - let query_password = format!("password={password}&", password=param_password.to_string()); - - - let url = format!( - "{}/v2/user/login?{username}{password}", - self.base_path, - username=utf8_percent_encode(&query_username, QUERY_ENCODE_SET), - password=utf8_percent_encode(&query_password, QUERY_ENCODE_SET) - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 200 => { - let mut buf = String::new(); - response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; - // 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 - let body = serde_xml_rs::from_str::(&buf) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; - header! { (ResponseXRateLimit, "X-Rate-Limit") => [i32] } - let response_x_rate_limit = response.headers.get::().ok_or_else(|| "Required response header X-Rate-Limit for response 200 was not found.")?; - header! { (ResponseXExpiresAfter, "X-Expires-After") => [chrono::DateTime] } - let response_x_expires_after = response.headers.get::().ok_or_else(|| "Required response header X-Expires-After for response 200 was not found.")?; - - Ok(LoginUserResponse::SuccessfulOperation{ body: body, x_rate_limit: response_x_rate_limit.0.clone(), x_expires_after: response_x_expires_after.0.clone() }) - }, - 400 => { - - - Ok(LoginUserResponse::InvalidUsername) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn logout_user(&self, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/user/logout", - self.base_path - ); - - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Get, &url); - let mut custom_headers = hyper::header::Headers::new(); - - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 0 => { - - - Ok(LogoutUserResponse::SuccessfulOperation) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - - fn update_user(&self, param_username: String, param_body: models::User, context: &Context) -> Box + Send> { - - - let url = format!( - "{}/v2/user/{username}", - self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - - let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - - let hyper_client = (self.hyper_client)(); - let request = hyper_client.request(hyper::method::Method::Put, &url); - let mut custom_headers = hyper::header::Headers::new(); - - let request = request.body(&body); - - custom_headers.set(ContentType(mimetypes::requests::UPDATE_USER.clone())); - context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); - - - let request = request.headers(custom_headers); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn parse_response(mut response: hyper::client::response::Response) -> Result { - match response.status.to_u16() { - 400 => { - - - Ok(UpdateUserResponse::InvalidUserSupplied) - }, - 404 => { - - - Ok(UpdateUserResponse::UserNotFound) - }, - code => { - let mut buf = [0; 100]; - let debug_body = match response.read(&mut buf) { - Ok(len) => match str::from_utf8(&buf[..len]) { - Ok(body) => Cow::from(body), - Err(_) => Cow::from(format!("", &buf[..len].to_vec())), - }, - Err(e) => Cow::from(format!("", e)), - }; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - response.headers, - debug_body))) - } - } - } - - let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); - Box::new(futures::done(result)) - } - -} - -#[derive(Debug)] -pub enum ClientInitError { - InvalidScheme, - InvalidUrl(hyper::error::ParseError), - MissingHost, - SslError(openssl::error::ErrorStack) -} - -impl From for ClientInitError { - fn from(err: hyper::error::ParseError) -> ClientInitError { - ClientInitError::InvalidUrl(err) - } -} - -impl From for ClientInitError { - fn from(err: openssl::error::ErrorStack) -> ClientInitError { - ClientInitError::SslError(err) - } -} - -impl fmt::Display for ClientInitError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - (self as &fmt::Debug).fmt(f) - } -} - -impl error::Error for ClientInitError { - fn description(&self) -> &str { - "Failed to produce a hyper client." - } -} diff --git a/samples/server/petstore/rust-server/src/client/mod.rs b/samples/server/petstore/rust-server/src/client/mod.rs new file mode 100644 index 00000000000..645907ba2d1 --- /dev/null +++ b/samples/server/petstore/rust-server/src/client/mod.rs @@ -0,0 +1,2783 @@ +#![allow(unused_extern_crates)] +extern crate tokio_core; +extern crate native_tls; +extern crate hyper_tls; +extern crate openssl; +extern crate mime; +extern crate chrono; +extern crate url; +extern crate multipart; +extern crate serde_urlencoded; + + +use self::multipart::client::lazy::Multipart; +use hyper; +use hyper::header::{Headers, ContentType}; +use hyper::Uri; +use self::url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; +use futures; +use futures::{Future, Stream}; +use futures::{future, stream}; +use self::tokio_core::reactor::Handle; +use std::borrow::Cow; +use std::io::{Read, Error, ErrorKind}; +use std::error; +use std::fmt; +use std::path::Path; +use std::sync::Arc; +use std::str; +use std::str::FromStr; + +use mimetypes; + +use serde_json; +use serde_xml_rs; + +#[allow(unused_imports)] +use std::collections::{HashMap, BTreeMap}; +#[allow(unused_imports)] +use swagger; + +use swagger::{Context, ApiError, XSpanId}; + +use {Api, + TestSpecialTagsResponse, + TestBodyWithQueryParamsResponse, + FakeOuterBooleanSerializeResponse, + FakeOuterCompositeSerializeResponse, + FakeOuterNumberSerializeResponse, + FakeOuterStringSerializeResponse, + TestClientModelResponse, + TestEndpointParametersResponse, + TestEnumParametersResponse, + TestInlineAdditionalPropertiesResponse, + TestJsonFormDataResponse, + TestClassnameResponse, + AddPetResponse, + DeletePetResponse, + FindPetsByStatusResponse, + FindPetsByTagsResponse, + GetPetByIdResponse, + UpdatePetResponse, + UpdatePetWithFormResponse, + UploadFileResponse, + DeleteOrderResponse, + GetInventoryResponse, + GetOrderByIdResponse, + PlaceOrderResponse, + CreateUserResponse, + CreateUsersWithArrayInputResponse, + CreateUsersWithListInputResponse, + DeleteUserResponse, + GetUserByNameResponse, + LoginUserResponse, + LogoutUserResponse, + UpdateUserResponse + }; +use models; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = Uri::from_str(input)?; + + let scheme = uri.scheme().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or_else(|| ClientInitError::MissingHost)?; + let port = uri.port().map(|x| format!(":{}", x)).unwrap_or_default(); + Ok(format!("{}://{}{}", scheme, host, port)) +} + +/// A client that implements the API by making HTTP calls out to a server. +#[derive(Clone)] +pub struct Client { + hyper_client: Arc Box, Response=hyper::Response, Error=hyper::Error, Future=hyper::client::FutureResponse>> + Sync + Send>, + handle: Arc, + base_path: String, +} + +impl fmt::Debug for Client { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Client { + + /// Create an HTTP client. + /// + /// # Arguments + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + pub fn try_new_http(handle: Handle, base_path: &str) -> Result { + let http_connector = swagger::http_connector(); + Self::try_new_with_connector::( + handle, + base_path, + Some("http"), + http_connector, + ) + } + + /// Create a client with a TLS connection to the server. + /// + /// # Arguments + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + pub fn try_new_https( + handle: Handle, + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = swagger::https_connector(ca_certificate); + Self::try_new_with_connector::>( + handle, + base_path, + Some("https"), + https_connector, + ) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + pub fn try_new_https_mutual( + handle: Handle, + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: C, + ) -> Result + where + CA: AsRef, + K: AsRef, + C: AsRef, + { + let https_connector = + swagger::https_mutual_connector(ca_certificate, client_key, client_certificate); + Self::try_new_with_connector::>( + handle, + base_path, + Some("https"), + https_connector, + ) + } + + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with + /// `swagger::{http_connector, https_connector, https_mutual_connector}`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `handle` - tokio reactor handle to use for execution + /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector_fn` - Function which returns an implementation of `hyper::client::Connect` + pub fn try_new_with_connector( + handle: Handle, + base_path: &str, + protocol: Option<&'static str>, + connector_fn: Box C + Send + Sync>, + ) -> Result + where + C: hyper::client::Connect + hyper::client::Service, + { + let hyper_client = { + move |handle: &Handle| -> Box< + hyper::client::Service< + Request = hyper::Request, + Response = hyper::Response, + Error = hyper::Error, + Future = hyper::client::FutureResponse, + >, + > { + let connector = connector_fn(handle); + Box::new(hyper::Client::configure().connector(connector).build( + handle, + )) + } + }; + + Ok(Client { + hyper_client: Arc::new(hyper_client), + handle: Arc::new(handle), + base_path: into_base_path(base_path, protocol)?, + }) + } + + /// Constructor for creating a `Client` by passing in a pre-made `hyper` client. + /// + /// One should avoid relying on this function if possible, since it adds a dependency on the underlying transport + /// implementation, which it would be better to abstract away. Therefore, using this function may lead to a loss of + /// code generality, which may make it harder to move the application to a serverless environment, for example. + /// + /// The reason for this function's existence is to support legacy test code, which did mocking at the hyper layer. + /// This is not a recommended way to write new tests. If other reasons are found for using this function, they + /// should be mentioned here. + pub fn try_new_with_hyper_client(hyper_client: Arc Box, Response=hyper::Response, Error=hyper::Error, Future=hyper::client::FutureResponse>> + Sync + Send>, + handle: Handle, + base_path: &str) + -> Result + { + Ok(Client { + hyper_client: hyper_client, + handle: Arc::new(handle), + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Api for Client { + + fn test_special_tags(&self, param_body: models::Client, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/another-fake/dummy", + self.base_path + ); + + 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::Patch, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_SPECIAL_TAGS.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + TestSpecialTagsResponse::SuccessfulOperation(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 test_body_with_query_params(&self, param_body: models::User, param_query: String, context: &Context) -> Box> { + + // Query parameters + let query_query = format!("query={query}&", query=param_query.to_string()); + + + let uri = format!( + "{}/v2/fake/body-with-query-params?{query}", + self.base_path, + query=utf8_percent_encode(&query_query, QUERY_ENCODE_SET) + ); + + 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::Put, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_BODY_WITH_QUERY_PARAMS.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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( + + future::ok( + TestBodyWithQueryParamsResponse::Success + ) + ) 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 fake_outer_boolean_serialize(&self, param_body: Option, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake/outer/boolean", + self.base_path + ); + + 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::Post, uri); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + +if let Some(body) = body { + request.set_body(body.into_bytes()); + } + + request.headers_mut().set(ContentType(mimetypes::requests::FAKE_OUTER_BOOLEAN_SERIALIZE.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + FakeOuterBooleanSerializeResponse::OutputBoolean(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 fake_outer_composite_serialize(&self, param_body: Option, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake/outer/composite", + self.base_path + ); + + 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::Post, uri); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + +if let Some(body) = body { + request.set_body(body.into_bytes()); + } + + request.headers_mut().set(ContentType(mimetypes::requests::FAKE_OUTER_COMPOSITE_SERIALIZE.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + FakeOuterCompositeSerializeResponse::OutputComposite(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 fake_outer_number_serialize(&self, param_body: Option, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake/outer/number", + self.base_path + ); + + 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::Post, uri); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + +if let Some(body) = body { + request.set_body(body.into_bytes()); + } + + request.headers_mut().set(ContentType(mimetypes::requests::FAKE_OUTER_NUMBER_SERIALIZE.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + FakeOuterNumberSerializeResponse::OutputNumber(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 fake_outer_string_serialize(&self, param_body: Option, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake/outer/string", + self.base_path + ); + + 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::Post, uri); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + +if let Some(body) = body { + request.set_body(body.into_bytes()); + } + + request.headers_mut().set(ContentType(mimetypes::requests::FAKE_OUTER_STRING_SERIALIZE.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + FakeOuterStringSerializeResponse::OutputString(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 test_client_model(&self, param_body: models::Client, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake", + self.base_path + ); + + 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::Patch, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_CLIENT_MODEL.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + TestClientModelResponse::SuccessfulOperation(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 test_endpoint_parameters(&self, param_number: f64, param_double: f64, param_pattern_without_delimiter: String, param_byte: swagger::ByteArray, param_integer: Option, param_int32: Option, param_int64: Option, param_float: Option, param_string: Option, param_binary: Option, param_date: Option>, param_date_time: Option>, param_password: Option, param_callback: Option, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake", + self.base_path + ); + + 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::Post, uri); + + let params = &[ + ("integer", param_integer.map(|param| format!("{:?}", param))), + ("int32", param_int32.map(|param| format!("{:?}", param))), + ("int64", param_int64.map(|param| format!("{:?}", param))), + ("number", Some(format!("{:?}", param_number))), + ("float", param_float.map(|param| format!("{:?}", param))), + ("double", Some(format!("{:?}", param_double))), + ("string", param_string), + ("pattern_without_delimiter", Some(param_pattern_without_delimiter)), + ("byte", Some(format!("{:?}", param_byte))), + ("binary", param_binary.map(|param| format!("{:?}", param))), + ("date", param_date.map(|param| format!("{:?}", param))), + ("dateTime", param_date_time.map(|param| format!("{:?}", param))), + ("password", param_password), + ("callback", param_callback), + ]; + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_ENDPOINT_PARAMETERS.clone())); + request.set_body(body.into_bytes()); + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + context.auth_data.as_ref().map(|auth_data| { + if let &swagger::AuthData::Basic(ref basic_header) = auth_data { + request.headers_mut().set(hyper::header::Authorization( + basic_header.clone(), + )) + } + }); + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 400 => { + let body = response.body(); + Box::new( + + future::ok( + TestEndpointParametersResponse::InvalidUsernameSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + TestEndpointParametersResponse::UserNotFound + ) + ) 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 test_enum_parameters(&self, param_enum_form_string_array: Option<&Vec>, param_enum_form_string: Option, param_enum_header_string_array: Option<&Vec>, param_enum_header_string: Option, param_enum_query_string_array: Option<&Vec>, param_enum_query_string: Option, param_enum_query_integer: Option, param_enum_query_double: Option, context: &Context) -> Box> { + + // Query parameters + let query_enum_query_string_array = param_enum_query_string_array.map_or_else(String::new, |query| format!("enum_query_string_array={enum_query_string_array}&", enum_query_string_array=query.join(","))); + let query_enum_query_string = param_enum_query_string.map_or_else(String::new, |query| format!("enum_query_string={enum_query_string}&", enum_query_string=query.to_string())); + let query_enum_query_integer = param_enum_query_integer.map_or_else(String::new, |query| format!("enum_query_integer={enum_query_integer}&", enum_query_integer=query.to_string())); + + + let uri = format!( + "{}/v2/fake?{enum_query_string_array}{enum_query_string}{enum_query_integer}", + self.base_path, + enum_query_string_array=utf8_percent_encode(&query_enum_query_string_array, QUERY_ENCODE_SET), + enum_query_string=utf8_percent_encode(&query_enum_query_string, QUERY_ENCODE_SET), + enum_query_integer=utf8_percent_encode(&query_enum_query_integer, QUERY_ENCODE_SET) + ); + + 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); + + let params = &[ + ("enum_form_string_array", param_enum_form_string_array.map(|param| format!("{:?}", param))), + ("enum_form_string", param_enum_form_string), + ("enum_query_double", param_enum_query_double.map(|param| format!("{:?}", param))), + ]; + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_ENUM_PARAMETERS.clone())); + request.set_body(body.into_bytes()); + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + // Header parameters + header! { (RequestEnumHeaderStringArray, "enum_header_string_array") => (String)* } + param_enum_header_string_array.map(|header| request.headers_mut().set(RequestEnumHeaderStringArray(header.clone()))); + header! { (RequestEnumHeaderString, "enum_header_string") => [String] } + param_enum_header_string.map(|header| request.headers_mut().set(RequestEnumHeaderString(header))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 400 => { + let body = response.body(); + Box::new( + + future::ok( + TestEnumParametersResponse::InvalidRequest + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + TestEnumParametersResponse::NotFound + ) + ) 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 test_inline_additional_properties(&self, param_param: object, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake/inline-additionalProperties", + self.base_path + ); + + 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::Post, uri); + + + let body = serde_json::to_string(¶m_param).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_INLINE_ADDITIONAL_PROPERTIES.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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( + + future::ok( + TestInlineAdditionalPropertiesResponse::SuccessfulOperation + ) + ) 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 test_json_form_data(&self, param_param: String, param_param2: String, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake/jsonFormData", + self.base_path + ); + + 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); + + let params = &[ + ("param", Some(param_param)), + ("param2", Some(param_param2)), + ]; + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_JSON_FORM_DATA.clone())); + request.set_body(body.into_bytes()); + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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( + + future::ok( + TestJsonFormDataResponse::SuccessfulOperation + ) + ) 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 test_classname(&self, param_body: models::Client, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/fake_classname_test", + self.base_path + ); + + 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::Patch, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::TEST_CLASSNAME.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + TestClassnameResponse::SuccessfulOperation(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 add_pet(&self, param_body: models::Pet, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/pet", + self.base_path + ); + + 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::Post, uri); + + + let body = serde_xml_rs::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::ADD_PET.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 405 => { + let body = response.body(); + Box::new( + + future::ok( + AddPetResponse::InvalidInput + ) + ) 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 delete_pet(&self, param_pet_id: i64, param_api_key: Option, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/pet/{petId}", + self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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::Delete, uri); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + // Header parameters + header! { (RequestApiKey, "api_key") => [String] } + param_api_key.map(|header| request.headers_mut().set(RequestApiKey(header))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 400 => { + let body = response.body(); + Box::new( + + future::ok( + DeletePetResponse::InvalidPetValue + ) + ) 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 find_pets_by_status(&self, param_status: &Vec, context: &Context) -> Box> { + + // Query parameters + let query_status = format!("status={status}&", status=param_status.join(",")); + + + let uri = format!( + "{}/v2/pet/findByStatus?{status}", + self.base_path, + status=utf8_percent_encode(&query_status, QUERY_ENCODE_SET) + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + + // 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) + ) + ) as Box> + }, + 400 => { + let body = response.body(); + Box::new( + + future::ok( + FindPetsByStatusResponse::InvalidStatusValue + ) + ) 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 find_pets_by_tags(&self, param_tags: &Vec, context: &Context) -> Box> { + + // Query parameters + let query_tags = format!("tags={tags}&", tags=param_tags.join(",")); + + + let uri = format!( + "{}/v2/pet/findByTags?{tags}", + self.base_path, + tags=utf8_percent_encode(&query_tags, QUERY_ENCODE_SET) + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + + // 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) + ) + ) as Box> + }, + 400 => { + let body = response.body(); + Box::new( + + future::ok( + FindPetsByTagsResponse::InvalidTagValue + ) + ) 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 get_pet_by_id(&self, param_pet_id: i64, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/pet/{petId}", + self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + + // 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) + ) + ) as Box> + }, + 400 => { + let body = response.body(); + Box::new( + + future::ok( + GetPetByIdResponse::InvalidIDSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + GetPetByIdResponse::PetNotFound + ) + ) 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 update_pet(&self, param_body: models::Pet, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/pet", + self.base_path + ); + + 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::Put, uri); + + + let body = serde_xml_rs::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::UPDATE_PET.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 400 => { + let body = response.body(); + Box::new( + + future::ok( + UpdatePetResponse::InvalidIDSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + UpdatePetResponse::PetNotFound + ) + ) as Box> + }, + 405 => { + let body = response.body(); + Box::new( + + future::ok( + UpdatePetResponse::ValidationException + ) + ) 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 update_pet_with_form(&self, param_pet_id: i64, param_name: Option, param_status: Option, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/pet/{petId}", + self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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::Post, uri); + + let params = &[ + ("name", param_name), + ("status", param_status), + ]; + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + request.headers_mut().set(ContentType(mimetypes::requests::UPDATE_PET_WITH_FORM.clone())); + request.set_body(body.into_bytes()); + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 405 => { + let body = response.body(); + Box::new( + + future::ok( + UpdatePetWithFormResponse::InvalidInput + ) + ) 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 upload_file(&self, param_pet_id: i64, param_additional_metadata: Option, param_file: Box, Error=Error> + Send>>, Error=Error> + Send>, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/pet/{petId}/uploadImage", + self.base_path, petId=utf8_percent_encode(¶m_pet_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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::Post, uri); + + // Form data body + let mut multipart = Multipart::new(); + + // Helper function to convert a Stream into a String. The String can then be used to build the HTTP body. + fn convert_stream_to_string(stream: Box, Error=Error> + Send>) -> Result { + + stream.concat2() + .wait() + .map_err(|e| ApiError(format!("Unable to collect stream: {}", e))) + .and_then(|body| String::from_utf8(body) + .map_err(|e| ApiError(format!("Failed to convert utf8 stream to String: {}", e)))) + } + + if let Ok(Some(param_file)) = param_file.wait() { + match convert_stream_to_string(param_file) { + Ok(param_file) => { + // Add file to multipart form. + multipart.add_text("file", param_file); + }, + Err(err) => return Box::new(futures::done(Err(err))), + } + } + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))), + }; + + let mut body_string = String::new(); + let body = fields.to_body().read_to_string(&mut body_string); + let boundary = fields.boundary(); + let multipart_header = match mime::Mime::from_str(&format!("multipart/form-data;boundary={}", boundary)) { + Ok(multipart_header) => multipart_header, + Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build multipart header: {:?}", err))))), + }; + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + request.headers_mut().set(ContentType(multipart_header)); + request.set_body(body_string.into_bytes()); + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + UploadFileResponse::SuccessfulOperation(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 delete_order(&self, param_order_id: String, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/store/order/{order_id}", + self.base_path, order_id=utf8_percent_encode(¶m_order_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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::Delete, uri); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 400 => { + let body = response.body(); + Box::new( + + future::ok( + DeleteOrderResponse::InvalidIDSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + DeleteOrderResponse::OrderNotFound + ) + ) 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 get_inventory(&self, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/store/inventory", + self.base_path + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + GetInventoryResponse::SuccessfulOperation(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 get_order_by_id(&self, param_order_id: i64, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/store/order/{order_id}", + self.base_path, order_id=utf8_percent_encode(¶m_order_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + + // 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) + ) + ) as Box> + }, + 400 => { + let body = response.body(); + Box::new( + + future::ok( + GetOrderByIdResponse::InvalidIDSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + GetOrderByIdResponse::OrderNotFound + ) + ) 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 place_order(&self, param_body: models::Order, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/store/order", + self.base_path + ); + + 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::Post, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::PLACE_ORDER.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + + // 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) + ) + ) as Box> + }, + 400 => { + let body = response.body(); + Box::new( + + future::ok( + PlaceOrderResponse::InvalidOrder + ) + ) 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 create_user(&self, param_body: models::User, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/user", + self.base_path + ); + + 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::Post, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::CREATE_USER.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 0 => { + let body = response.body(); + Box::new( + + future::ok( + CreateUserResponse::SuccessfulOperation + ) + ) 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 create_users_with_array_input(&self, param_body: &Vec, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/user/createWithArray", + self.base_path + ); + + 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::Post, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::CREATE_USERS_WITH_ARRAY_INPUT.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 0 => { + let body = response.body(); + Box::new( + + future::ok( + CreateUsersWithArrayInputResponse::SuccessfulOperation + ) + ) 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 create_users_with_list_input(&self, param_body: &Vec, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/user/createWithList", + self.base_path + ); + + 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::Post, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::CREATE_USERS_WITH_LIST_INPUT.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 0 => { + let body = response.body(); + Box::new( + + future::ok( + CreateUsersWithListInputResponse::SuccessfulOperation + ) + ) 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 delete_user(&self, param_username: String, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/user/{username}", + self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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::Delete, uri); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 400 => { + let body = response.body(); + Box::new( + + future::ok( + DeleteUserResponse::InvalidUsernameSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + DeleteUserResponse::UserNotFound + ) + ) 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 get_user_by_name(&self, param_username: String, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/user/{username}", + self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.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| + + // 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) + ) + ) as Box> + }, + 400 => { + let body = response.body(); + Box::new( + + future::ok( + GetUserByNameResponse::InvalidUsernameSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + GetUserByNameResponse::UserNotFound + ) + ) 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 login_user(&self, param_username: String, param_password: String, context: &Context) -> Box> { + + // Query parameters + let query_username = format!("username={username}&", username=param_username.to_string()); + let query_password = format!("password={password}&", password=param_password.to_string()); + + + let uri = format!( + "{}/v2/user/login?{username}{password}", + self.base_path, + username=utf8_percent_encode(&query_username, QUERY_ENCODE_SET), + password=utf8_percent_encode(&query_password, QUERY_ENCODE_SET) + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 200 => { + header! { (ResponseXRateLimit, "X-Rate-Limit") => [i32] } + let response_x_rate_limit = match response.headers().get::() { + Some(response_x_rate_limit) => response_x_rate_limit.0.clone(), + None => return Box::new(future::err(ApiError(String::from("Required response header X-Rate-Limit for response 200 was not found.")))) as Box>, + }; + header! { (ResponseXExpiresAfter, "X-Expires-After") => [chrono::DateTime] } + let response_x_expires_after = match response.headers().get::() { + Some(response_x_expires_after) => response_x_expires_after.0.clone(), + None => return Box::new(future::err(ApiError(String::from("Required response header X-Expires-After for response 200 was not found.")))) as Box>, + }; + 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| + LoginUserResponse::SuccessfulOperation{ body: body, x_rate_limit: response_x_rate_limit, x_expires_after: response_x_expires_after } + ) + ) as Box> + }, + 400 => { + let body = response.body(); + Box::new( + + future::ok( + LoginUserResponse::InvalidUsername + ) + ) 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 logout_user(&self, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/user/logout", + self.base_path + ); + + 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); + + + + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 0 => { + let body = response.body(); + Box::new( + + future::ok( + LogoutUserResponse::SuccessfulOperation + ) + ) 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 update_user(&self, param_username: String, param_body: models::User, context: &Context) -> Box> { + + + let uri = format!( + "{}/v2/user/{username}", + self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + 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::Put, uri); + + + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + + + request.set_body(body.into_bytes()); + + + request.headers_mut().set(ContentType(mimetypes::requests::UPDATE_USER.clone())); + context.x_span_id.as_ref().map(|header| request.headers_mut().set(XSpanId(header.clone()))); + + + + + let hyper_client = (self.hyper_client)(&*self.handle); + Box::new(hyper_client.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 400 => { + let body = response.body(); + Box::new( + + future::ok( + UpdateUserResponse::InvalidUserSupplied + ) + ) as Box> + }, + 404 => { + let body = response.body(); + Box::new( + + future::ok( + UpdateUserResponse::UserNotFound + ) + ) 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> + } + } + })) + + } + +} + +#[derive(Debug)] +pub enum ClientInitError { + InvalidScheme, + InvalidUri(hyper::error::UriError), + MissingHost, + SslError(openssl::error::ErrorStack) +} + +impl From for ClientInitError { + fn from(err: hyper::error::UriError) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl From for ClientInitError { + fn from(err: openssl::error::ErrorStack) -> ClientInitError { + ClientInitError::SslError(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (self as &fmt::Debug).fmt(f) + } +} + +impl error::Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} diff --git a/samples/server/petstore/rust-server/src/lib.rs b/samples/server/petstore/rust-server/src/lib.rs index d7b80c2f1d1..40f22dc522d 100644 --- a/samples/server/petstore/rust-server/src/lib.rs +++ b/samples/server/petstore/rust-server/src/lib.rs @@ -3,10 +3,10 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; + extern crate serde_xml_rs; extern crate futures; extern crate chrono; -extern crate multipart; #[macro_use] extern crate lazy_static; #[macro_use] @@ -32,6 +32,8 @@ mod mimetypes; pub use swagger::{ApiError, Context, ContextWrapper}; +pub const BASE_PATH: &'static str = "/v2"; + #[derive(Debug, PartialEq)] pub enum TestSpecialTagsResponse { @@ -39,6 +41,12 @@ pub enum TestSpecialTagsResponse { SuccessfulOperation ( models::Client ) , } +#[derive(Debug, PartialEq)] +pub enum TestBodyWithQueryParamsResponse { + /// Success + Success , +} + #[derive(Debug, PartialEq)] pub enum FakeOuterBooleanSerializeResponse { /// Output boolean @@ -258,97 +266,100 @@ pub enum UpdateUserResponse { pub trait Api { /// To test special tags - fn test_special_tags(&self, body: models::Client, context: &Context) -> Box + Send>; + fn test_special_tags(&self, body: models::Client, context: &Context) -> Box>; - fn fake_outer_boolean_serialize(&self, body: Option, context: &Context) -> Box + Send>; + fn test_body_with_query_params(&self, body: models::User, query: String, context: &Context) -> Box>; - fn fake_outer_composite_serialize(&self, body: Option, context: &Context) -> Box + Send>; + fn fake_outer_boolean_serialize(&self, body: Option, context: &Context) -> Box>; - fn fake_outer_number_serialize(&self, body: Option, context: &Context) -> Box + Send>; + fn fake_outer_composite_serialize(&self, body: Option, context: &Context) -> Box>; - fn fake_outer_string_serialize(&self, body: Option, context: &Context) -> Box + Send>; + fn fake_outer_number_serialize(&self, body: Option, context: &Context) -> Box>; + + + fn fake_outer_string_serialize(&self, body: Option, context: &Context) -> Box>; /// To test \"client\" model - fn test_client_model(&self, body: models::Client, context: &Context) -> Box + Send>; + fn test_client_model(&self, body: models::Client, context: &Context) -> Box>; /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option, context: &Context) -> Box + Send>; + fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option, context: &Context) -> Box>; /// To test enum parameters - fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option, context: &Context) -> Box + Send>; + fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option, context: &Context) -> Box>; /// test inline additionalProperties - fn test_inline_additional_properties(&self, param: object, context: &Context) -> Box + Send>; + fn test_inline_additional_properties(&self, param: object, context: &Context) -> Box>; /// test json serialization of form data - fn test_json_form_data(&self, param: String, param2: String, context: &Context) -> Box + Send>; + fn test_json_form_data(&self, param: String, param2: String, context: &Context) -> Box>; /// To test class name in snake case - fn test_classname(&self, body: models::Client, context: &Context) -> Box + Send>; + fn test_classname(&self, body: models::Client, context: &Context) -> Box>; /// Add a new pet to the store - fn add_pet(&self, body: models::Pet, context: &Context) -> Box + Send>; + fn add_pet(&self, body: models::Pet, context: &Context) -> Box>; /// Deletes a pet - fn delete_pet(&self, pet_id: i64, api_key: Option, context: &Context) -> Box + Send>; + fn delete_pet(&self, pet_id: i64, api_key: Option, context: &Context) -> Box>; /// Finds Pets by status - fn find_pets_by_status(&self, status: &Vec, context: &Context) -> Box + Send>; + fn find_pets_by_status(&self, status: &Vec, context: &Context) -> Box>; /// Finds Pets by tags - fn find_pets_by_tags(&self, tags: &Vec, context: &Context) -> Box + Send>; + fn find_pets_by_tags(&self, tags: &Vec, context: &Context) -> Box>; /// Find pet by ID - fn get_pet_by_id(&self, pet_id: i64, context: &Context) -> Box + Send>; + fn get_pet_by_id(&self, pet_id: i64, context: &Context) -> Box>; /// Update an existing pet - fn update_pet(&self, body: models::Pet, context: &Context) -> Box + Send>; + fn update_pet(&self, body: models::Pet, context: &Context) -> Box>; /// Updates a pet in the store with form data - fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option, context: &Context) -> Box + Send>; + fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option, context: &Context) -> Box>; /// uploads an image - fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>, context: &Context) -> Box + Send>; + fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>, context: &Context) -> Box>; /// Delete purchase order by ID - fn delete_order(&self, order_id: String, context: &Context) -> Box + Send>; + fn delete_order(&self, order_id: String, context: &Context) -> Box>; /// Returns pet inventories by status - fn get_inventory(&self, context: &Context) -> Box + Send>; + fn get_inventory(&self, context: &Context) -> Box>; /// Find purchase order by ID - fn get_order_by_id(&self, order_id: i64, context: &Context) -> Box + Send>; + fn get_order_by_id(&self, order_id: i64, context: &Context) -> Box>; /// Place an order for a pet - fn place_order(&self, body: models::Order, context: &Context) -> Box + Send>; + fn place_order(&self, body: models::Order, context: &Context) -> Box>; /// Create user - fn create_user(&self, body: models::User, context: &Context) -> Box + Send>; + fn create_user(&self, body: models::User, context: &Context) -> Box>; /// Creates list of users with given input array - fn create_users_with_array_input(&self, body: &Vec, context: &Context) -> Box + Send>; + fn create_users_with_array_input(&self, body: &Vec, context: &Context) -> Box>; /// Creates list of users with given input array - fn create_users_with_list_input(&self, body: &Vec, context: &Context) -> Box + Send>; + fn create_users_with_list_input(&self, body: &Vec, context: &Context) -> Box>; /// Delete user - fn delete_user(&self, username: String, context: &Context) -> Box + Send>; + fn delete_user(&self, username: String, context: &Context) -> Box>; /// Get user by user name - fn get_user_by_name(&self, username: String, context: &Context) -> Box + Send>; + fn get_user_by_name(&self, username: String, context: &Context) -> Box>; /// Logs user into the system - fn login_user(&self, username: String, password: String, context: &Context) -> Box + Send>; + fn login_user(&self, username: String, password: String, context: &Context) -> Box>; /// Logs out current logged in user session - fn logout_user(&self, context: &Context) -> Box + Send>; + fn logout_user(&self, context: &Context) -> Box>; /// Updated user - fn update_user(&self, username: String, body: models::User, context: &Context) -> Box + Send>; + fn update_user(&self, username: String, body: models::User, context: &Context) -> Box>; } @@ -356,97 +367,100 @@ pub trait Api { pub trait ApiNoContext { /// To test special tags - fn test_special_tags(&self, body: models::Client) -> Box + Send>; + fn test_special_tags(&self, body: models::Client) -> Box>; - fn fake_outer_boolean_serialize(&self, body: Option) -> Box + Send>; + fn test_body_with_query_params(&self, body: models::User, query: String) -> Box>; - fn fake_outer_composite_serialize(&self, body: Option) -> Box + Send>; + fn fake_outer_boolean_serialize(&self, body: Option) -> Box>; - fn fake_outer_number_serialize(&self, body: Option) -> Box + Send>; + fn fake_outer_composite_serialize(&self, body: Option) -> Box>; - fn fake_outer_string_serialize(&self, body: Option) -> Box + Send>; + fn fake_outer_number_serialize(&self, body: Option) -> Box>; + + + fn fake_outer_string_serialize(&self, body: Option) -> Box>; /// To test \"client\" model - fn test_client_model(&self, body: models::Client) -> Box + Send>; + fn test_client_model(&self, body: models::Client) -> Box>; /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option) -> Box + Send>; + fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option) -> Box>; /// To test enum parameters - fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option) -> Box + Send>; + fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option) -> Box>; /// test inline additionalProperties - fn test_inline_additional_properties(&self, param: object) -> Box + Send>; + fn test_inline_additional_properties(&self, param: object) -> Box>; /// test json serialization of form data - fn test_json_form_data(&self, param: String, param2: String) -> Box + Send>; + fn test_json_form_data(&self, param: String, param2: String) -> Box>; /// To test class name in snake case - fn test_classname(&self, body: models::Client) -> Box + Send>; + fn test_classname(&self, body: models::Client) -> Box>; /// Add a new pet to the store - fn add_pet(&self, body: models::Pet) -> Box + Send>; + fn add_pet(&self, body: models::Pet) -> Box>; /// Deletes a pet - fn delete_pet(&self, pet_id: i64, api_key: Option) -> Box + Send>; + fn delete_pet(&self, pet_id: i64, api_key: Option) -> Box>; /// Finds Pets by status - fn find_pets_by_status(&self, status: &Vec) -> Box + Send>; + fn find_pets_by_status(&self, status: &Vec) -> Box>; /// Finds Pets by tags - fn find_pets_by_tags(&self, tags: &Vec) -> Box + Send>; + fn find_pets_by_tags(&self, tags: &Vec) -> Box>; /// Find pet by ID - fn get_pet_by_id(&self, pet_id: i64) -> Box + Send>; + fn get_pet_by_id(&self, pet_id: i64) -> Box>; /// Update an existing pet - fn update_pet(&self, body: models::Pet) -> Box + Send>; + fn update_pet(&self, body: models::Pet) -> Box>; /// Updates a pet in the store with form data - fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option) -> Box + Send>; + fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option) -> Box>; /// uploads an image - fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>) -> Box + Send>; + fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>) -> Box>; /// Delete purchase order by ID - fn delete_order(&self, order_id: String) -> Box + Send>; + fn delete_order(&self, order_id: String) -> Box>; /// Returns pet inventories by status - fn get_inventory(&self) -> Box + Send>; + fn get_inventory(&self) -> Box>; /// Find purchase order by ID - fn get_order_by_id(&self, order_id: i64) -> Box + Send>; + fn get_order_by_id(&self, order_id: i64) -> Box>; /// Place an order for a pet - fn place_order(&self, body: models::Order) -> Box + Send>; + fn place_order(&self, body: models::Order) -> Box>; /// Create user - fn create_user(&self, body: models::User) -> Box + Send>; + fn create_user(&self, body: models::User) -> Box>; /// Creates list of users with given input array - fn create_users_with_array_input(&self, body: &Vec) -> Box + Send>; + fn create_users_with_array_input(&self, body: &Vec) -> Box>; /// Creates list of users with given input array - fn create_users_with_list_input(&self, body: &Vec) -> Box + Send>; + fn create_users_with_list_input(&self, body: &Vec) -> Box>; /// Delete user - fn delete_user(&self, username: String) -> Box + Send>; + fn delete_user(&self, username: String) -> Box>; /// Get user by user name - fn get_user_by_name(&self, username: String) -> Box + Send>; + fn get_user_by_name(&self, username: String) -> Box>; /// Logs user into the system - fn login_user(&self, username: String, password: String) -> Box + Send>; + fn login_user(&self, username: String, password: String) -> Box>; /// Logs out current logged in user session - fn logout_user(&self) -> Box + Send>; + fn logout_user(&self) -> Box>; /// Updated user - fn update_user(&self, username: String, body: models::User) -> Box + Send>; + fn update_user(&self, username: String, body: models::User) -> Box>; } @@ -465,157 +479,162 @@ impl<'a, T: Api + Sized> ContextWrapperExt<'a> for T { impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { /// To test special tags - fn test_special_tags(&self, body: models::Client) -> Box + Send> { + fn test_special_tags(&self, body: models::Client) -> Box> { self.api().test_special_tags(body, &self.context()) } - fn fake_outer_boolean_serialize(&self, body: Option) -> Box + Send> { + fn test_body_with_query_params(&self, body: models::User, query: String) -> Box> { + self.api().test_body_with_query_params(body, query, &self.context()) + } + + + fn fake_outer_boolean_serialize(&self, body: Option) -> Box> { self.api().fake_outer_boolean_serialize(body, &self.context()) } - fn fake_outer_composite_serialize(&self, body: Option) -> Box + Send> { + fn fake_outer_composite_serialize(&self, body: Option) -> Box> { self.api().fake_outer_composite_serialize(body, &self.context()) } - fn fake_outer_number_serialize(&self, body: Option) -> Box + Send> { + fn fake_outer_number_serialize(&self, body: Option) -> Box> { self.api().fake_outer_number_serialize(body, &self.context()) } - fn fake_outer_string_serialize(&self, body: Option) -> Box + Send> { + fn fake_outer_string_serialize(&self, body: Option) -> Box> { self.api().fake_outer_string_serialize(body, &self.context()) } /// To test \"client\" model - fn test_client_model(&self, body: models::Client) -> Box + Send> { + fn test_client_model(&self, body: models::Client) -> Box> { self.api().test_client_model(body, &self.context()) } /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option) -> Box + Send> { + fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option, int32: Option, int64: Option, float: Option, string: Option, binary: Option, date: Option>, date_time: Option>, password: Option, callback: Option) -> Box> { self.api().test_endpoint_parameters(number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, &self.context()) } /// To test enum parameters - fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option) -> Box + Send> { + fn test_enum_parameters(&self, enum_form_string_array: Option<&Vec>, enum_form_string: Option, enum_header_string_array: Option<&Vec>, enum_header_string: Option, enum_query_string_array: Option<&Vec>, enum_query_string: Option, enum_query_integer: Option, enum_query_double: Option) -> Box> { self.api().test_enum_parameters(enum_form_string_array, enum_form_string, enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, &self.context()) } /// test inline additionalProperties - fn test_inline_additional_properties(&self, param: object) -> Box + Send> { + fn test_inline_additional_properties(&self, param: object) -> Box> { self.api().test_inline_additional_properties(param, &self.context()) } /// test json serialization of form data - fn test_json_form_data(&self, param: String, param2: String) -> Box + Send> { + fn test_json_form_data(&self, param: String, param2: String) -> Box> { self.api().test_json_form_data(param, param2, &self.context()) } /// To test class name in snake case - fn test_classname(&self, body: models::Client) -> Box + Send> { + fn test_classname(&self, body: models::Client) -> Box> { self.api().test_classname(body, &self.context()) } /// Add a new pet to the store - fn add_pet(&self, body: models::Pet) -> Box + Send> { + fn add_pet(&self, body: models::Pet) -> Box> { self.api().add_pet(body, &self.context()) } /// Deletes a pet - fn delete_pet(&self, pet_id: i64, api_key: Option) -> Box + Send> { + fn delete_pet(&self, pet_id: i64, api_key: Option) -> Box> { self.api().delete_pet(pet_id, api_key, &self.context()) } /// Finds Pets by status - fn find_pets_by_status(&self, status: &Vec) -> Box + Send> { + fn find_pets_by_status(&self, status: &Vec) -> Box> { self.api().find_pets_by_status(status, &self.context()) } /// Finds Pets by tags - fn find_pets_by_tags(&self, tags: &Vec) -> Box + Send> { + fn find_pets_by_tags(&self, tags: &Vec) -> Box> { self.api().find_pets_by_tags(tags, &self.context()) } /// Find pet by ID - fn get_pet_by_id(&self, pet_id: i64) -> Box + Send> { + fn get_pet_by_id(&self, pet_id: i64) -> Box> { self.api().get_pet_by_id(pet_id, &self.context()) } /// Update an existing pet - fn update_pet(&self, body: models::Pet) -> Box + Send> { + fn update_pet(&self, body: models::Pet) -> Box> { self.api().update_pet(body, &self.context()) } /// Updates a pet in the store with form data - fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option) -> Box + Send> { + fn update_pet_with_form(&self, pet_id: i64, name: Option, status: Option) -> Box> { self.api().update_pet_with_form(pet_id, name, status, &self.context()) } /// uploads an image - fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>) -> Box + Send> { + fn upload_file(&self, pet_id: i64, additional_metadata: Option, file: Box, Error=Error> + Send>>, Error=Error> + Send>) -> Box> { self.api().upload_file(pet_id, additional_metadata, file, &self.context()) } /// Delete purchase order by ID - fn delete_order(&self, order_id: String) -> Box + Send> { + fn delete_order(&self, order_id: String) -> Box> { self.api().delete_order(order_id, &self.context()) } /// Returns pet inventories by status - fn get_inventory(&self) -> Box + Send> { + fn get_inventory(&self) -> Box> { self.api().get_inventory(&self.context()) } /// Find purchase order by ID - fn get_order_by_id(&self, order_id: i64) -> Box + Send> { + fn get_order_by_id(&self, order_id: i64) -> Box> { self.api().get_order_by_id(order_id, &self.context()) } /// Place an order for a pet - fn place_order(&self, body: models::Order) -> Box + Send> { + fn place_order(&self, body: models::Order) -> Box> { self.api().place_order(body, &self.context()) } /// Create user - fn create_user(&self, body: models::User) -> Box + Send> { + fn create_user(&self, body: models::User) -> Box> { self.api().create_user(body, &self.context()) } /// Creates list of users with given input array - fn create_users_with_array_input(&self, body: &Vec) -> Box + Send> { + fn create_users_with_array_input(&self, body: &Vec) -> Box> { self.api().create_users_with_array_input(body, &self.context()) } /// Creates list of users with given input array - fn create_users_with_list_input(&self, body: &Vec) -> Box + Send> { + fn create_users_with_list_input(&self, body: &Vec) -> Box> { self.api().create_users_with_list_input(body, &self.context()) } /// Delete user - fn delete_user(&self, username: String) -> Box + Send> { + fn delete_user(&self, username: String) -> Box> { self.api().delete_user(username, &self.context()) } /// Get user by user name - fn get_user_by_name(&self, username: String) -> Box + Send> { + fn get_user_by_name(&self, username: String) -> Box> { self.api().get_user_by_name(username, &self.context()) } /// Logs user into the system - fn login_user(&self, username: String, password: String) -> Box + Send> { + fn login_user(&self, username: String, password: String) -> Box> { self.api().login_user(username, password, &self.context()) } /// Logs out current logged in user session - fn logout_user(&self) -> Box + Send> { + fn logout_user(&self) -> Box> { self.api().logout_user(&self.context()) } /// Updated user - fn update_user(&self, username: String, body: models::User) -> Box + Send> { + fn update_user(&self, username: String, body: models::User) -> Box> { self.api().update_user(username, body, &self.context()) } @@ -633,6 +652,6 @@ pub mod server; // Re-export router() as a top-level name #[cfg(feature = "server")] -pub use self::server::router; +pub use self::server::Service; pub mod models; diff --git a/samples/server/petstore/rust-server/src/mimetypes.rs b/samples/server/petstore/rust-server/src/mimetypes.rs index c35afc74ff3..1ad0e1d9b0c 100644 --- a/samples/server/petstore/rust-server/src/mimetypes.rs +++ b/samples/server/petstore/rust-server/src/mimetypes.rs @@ -61,30 +61,46 @@ pub mod requests { lazy_static! { pub static ref TEST_SPECIAL_TAGS: Mime = "application/json".parse().unwrap(); } + /// Create Mime objects for the request content types for TestBodyWithQueryParams + lazy_static! { + pub static ref TEST_BODY_WITH_QUERY_PARAMS: Mime = "application/json".parse().unwrap(); + } /// Create Mime objects for the request content types for FakeOuterBooleanSerialize lazy_static! { - pub static ref FAKE_OUTER_BOOLEAN_SERIALIZE: Mime = "Application/Json".parse().unwrap(); + pub static ref FAKE_OUTER_BOOLEAN_SERIALIZE: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for FakeOuterCompositeSerialize lazy_static! { - pub static ref FAKE_OUTER_COMPOSITE_SERIALIZE: Mime = "Application/Json".parse().unwrap(); + pub static ref FAKE_OUTER_COMPOSITE_SERIALIZE: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for FakeOuterNumberSerialize lazy_static! { - pub static ref FAKE_OUTER_NUMBER_SERIALIZE: Mime = "Application/Json".parse().unwrap(); + pub static ref FAKE_OUTER_NUMBER_SERIALIZE: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for FakeOuterStringSerialize lazy_static! { - pub static ref FAKE_OUTER_STRING_SERIALIZE: Mime = "Application/Json".parse().unwrap(); + pub static ref FAKE_OUTER_STRING_SERIALIZE: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for TestClientModel lazy_static! { pub static ref TEST_CLIENT_MODEL: Mime = "application/json".parse().unwrap(); } + /// Create Mime objects for the request content types for TestEndpointParameters + lazy_static! { + pub static ref TEST_ENDPOINT_PARAMETERS: Mime = "application/xml; charset=utf-8".parse().unwrap(); + } + /// Create Mime objects for the request content types for TestEnumParameters + lazy_static! { + pub static ref TEST_ENUM_PARAMETERS: Mime = "*/*".parse().unwrap(); + } /// Create Mime objects for the request content types for TestInlineAdditionalProperties lazy_static! { pub static ref TEST_INLINE_ADDITIONAL_PROPERTIES: Mime = "application/json".parse().unwrap(); } + /// Create Mime objects for the request content types for TestJsonFormData + lazy_static! { + pub static ref TEST_JSON_FORM_DATA: Mime = "application/json".parse().unwrap(); + } /// Create Mime objects for the request content types for TestClassname lazy_static! { pub static ref TEST_CLASSNAME: Mime = "application/json".parse().unwrap(); @@ -97,25 +113,29 @@ pub mod requests { lazy_static! { pub static ref UPDATE_PET: Mime = "application/json".parse().unwrap(); } + /// Create Mime objects for the request content types for UpdatePetWithForm + lazy_static! { + pub static ref UPDATE_PET_WITH_FORM: Mime = "application/x-www-form-urlencoded".parse().unwrap(); + } /// Create Mime objects for the request content types for PlaceOrder lazy_static! { - pub static ref PLACE_ORDER: Mime = "Application/Json".parse().unwrap(); + pub static ref PLACE_ORDER: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for CreateUser lazy_static! { - pub static ref CREATE_USER: Mime = "Application/Json".parse().unwrap(); + pub static ref CREATE_USER: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for CreateUsersWithArrayInput lazy_static! { - pub static ref CREATE_USERS_WITH_ARRAY_INPUT: Mime = "Application/Json".parse().unwrap(); + pub static ref CREATE_USERS_WITH_ARRAY_INPUT: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for CreateUsersWithListInput lazy_static! { - pub static ref CREATE_USERS_WITH_LIST_INPUT: Mime = "Application/Json".parse().unwrap(); + pub static ref CREATE_USERS_WITH_LIST_INPUT: Mime = "application/json".parse().unwrap(); } /// Create Mime objects for the request content types for UpdateUser lazy_static! { - pub static ref UPDATE_USER: Mime = "Application/Json".parse().unwrap(); + pub static ref UPDATE_USER: Mime = "application/json".parse().unwrap(); } } diff --git a/samples/server/petstore/rust-server/src/server.rs b/samples/server/petstore/rust-server/src/server.rs deleted file mode 100644 index 675dae8ef56..00000000000 --- a/samples/server/petstore/rust-server/src/server.rs +++ /dev/null @@ -1,2481 +0,0 @@ -#![allow(unused_extern_crates)] -extern crate serde_ignored; -extern crate iron; -extern crate router; -extern crate bodyparser; -extern crate urlencoded; -extern crate uuid; -extern crate chrono; -extern crate multipart; - -use futures::Future; -use futures::future; -use futures::{stream, Stream}; -use hyper; -use hyper::header::{Headers, ContentType}; -use self::iron::prelude::*; -use self::iron::{status, modifiers, BeforeMiddleware}; -use self::iron::url::percent_encoding::percent_decode; -use self::router::Router; -use self::urlencoded::UrlEncodedQuery; -use mimetypes; -use multipart::server::{Multipart, SaveResult}; - -use serde_json; -use serde_xml_rs; - -#[allow(unused_imports)] -use std::collections::{HashMap, BTreeMap}; -#[allow(unused_imports)] -use swagger; -use std::io::Error; - -#[allow(unused_imports)] -use std::collections::BTreeSet; - -pub use swagger::auth::Authorization; -use swagger::auth::{AuthData, Scopes}; -use swagger::{ApiError, Context, XSpanId}; - -use {Api, - TestSpecialTagsResponse, - FakeOuterBooleanSerializeResponse, - FakeOuterCompositeSerializeResponse, - FakeOuterNumberSerializeResponse, - FakeOuterStringSerializeResponse, - TestClientModelResponse, - TestEndpointParametersResponse, - TestEnumParametersResponse, - TestInlineAdditionalPropertiesResponse, - TestJsonFormDataResponse, - TestClassnameResponse, - AddPetResponse, - DeletePetResponse, - FindPetsByStatusResponse, - FindPetsByTagsResponse, - GetPetByIdResponse, - UpdatePetResponse, - UpdatePetWithFormResponse, - UploadFileResponse, - DeleteOrderResponse, - GetInventoryResponse, - GetOrderByIdResponse, - PlaceOrderResponse, - CreateUserResponse, - CreateUsersWithArrayInputResponse, - CreateUsersWithListInputResponse, - DeleteUserResponse, - GetUserByNameResponse, - LoginUserResponse, - LogoutUserResponse, - UpdateUserResponse - }; -#[allow(unused_imports)] -use models; - -header! { (Warning, "Warning") => [String] } - -/// Create a new router for `Api` -pub fn router(api: T) -> Router where T: Api + Send + Sync + Clone + 'static { - let mut router = Router::new(); - add_routes(&mut router, api); - router -} - -/// Add routes for `Api` to a provided router. -/// -/// Note that these routes are added straight onto the router. This means that if the router -/// already has a route for an endpoint which clashes with those provided by this API, then the -/// old route will be lost. -/// -/// It is generally a bad idea to add routes in this way to an existing router, which may have -/// routes on it for other APIs. Distinct APIs should be behind distinct paths to encourage -/// separation of interfaces, which this function does not enforce. APIs should not overlap. -/// -/// Alternative approaches include: -/// -/// - generate an `iron::middleware::Handler` (usually a `router::Router` or -/// `iron::middleware::chain`) for each interface, and add those handlers inside an existing -/// router, mounted at different paths - so the interfaces are separated by path -/// - use a different instance of `iron::Iron` for each interface - so the interfaces are -/// separated by the address/port they listen on -/// -/// This function exists to allow legacy code, which doesn't separate its APIs properly, to make -/// use of this crate. -#[deprecated(note="APIs should not overlap - only for use in legacy code.")] -pub fn route(router: &mut Router, api: T) where T: Api + Send + Sync + Clone + 'static { - add_routes(router, api) -} - -/// Add routes for `Api` to a provided router -fn add_routes(router: &mut Router, api: T) where T: Api + Send + Sync + Clone + 'static { - - let api_clone = api.clone(); - router.patch( - "/v2/another-fake/dummy", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.test_special_tags(param_body, context).wait() { - Ok(rsp) => match rsp { - TestSpecialTagsResponse::SuccessfulOperation(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::TEST_SPECIAL_TAGS_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "TestSpecialTags"); - - let api_clone = api.clone(); - router.post( - "/v2/fake/outer/boolean", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().unwrap_or(None); - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).unwrap_or(None); - - param_body - } else { - None - };; - - - match api.fake_outer_boolean_serialize(param_body, context).wait() { - Ok(rsp) => match rsp { - FakeOuterBooleanSerializeResponse::OutputBoolean(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "FakeOuterBooleanSerialize"); - - let api_clone = api.clone(); - router.post( - "/v2/fake/outer/composite", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().unwrap_or(None); - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).unwrap_or(None); - - param_body - } else { - None - };; - - - match api.fake_outer_composite_serialize(param_body, context).wait() { - Ok(rsp) => match rsp { - FakeOuterCompositeSerializeResponse::OutputComposite(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "FakeOuterCompositeSerialize"); - - let api_clone = api.clone(); - router.post( - "/v2/fake/outer/number", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().unwrap_or(None); - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).unwrap_or(None); - - param_body - } else { - None - };; - - - match api.fake_outer_number_serialize(param_body, context).wait() { - Ok(rsp) => match rsp { - FakeOuterNumberSerializeResponse::OutputNumber(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "FakeOuterNumberSerialize"); - - let api_clone = api.clone(); - router.post( - "/v2/fake/outer/string", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().unwrap_or(None); - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).unwrap_or(None); - - param_body - } else { - None - };; - - - match api.fake_outer_string_serialize(param_body, context).wait() { - Ok(rsp) => match rsp { - FakeOuterStringSerializeResponse::OutputString(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "FakeOuterStringSerialize"); - - let api_clone = api.clone(); - router.patch( - "/v2/fake", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.test_client_model(param_body, context).wait() { - Ok(rsp) => match rsp { - TestClientModelResponse::SuccessfulOperation(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::TEST_CLIENT_MODEL_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "TestClientModel"); - - let api_clone = api.clone(); - router.post( - "/v2/fake", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - - - - // Form parameters - let param_number = 8.14; - let param_double = 1.2; - let param_pattern_without_delimiter = "pattern_without_delimiter_example".to_string(); - let param_byte = swagger::ByteArray(Vec::from("B")); - let param_integer = Some(56); - let param_int32 = Some(56); - let param_int64 = Some(789); - let param_float = Some(3.4); - let param_string = Some("string_example".to_string()); - let param_binary = Some(swagger::ByteArray(Vec::from("B"))); - let param_date = None; - let param_date_time = None; - let param_password = Some("password_example".to_string()); - let param_callback = Some("callback_example".to_string()); - - match api.test_endpoint_parameters(param_number, param_double, param_pattern_without_delimiter, param_byte, param_integer, param_int32, param_int64, param_float, param_string, param_binary, param_date, param_date_time, param_password, param_callback, context).wait() { - Ok(rsp) => match rsp { - TestEndpointParametersResponse::InvalidUsernameSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - TestEndpointParametersResponse::UserNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "TestEndpointParameters"); - - let api_clone = api.clone(); - router.get( - "/v2/fake", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - // Header parameters - header! { (RequestEnumHeaderStringArray, "enum_header_string_array") => (String)* } - let param_enum_header_string_array = req.headers.get::().map(|header| header.0.clone()); - header! { (RequestEnumHeaderString, "enum_header_string") => [String] } - let param_enum_header_string = req.headers.get::().map(|header| header.0.clone()); - - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = req.get::().unwrap_or_default(); - let param_enum_query_string_array = query_params.get("enum_query_string_array") - .map(|list| list.iter().flat_map(|x| x.parse::()).collect::>()); - let param_enum_query_string = query_params.get("enum_query_string") - .and_then(|list| list.first()).and_then(|x| x.parse::().ok()); - let param_enum_query_integer = query_params.get("enum_query_integer") - .and_then(|list| list.first()).and_then(|x| x.parse::().ok()); - - // Form parameters - let param_enum_form_string_array = None; - let param_enum_form_string = Some("enum_form_string_example".to_string()); - let param_enum_query_double = Some(1.2); - - match api.test_enum_parameters(param_enum_form_string_array.as_ref(), param_enum_form_string, param_enum_header_string_array.as_ref(), param_enum_header_string, param_enum_query_string_array.as_ref(), param_enum_query_string, param_enum_query_integer, param_enum_query_double, context).wait() { - Ok(rsp) => match rsp { - TestEnumParametersResponse::InvalidRequest => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - TestEnumParametersResponse::NotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "TestEnumParameters"); - - let api_clone = api.clone(); - router.post( - "/v2/fake/inline-additionalProperties", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_param = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter param - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_param = if let Some(param_param_raw) = param_param { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_param_raw); - - let param_param: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter param - doesn't match schema: {}", e))))?; - - param_param - } else { - None - }; - let param_param = param_param.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter param".to_string())))?; - - - match api.test_inline_additional_properties(param_param, context).wait() { - Ok(rsp) => match rsp { - TestInlineAdditionalPropertiesResponse::SuccessfulOperation => { - - - let mut response = Response::with((status::Status::from_u16(200))); - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "TestInlineAdditionalProperties"); - - let api_clone = api.clone(); - router.get( - "/v2/fake/jsonFormData", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Form parameters - let param_param = "param_example".to_string(); - let param_param2 = "param2_example".to_string(); - - match api.test_json_form_data(param_param, param_param2, context).wait() { - Ok(rsp) => match rsp { - TestJsonFormDataResponse::SuccessfulOperation => { - - - let mut response = Response::with((status::Status::from_u16(200))); - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "TestJsonFormData"); - - let api_clone = api.clone(); - router.patch( - "/v2/fake_classname_test", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.test_classname(param_body, context).wait() { - Ok(rsp) => match rsp { - TestClassnameResponse::SuccessfulOperation(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::TEST_CLASSNAME_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "TestClassname"); - - let api_clone = api.clone(); - router.post( - "/v2/pet", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - "write:pets".to_string(), // modify pets in your account - "read:pets".to_string(), // read your pets - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(param_body_raw.as_bytes()); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.add_pet(param_body, context).wait() { - Ok(rsp) => match rsp { - AddPetResponse::InvalidInput => { - - - let mut response = Response::with((status::Status::from_u16(405))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "AddPet"); - - let api_clone = api.clone(); - router.delete( - "/v2/pet/:petId", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - "write:pets".to_string(), // modify pets in your account - "read:pets".to_string(), // read your pets - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - - - // Path parameters - let param_pet_id = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("petId").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter petId".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter petId: {}", e))))? - }; - - // Header parameters - header! { (RequestApiKey, "api_key") => [String] } - let param_api_key = req.headers.get::().map(|header| header.0.clone()); - - - - match api.delete_pet(param_pet_id, param_api_key, context).wait() { - Ok(rsp) => match rsp { - DeletePetResponse::InvalidPetValue => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "DeletePet"); - - let api_clone = api.clone(); - router.get( - "/v2/pet/findByStatus", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - "write:pets".to_string(), // modify pets in your account - "read:pets".to_string(), // read your pets - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - - - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = req.get::().unwrap_or_default(); - let param_status = query_params.get("status") - .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter status".to_string())))? - .iter().flat_map(|x| x.parse::()).collect::>(); - - - match api.find_pets_by_status(param_status.as_ref(), context).wait() { - Ok(rsp) => match rsp { - FindPetsByStatusResponse::SuccessfulOperation(body) => { - - let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::FIND_PETS_BY_STATUS_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - FindPetsByStatusResponse::InvalidStatusValue => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "FindPetsByStatus"); - - let api_clone = api.clone(); - router.get( - "/v2/pet/findByTags", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - "write:pets".to_string(), // modify pets in your account - "read:pets".to_string(), // read your pets - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - - - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = req.get::().unwrap_or_default(); - let param_tags = query_params.get("tags") - .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter tags".to_string())))? - .iter().flat_map(|x| x.parse::()).collect::>(); - - - match api.find_pets_by_tags(param_tags.as_ref(), context).wait() { - Ok(rsp) => match rsp { - FindPetsByTagsResponse::SuccessfulOperation(body) => { - - let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::FIND_PETS_BY_TAGS_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - FindPetsByTagsResponse::InvalidTagValue => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "FindPetsByTags"); - - let api_clone = api.clone(); - router.get( - "/v2/pet/:petId", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - - - // Path parameters - let param_pet_id = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("petId").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter petId".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter petId: {}", e))))? - }; - - - - match api.get_pet_by_id(param_pet_id, context).wait() { - Ok(rsp) => match rsp { - GetPetByIdResponse::SuccessfulOperation(body) => { - - let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::GET_PET_BY_ID_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - GetPetByIdResponse::InvalidIDSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - GetPetByIdResponse::PetNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "GetPetById"); - - let api_clone = api.clone(); - router.put( - "/v2/pet", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - "write:pets".to_string(), // modify pets in your account - "read:pets".to_string(), // read your pets - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(param_body_raw.as_bytes()); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.update_pet(param_body, context).wait() { - Ok(rsp) => match rsp { - UpdatePetResponse::InvalidIDSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - UpdatePetResponse::PetNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - UpdatePetResponse::ValidationException => { - - - let mut response = Response::with((status::Status::from_u16(405))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "UpdatePet"); - - let api_clone = api.clone(); - router.post( - "/v2/pet/:petId", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - "write:pets".to_string(), // modify pets in your account - "read:pets".to_string(), // read your pets - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - - - // Path parameters - let param_pet_id = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("petId").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter petId".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter petId: {}", e))))? - }; - - - // Form parameters - let param_name = Some("name_example".to_string()); - let param_status = Some("status_example".to_string()); - - match api.update_pet_with_form(param_pet_id, param_name, param_status, context).wait() { - Ok(rsp) => match rsp { - UpdatePetWithFormResponse::InvalidInput => { - - - let mut response = Response::with((status::Status::from_u16(405))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "UpdatePetWithForm"); - - let api_clone = api.clone(); - router.post( - "/v2/pet/:petId/uploadImage", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - // Authorization - if let Scopes::Some(ref scopes) = authorization.scopes { - let required_scopes: BTreeSet = vec![ - "write:pets".to_string(), // modify pets in your account - "read:pets".to_string(), // read your pets - ].into_iter().collect(); - - if !required_scopes.is_subset(scopes) { - let missing_scopes = required_scopes.difference(scopes); - return Err(Response::with(( - status::Forbidden, - missing_scopes.fold( - "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope) - ) - ))); - } - } - - - // Path parameters - let param_pet_id = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("petId").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter petId".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter petId: {}", e))))? - }; - - - // Form parameters - - // Expecting a multipart form, extract and parse it now. - let mut entries = match Multipart::from_request(req) { - Ok(mut multipart) => { - - match multipart.save().temp() { - SaveResult::Full(entries) => { - Ok(entries) - }, - _ => { - Err(Response::with((status::InternalServerError, format!("Unable to process all message parts")))) - }, - } - }, - Err(e) => { - // Unable to parse as multipart - Err(Response::with((status::BadRequest, format!("Couldn't parse body as multipart")))) - } - }?; - - let param_additional_metadata = Some("additional_metadata_example".to_string()); - - - let param_file = entries.fields.remove("file"); - - let param_file = match param_file { - Some(body) => { - Ok({let bytes = body.as_bytes(); - Some( - Box::new(stream::once(Ok(bytes.to_vec()))) as Box, Error=Error> + Send> - )} - ) - } - None => {Err(Response::with((status::BadRequest, format!("Body part not found!"))))} - }?; - let param_file = Box::new(future::ok(param_file)); - - match api.upload_file(param_pet_id, param_additional_metadata, param_file, context).wait() { - Ok(rsp) => match rsp { - UploadFileResponse::SuccessfulOperation(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::UPLOAD_FILE_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "UploadFile"); - - let api_clone = api.clone(); - router.delete( - "/v2/store/order/:order_id", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - // Path parameters - let param_order_id = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("order_id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter order_id".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter order_id: {}", e))))? - }; - - - - match api.delete_order(param_order_id, context).wait() { - Ok(rsp) => match rsp { - DeleteOrderResponse::InvalidIDSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - DeleteOrderResponse::OrderNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "DeleteOrder"); - - let api_clone = api.clone(); - router.get( - "/v2/store/inventory", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - let authorization = context.authorization.as_ref().ok_or_else(|| { - Response::with(( - status::Forbidden, - "Unauthenticated".to_string() - )) - })?; - - - - - - match api.get_inventory(context).wait() { - Ok(rsp) => match rsp { - GetInventoryResponse::SuccessfulOperation(body) => { - - let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::GET_INVENTORY_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "GetInventory"); - - let api_clone = api.clone(); - router.get( - "/v2/store/order/:order_id", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - // Path parameters - let param_order_id = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("order_id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter order_id".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter order_id: {}", e))))? - }; - - - - match api.get_order_by_id(param_order_id, context).wait() { - Ok(rsp) => match rsp { - GetOrderByIdResponse::SuccessfulOperation(body) => { - - let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::GET_ORDER_BY_ID_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - GetOrderByIdResponse::InvalidIDSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - GetOrderByIdResponse::OrderNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "GetOrderById"); - - let api_clone = api.clone(); - router.post( - "/v2/store/order", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.place_order(param_body, context).wait() { - Ok(rsp) => match rsp { - PlaceOrderResponse::SuccessfulOperation(body) => { - - let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::PLACE_ORDER_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - PlaceOrderResponse::InvalidOrder => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "PlaceOrder"); - - let api_clone = api.clone(); - router.post( - "/v2/user", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.create_user(param_body, context).wait() { - Ok(rsp) => match rsp { - CreateUserResponse::SuccessfulOperation => { - - - let mut response = Response::with((status::Status::from_u16(0))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "CreateUser"); - - let api_clone = api.clone(); - router.post( - "/v2/user/createWithArray", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option> = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.create_users_with_array_input(param_body.as_ref(), context).wait() { - Ok(rsp) => match rsp { - CreateUsersWithArrayInputResponse::SuccessfulOperation => { - - - let mut response = Response::with((status::Status::from_u16(0))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "CreateUsersWithArrayInput"); - - let api_clone = api.clone(); - router.post( - "/v2/user/createWithList", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option> = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.create_users_with_list_input(param_body.as_ref(), context).wait() { - Ok(rsp) => match rsp { - CreateUsersWithListInputResponse::SuccessfulOperation => { - - - let mut response = Response::with((status::Status::from_u16(0))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "CreateUsersWithListInput"); - - let api_clone = api.clone(); - router.delete( - "/v2/user/:username", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - // Path parameters - let param_username = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("username").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter username".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter username: {}", e))))? - }; - - - - match api.delete_user(param_username, context).wait() { - Ok(rsp) => match rsp { - DeleteUserResponse::InvalidUsernameSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - DeleteUserResponse::UserNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "DeleteUser"); - - let api_clone = api.clone(); - router.get( - "/v2/user/:username", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - // Path parameters - let param_username = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("username").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter username".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter username: {}", e))))? - }; - - - - match api.get_user_by_name(param_username, context).wait() { - Ok(rsp) => match rsp { - GetUserByNameResponse::SuccessfulOperation(body) => { - - let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); - response.headers.set(ContentType(mimetypes::responses::GET_USER_BY_NAME_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - GetUserByNameResponse::InvalidUsernameSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - GetUserByNameResponse::UserNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "GetUserByName"); - - let api_clone = api.clone(); - router.get( - "/v2/user/login", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = req.get::().unwrap_or_default(); - let param_username = query_params.get("username") - .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter username".to_string())))? - .first().ok_or_else(|| Response::with((status::BadRequest, "Required query parameter username was empty".to_string())))? - .parse::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse query parameter username - doesn't match schema: {}", e))))?; - let param_password = query_params.get("password") - .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter password".to_string())))? - .first().ok_or_else(|| Response::with((status::BadRequest, "Required query parameter password was empty".to_string())))? - .parse::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse query parameter password - doesn't match schema: {}", e))))?; - - - match api.login_user(param_username, param_password, context).wait() { - Ok(rsp) => match rsp { - LoginUserResponse::SuccessfulOperation{ body, x_rate_limit, x_expires_after } => { - - let body_string = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - - let mut response = Response::with((status::Status::from_u16(200), body_string)); header! { (ResponseXRateLimit, "X-Rate-Limit") => [i32] } - response.headers.set(ResponseXRateLimit(x_rate_limit)); - header! { (ResponseXExpiresAfter, "X-Expires-After") => [chrono::DateTime] } - response.headers.set(ResponseXExpiresAfter(x_expires_after)); - - response.headers.set(ContentType(mimetypes::responses::LOGIN_USER_SUCCESSFUL_OPERATION.clone())); - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - LoginUserResponse::InvalidUsername => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "LoginUser"); - - let api_clone = api.clone(); - router.get( - "/v2/user/logout", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - - - match api.logout_user(context).wait() { - Ok(rsp) => match rsp { - LogoutUserResponse::SuccessfulOperation => { - - - let mut response = Response::with((status::Status::from_u16(0))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "LogoutUser"); - - let api_clone = api.clone(); - router.put( - "/v2/user/:username", - move |req: &mut Request| { - let mut context = Context::default(); - - // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). - fn handle_request(req: &mut Request, api: &T, context: &mut Context) -> Result where T: Api { - - context.x_span_id = Some(req.headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); - context.auth_data = req.extensions.remove::(); - context.authorization = req.extensions.remove::(); - - - - // Path parameters - let param_username = { - let param = req.extensions.get::().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? - .find("username").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter username".to_string())))?; - percent_decode(param.as_bytes()).decode_utf8() - .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? - .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter username: {}", e))))? - }; - - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - - let param_body = req.get::().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))))?; - - let mut unused_elements = Vec::new(); - - let param_body = if let Some(param_body_raw) = param_body { - let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); - - let param_body: Option = serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }).map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse body parameter body - doesn't match schema: {}", e))))?; - - param_body - } else { - None - }; - let param_body = param_body.ok_or_else(|| Response::with((status::BadRequest, "Missing required body parameter body".to_string())))?; - - - match api.update_user(param_username, param_body, context).wait() { - Ok(rsp) => match rsp { - UpdateUserResponse::InvalidUserSupplied => { - - - let mut response = Response::with((status::Status::from_u16(400))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - UpdateUserResponse::UserNotFound => { - - - let mut response = Response::with((status::Status::from_u16(404))); - - - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - if !unused_elements.is_empty() { - response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); - } - Ok(response) - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) - } - } - } - - handle_request(req, &api_clone, &mut context).or_else(|mut response| { - context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); - Ok(response) - }) - }, - "UpdateUser"); - -} - -/// Middleware to extract authentication data from request -pub struct ExtractAuthData; - -impl BeforeMiddleware for ExtractAuthData { - fn before(&self, req: &mut Request) -> IronResult<()> { - { - header! { (ApiKey1, "api_key") => [String] } - if let Some(header) = req.headers.get::() { - req.extensions.insert::(AuthData::ApiKey(header.0.clone())); - return Ok(()); - } - } - { - let header = match req.get_ref::() { - Ok(query) => query.get("api_key_query").map(|v| v[0].clone()), - _ => None - }; - if let Some(key) = header { - req.extensions.insert::(AuthData::ApiKey(key)); - return Ok(()); - } - } - { - use hyper::header::{Authorization, Basic, Bearer}; - use std::ops::Deref; - if let Some(basic) = req.headers.get::>() { - req.extensions.insert::(AuthData::Basic(basic.deref().clone())); - return Ok(()); - } - } - { - use hyper::header::{Authorization, Basic, Bearer}; - use std::ops::Deref; - if let Some(bearer) = req.headers.get::>() { - req.extensions.insert::(AuthData::Bearer(bearer.deref().clone())); - return Ok(()); - } - } - - Ok(()) - } -} diff --git a/samples/server/petstore/rust-server/src/server/auth.rs b/samples/server/petstore/rust-server/src/server/auth.rs new file mode 100644 index 00000000000..5c120b74c7c --- /dev/null +++ b/samples/server/petstore/rust-server/src/server/auth.rs @@ -0,0 +1,83 @@ +use std::io; +use hyper; +use hyper::{Request, Response, Error, StatusCode}; +use server::url::form_urlencoded; +use swagger::auth::{Authorization, AuthData, Scopes}; +use Api; + +pub struct NewService where T: hyper::server::NewService), Response=Response, Error=Error> { + inner: T, +} + +impl NewService where T: hyper::server::NewService), Response=Response, Error=Error> + 'static { + pub fn new(inner: T) -> NewService { + NewService{inner} + } +} + +impl hyper::server::NewService for NewService where T: hyper::server::NewService), Response=Response, Error=Error> + 'static { + type Request = Request; + type Response = Response; + type Error = Error; + type Instance = Service; + + fn new_service(&self) -> Result { + self.inner.new_service().map(|s| Service::new(s)) + } +} + +/// Middleware to extract authentication data from request +pub struct Service where T: hyper::server::Service), Response=Response, Error=Error> { + inner: T, +} + +impl Service where T: hyper::server::Service), Response=Response, Error=Error> { + pub fn new(inner: T) -> Service { + Service{inner} + } +} + +impl hyper::server::Service for Service where T: hyper::server::Service), Response=Response, Error=Error> { + type Request = Request; + type Response = Response; + type Error = Error; + type Future = T::Future; + + fn call(&self, req: Self::Request) -> Self::Future { + { + header! { (ApiKey1, "api_key") => [String] } + if let Some(header) = req.headers().get::().cloned() { + let auth_data = AuthData::ApiKey(header.0); + return self.inner.call((req, Some(auth_data))); + } + } + { + let key = form_urlencoded::parse(req.query().unwrap_or_default().as_bytes()) + .filter(|e| e.0 == "api_key_query") + .map(|e| e.1.clone().into_owned()) + .nth(0); + if let Some(key) = key { + let auth_data = AuthData::ApiKey(key); + return self.inner.call((req, Some(auth_data))); + } + } + { + use hyper::header::{Authorization, Basic, Bearer}; + use std::ops::Deref; + if let Some(basic) = req.headers().get::>().cloned() { + let auth_data = AuthData::Basic(basic.deref().clone()); + return self.inner.call((req, Some(auth_data))); + } + } + { + use hyper::header::{Authorization, Basic, Bearer}; + use std::ops::Deref; + if let Some(bearer) = req.headers().get::>().cloned() { + let auth_data = AuthData::Bearer(bearer.deref().clone()); + return self.inner.call((req, Some(auth_data))); + } + } + + return self.inner.call((req, None)); + } +} diff --git a/samples/server/petstore/rust-server/src/server/mod.rs b/samples/server/petstore/rust-server/src/server/mod.rs new file mode 100644 index 00000000000..7f88b6b3ad8 --- /dev/null +++ b/samples/server/petstore/rust-server/src/server/mod.rs @@ -0,0 +1,3058 @@ +#![allow(unused_extern_crates)] +extern crate serde_ignored; +extern crate tokio_core; +extern crate native_tls; +extern crate hyper_tls; +extern crate openssl; +extern crate mime; +extern crate uuid; +extern crate chrono; +extern crate multipart; +extern crate percent_encoding; +extern crate url; + + +use std::sync::Arc; +use futures::{Future, future, Stream, stream}; +use hyper; +use hyper::{Request, Response, Error, StatusCode}; +use hyper::header::{Headers, ContentType}; +use self::url::form_urlencoded; +use mimetypes; +use self::multipart::server::Multipart; +use self::multipart::server::save::SaveResult; + +use serde_json; +use serde_xml_rs; + +#[allow(unused_imports)] +use std::collections::{HashMap, BTreeMap}; +#[allow(unused_imports)] +use swagger; +use std::io; + +#[allow(unused_imports)] +use std::collections::BTreeSet; + +pub use swagger::auth::Authorization; +use swagger::{ApiError, Context, XSpanId}; +use swagger::auth::Scopes; + +use {Api, + TestSpecialTagsResponse, + TestBodyWithQueryParamsResponse, + FakeOuterBooleanSerializeResponse, + FakeOuterCompositeSerializeResponse, + FakeOuterNumberSerializeResponse, + FakeOuterStringSerializeResponse, + TestClientModelResponse, + TestEndpointParametersResponse, + TestEnumParametersResponse, + TestInlineAdditionalPropertiesResponse, + TestJsonFormDataResponse, + TestClassnameResponse, + AddPetResponse, + DeletePetResponse, + FindPetsByStatusResponse, + FindPetsByTagsResponse, + GetPetByIdResponse, + UpdatePetResponse, + UpdatePetWithFormResponse, + UploadFileResponse, + DeleteOrderResponse, + GetInventoryResponse, + GetOrderByIdResponse, + PlaceOrderResponse, + CreateUserResponse, + CreateUsersWithArrayInputResponse, + CreateUsersWithListInputResponse, + DeleteUserResponse, + GetUserByNameResponse, + LoginUserResponse, + LogoutUserResponse, + UpdateUserResponse + }; +#[allow(unused_imports)] +use models; + +pub mod auth; + +header! { (Warning, "Warning") => [String] } + +mod paths { + extern crate regex; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(&[ + r"^/v2/another-fake/dummy$", + r"^/v2/fake$", + r"^/v2/fake/body-with-query-params$", + r"^/v2/fake/inline-additionalProperties$", + r"^/v2/fake/jsonFormData$", + r"^/v2/fake/outer/boolean$", + r"^/v2/fake/outer/composite$", + r"^/v2/fake/outer/number$", + r"^/v2/fake/outer/string$", + r"^/v2/fake_classname_test$", + r"^/v2/pet$", + r"^/v2/pet/findByStatus$", + r"^/v2/pet/findByTags$", + r"^/v2/pet/(?P[^/?#]*)$", + r"^/v2/pet/(?P[^/?#]*)/uploadImage$", + r"^/v2/store/inventory$", + r"^/v2/store/order$", + r"^/v2/store/order/(?P[^/?#]*)$", + r"^/v2/user$", + r"^/v2/user/createWithArray$", + r"^/v2/user/createWithList$", + r"^/v2/user/login$", + r"^/v2/user/logout$", + r"^/v2/user/(?P[^/?#]*)$" + ]).unwrap(); + } + pub static ID_ANOTHER_FAKE_DUMMY: usize = 0; + pub static ID_FAKE: usize = 1; + pub static ID_FAKE_BODY_WITH_QUERY_PARAMS: usize = 2; + pub static ID_FAKE_INLINE_ADDITIONALPROPERTIES: usize = 3; + pub static ID_FAKE_JSONFORMDATA: usize = 4; + pub static ID_FAKE_OUTER_BOOLEAN: usize = 5; + pub static ID_FAKE_OUTER_COMPOSITE: usize = 6; + pub static ID_FAKE_OUTER_NUMBER: usize = 7; + pub static ID_FAKE_OUTER_STRING: usize = 8; + pub static ID_FAKE_CLASSNAME_TEST: usize = 9; + pub static ID_PET: usize = 10; + pub static ID_PET_FINDBYSTATUS: usize = 11; + pub static ID_PET_FINDBYTAGS: usize = 12; + pub static ID_PET_PETID: usize = 13; + lazy_static! { + pub static ref REGEX_PET_PETID: regex::Regex = regex::Regex::new(r"^/v2/pet/(?P[^/?#]*)$").unwrap(); + } + pub static ID_PET_PETID_UPLOADIMAGE: usize = 14; + lazy_static! { + pub static ref REGEX_PET_PETID_UPLOADIMAGE: regex::Regex = regex::Regex::new(r"^/v2/pet/(?P[^/?#]*)/uploadImage$").unwrap(); + } + pub static ID_STORE_INVENTORY: usize = 15; + pub static ID_STORE_ORDER: usize = 16; + pub static ID_STORE_ORDER_ORDER_ID: usize = 17; + lazy_static! { + pub static ref REGEX_STORE_ORDER_ORDER_ID: regex::Regex = regex::Regex::new(r"^/v2/store/order/(?P[^/?#]*)$").unwrap(); + } + pub static ID_USER: usize = 18; + pub static ID_USER_CREATEWITHARRAY: usize = 19; + pub static ID_USER_CREATEWITHLIST: usize = 20; + pub static ID_USER_LOGIN: usize = 21; + pub static ID_USER_LOGOUT: usize = 22; + pub static ID_USER_USERNAME: usize = 23; + lazy_static! { + pub static ref REGEX_USER_USERNAME: regex::Regex = regex::Regex::new(r"^/v2/user/(?P[^/?#]*)$").unwrap(); + } +} + +pub struct NewService { + api_impl: Arc, +} + +impl NewService where T: Api + Clone + 'static { + pub fn new>>(api_impl: U) -> NewService { + NewService{api_impl: api_impl.into()} + } +} + +impl hyper::server::NewService for NewService where T: Api + Clone + 'static { + type Request = (Request, Context); + type Response = Response; + type Error = Error; + type Instance = Service; + + fn new_service(&self) -> Result { + Ok(Service::new(self.api_impl.clone())) + } +} + +pub struct Service { + api_impl: Arc, +} + +impl Service where T: Api + Clone + 'static { + pub fn new>>(api_impl: U) -> Service { + Service{api_impl: api_impl.into()} + } +} + +impl hyper::server::Service for Service where T: Api + Clone + 'static { + type Request = (Request, Context); + type Response = Response; + type Error = Error; + type Future = Box>; + + fn call(&self, (req, mut context): Self::Request) -> Self::Future { + let api_impl = self.api_impl.clone(); + let (method, uri, _, headers, body) = req.deconstruct(); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + match &method { + + // TestSpecialTags - PATCH /another-fake/dummy + &hyper::Method::Patch if path.matched(paths::ID_ANOTHER_FAKE_DUMMY) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.test_special_tags(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + TestSpecialTagsResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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); + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // TestBodyWithQueryParams - PUT /fake/body-with-query-params + &hyper::Method::Put if path.matched(paths::ID_FAKE_BODY_WITH_QUERY_PARAMS) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_query = query_params.iter().filter(|e| e.0 == "query").map(|e| e.1.to_owned()) + + .nth(0); + let param_query = match param_query { + Some(param_query) => match param_query.parse::() { + Ok(param_query) => param_query, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse query parameter query - doesn't match schema: {}", e)))), + }, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required query parameter query"))), + }; + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.test_body_with_query_params(param_body, param_query, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + TestBodyWithQueryParamsResponse::Success + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // FakeOuterBooleanSerialize - POST /fake/outer/boolean + &hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_BOOLEAN) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + + Err(_) => None, + } + + } else { + None + }; + + + Box::new(api_impl.fake_outer_boolean_serialize(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + FakeOuterBooleanSerializeResponse::OutputBoolean + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // FakeOuterCompositeSerialize - POST /fake/outer/composite + &hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_COMPOSITE) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + + Err(_) => None, + } + + } else { + None + }; + + + Box::new(api_impl.fake_outer_composite_serialize(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + FakeOuterCompositeSerializeResponse::OutputComposite + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // FakeOuterNumberSerialize - POST /fake/outer/number + &hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_NUMBER) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + + Err(_) => None, + } + + } else { + None + }; + + + Box::new(api_impl.fake_outer_number_serialize(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + FakeOuterNumberSerializeResponse::OutputNumber + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // FakeOuterStringSerialize - POST /fake/outer/string + &hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_STRING) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + + Err(_) => None, + } + + } else { + None + }; + + + Box::new(api_impl.fake_outer_string_serialize(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + FakeOuterStringSerializeResponse::OutputString + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // TestClientModel - PATCH /fake + &hyper::Method::Patch if path.matched(paths::ID_FAKE) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.test_client_model(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + TestClientModelResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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); + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // TestEndpointParameters - POST /fake + &hyper::Method::Post if path.matched(paths::ID_FAKE) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + } + + + + + + + + Box::new(({ + {{ + + // Form parameters + let param_integer = Some(56); + let param_int32 = Some(56); + let param_int64 = Some(789); + let param_number = 8.14; + let param_float = Some(3.4); + let param_double = 1.2; + let param_string = Some("string_example".to_string()); + let param_pattern_without_delimiter = "pattern_without_delimiter_example".to_string(); + let param_byte = swagger::ByteArray(Vec::from("B")); + let param_binary = Some(swagger::ByteArray(Vec::from("B"))); + let param_date = None; + let param_date_time = None; + let param_password = Some("password_example".to_string()); + let param_callback = Some("callback_example".to_string()); + + Box::new(api_impl.test_endpoint_parameters(param_number, param_double, param_pattern_without_delimiter, param_byte, param_integer, param_int32, param_int64, param_float, param_string, param_binary, param_date, param_date_time, param_password, param_callback, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + TestEndpointParametersResponse::InvalidUsernameSupplied + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + TestEndpointParametersResponse::UserNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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> + + + }, + + + // TestEnumParameters - GET /fake + &hyper::Method::Get if path.matched(paths::ID_FAKE) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + // Header parameters + header! { (RequestEnumHeaderStringArray, "enum_header_string_array") => (String)* } + let param_enum_header_string_array = headers.get::().map(|header| header.0.clone()); + header! { (RequestEnumHeaderString, "enum_header_string") => [String] } + let param_enum_header_string = headers.get::().map(|header| header.0.clone()); + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_enum_query_string_array = query_params.iter().filter(|e| e.0 == "enum_query_string_array").map(|e| e.1.to_owned()) + .filter_map(|param_enum_query_string_array| param_enum_query_string_array.parse::().ok()) + .collect::>(); + let param_enum_query_string_array = if !param_enum_query_string_array.is_empty() { + Some(param_enum_query_string_array) + } else { + None + }; + let param_enum_query_string = query_params.iter().filter(|e| e.0 == "enum_query_string").map(|e| e.1.to_owned()) + + .nth(0); + + let param_enum_query_string = param_enum_query_string.and_then(|param_enum_query_string| param_enum_query_string.parse::<>().ok()); + let param_enum_query_integer = query_params.iter().filter(|e| e.0 == "enum_query_integer").map(|e| e.1.to_owned()) + + .nth(0); + + let param_enum_query_integer = param_enum_query_integer.and_then(|param_enum_query_integer| param_enum_query_integer.parse::<>().ok()); + + + + Box::new(({ + {{ + + // Form parameters + let param_enum_form_string_array = None; + let param_enum_form_string = Some("enum_form_string_example".to_string()); + let param_enum_query_double = Some(1.2); + + Box::new(api_impl.test_enum_parameters(param_enum_form_string_array.as_ref(), param_enum_form_string, param_enum_header_string_array.as_ref(), param_enum_header_string, param_enum_query_string_array.as_ref(), param_enum_query_string, param_enum_query_integer, param_enum_query_double, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + TestEnumParametersResponse::InvalidRequest + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + TestEnumParametersResponse::NotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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> + + + }, + + + // TestInlineAdditionalProperties - POST /fake/inline-additionalProperties + &hyper::Method::Post if path.matched(paths::ID_FAKE_INLINE_ADDITIONALPROPERTIES) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_param: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_param) => param_param, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter param - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_param = match param_param { + Some(param_param) => param_param, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter param"))), + }; + + + Box::new(api_impl.test_inline_additional_properties(param_param, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + TestInlineAdditionalPropertiesResponse::SuccessfulOperation + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter param: {}", e)))), + } + }) + ) as Box> + + }, + + + // TestJsonFormData - GET /fake/jsonFormData + &hyper::Method::Get if path.matched(paths::ID_FAKE_JSONFORMDATA) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + + Box::new(({ + {{ + + // Form parameters + let param_param = "param_example".to_string(); + let param_param2 = "param2_example".to_string(); + + Box::new(api_impl.test_json_form_data(param_param, param_param2, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + TestJsonFormDataResponse::SuccessfulOperation + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + }, + }, + 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> + + + }, + + + // TestClassname - PATCH /fake_classname_test + &hyper::Method::Patch if path.matched(paths::ID_FAKE_CLASSNAME_TEST) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.test_classname(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + TestClassnameResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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); + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // AddPet - POST /pet + &hyper::Method::Post if path.matched(paths::ID_PET) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.add_pet(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + AddPetResponse::InvalidInput + + + => { + response.set_status(StatusCode::try_from(405).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // DeletePet - DELETE /pet/{petId} + &hyper::Method::Delete if path.matched(paths::ID_PET_PETID) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_PET_PETID + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter petId: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"])))) + }; + + // Header parameters + header! { (RequestApiKey, "api_key") => [String] } + let param_api_key = headers.get::().map(|header| header.0.clone()); + + + + + + Box::new(({ + {{ + + Box::new(api_impl.delete_pet(param_pet_id, param_api_key, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + DeletePetResponse::InvalidPetValue + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + }, + 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> + + + }, + + + // FindPetsByStatus - GET /pet/findByStatus + &hyper::Method::Get if path.matched(paths::ID_PET_FINDBYSTATUS) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + } + + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_status = query_params.iter().filter(|e| e.0 == "status").map(|e| e.1.to_owned()) + .filter_map(|param_status| param_status.parse::().ok()) + .collect::>(); + + + + Box::new(({ + {{ + + Box::new(api_impl.find_pets_by_status(param_status.as_ref(), &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + FindPetsByStatusResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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 + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + }, + 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> + + + }, + + + // FindPetsByTags - GET /pet/findByTags + &hyper::Method::Get if path.matched(paths::ID_PET_FINDBYTAGS) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + } + + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_tags = query_params.iter().filter(|e| e.0 == "tags").map(|e| e.1.to_owned()) + .filter_map(|param_tags| param_tags.parse::().ok()) + .collect::>(); + + + + Box::new(({ + {{ + + Box::new(api_impl.find_pets_by_tags(param_tags.as_ref(), &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + FindPetsByTagsResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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 + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + }, + 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> + + + }, + + + // GetPetById - GET /pet/{petId} + &hyper::Method::Get if path.matched(paths::ID_PET_PETID) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_PET_PETID + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter petId: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"])))) + }; + + + + + + Box::new(({ + {{ + + Box::new(api_impl.get_pet_by_id(param_pet_id, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + GetPetByIdResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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 + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + GetPetByIdResponse::PetNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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> + + + }, + + + // UpdatePet - PUT /pet + &hyper::Method::Put if path.matched(paths::ID_PET) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.update_pet(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + UpdatePetResponse::InvalidIDSupplied + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + UpdatePetResponse::PetNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + UpdatePetResponse::ValidationException + + + => { + response.set_status(StatusCode::try_from(405).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // UpdatePetWithForm - POST /pet/{petId} + &hyper::Method::Post if path.matched(paths::ID_PET_PETID) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_PET_PETID + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter petId: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"])))) + }; + + + + + + Box::new(({ + {{ + + // Form parameters + let param_name = Some("name_example".to_string()); + let param_status = Some("status_example".to_string()); + + Box::new(api_impl.update_pet_with_form(param_pet_id, param_name, param_status, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + UpdatePetWithFormResponse::InvalidInput + + + => { + response.set_status(StatusCode::try_from(405).unwrap()); + + }, + }, + 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> + + + }, + + + // UploadFile - POST /pet/{petId}/uploadImage + &hyper::Method::Post if path.matched(paths::ID_PET_PETID_UPLOADIMAGE) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{} {}", s, scope) + )) + )); + } + } + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_PET_PETID_UPLOADIMAGE + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID_UPLOADIMAGE in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID_UPLOADIMAGE.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter petId: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"])))) + }; + + + + + + let boundary = match multipart_boundary(&headers) { + Some(boundary) => boundary.to_string(), + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Couldn't find valid multipart body"))), + }; + + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() { + SaveResult::Full(entries) => { + entries + }, + _ => { + return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Unable to process all message parts")))) + }, + }; + + // Form parameters + let param_additional_metadata = entries.fields.remove("additional_metadata"); + let param_additional_metadata = match param_additional_metadata { + Some(entry) => + + match entry.parse::() { + Ok(entry) => Some(entry), + + Err(_) => None, + }, + + None => None, + }; + + let param_file = entries.fields.remove("file"); + let param_file = match param_file { + Some(entry) => + Some(Box::new(stream::once(Ok(entry.as_bytes().to_vec()))) as Box, Error=io::Error> + Send>), + + None => None, + }; + let param_file = Box::new(future::ok(param_file)); + + Box::new(api_impl.upload_file(param_pet_id, param_additional_metadata, param_file, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + UploadFileResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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); + }, + }, + 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> + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read multipart body")))), + } + }) + ) + + + }, + + + // DeleteOrder - DELETE /store/order/{order_id} + &hyper::Method::Delete if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_STORE_ORDER_ORDER_ID + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE STORE_ORDER_ORDER_ID in set but failed match against \"{}\"", path, paths::REGEX_STORE_ORDER_ORDER_ID.as_str()) + ); + + let param_order_id = match percent_encoding::percent_decode(path_params["order_id"].as_bytes()).decode_utf8() { + Ok(param_order_id) => match param_order_id.parse::() { + Ok(param_order_id) => param_order_id, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter order_id: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"])))) + }; + + + + + + Box::new(({ + {{ + + Box::new(api_impl.delete_order(param_order_id, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + DeleteOrderResponse::InvalidIDSupplied + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + DeleteOrderResponse::OrderNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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> + + + }, + + + // GetInventory - GET /store/inventory + &hyper::Method::Get if path.matched(paths::ID_STORE_INVENTORY) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + { + let authorization = match context.authorization.as_ref() { + Some(authorization) => authorization, + None => return Box::new(future::ok(Response::new() + .with_status(StatusCode::Forbidden) + .with_body("Unauthenticated"))), + }; + + } + + + + + + + + Box::new(({ + {{ + + Box::new(api_impl.get_inventory(&context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + GetInventoryResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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); + }, + }, + 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> + + + }, + + + // GetOrderById - GET /store/order/{order_id} + &hyper::Method::Get if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_STORE_ORDER_ORDER_ID + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE STORE_ORDER_ORDER_ID in set but failed match against \"{}\"", path, paths::REGEX_STORE_ORDER_ORDER_ID.as_str()) + ); + + let param_order_id = match percent_encoding::percent_decode(path_params["order_id"].as_bytes()).decode_utf8() { + Ok(param_order_id) => match param_order_id.parse::() { + Ok(param_order_id) => param_order_id, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter order_id: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"])))) + }; + + + + + + Box::new(({ + {{ + + Box::new(api_impl.get_order_by_id(param_order_id, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + GetOrderByIdResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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 + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + GetOrderByIdResponse::OrderNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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> + + + }, + + + // PlaceOrder - POST /store/order + &hyper::Method::Post if path.matched(paths::ID_STORE_ORDER) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.place_order(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + PlaceOrderResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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 + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // CreateUser - POST /user + &hyper::Method::Post if path.matched(paths::ID_USER) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.create_user(param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + CreateUserResponse::SuccessfulOperation + + + => { + response.set_status(StatusCode::try_from(0).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // CreateUsersWithArrayInput - POST /user/createWithArray + &hyper::Method::Post if path.matched(paths::ID_USER_CREATEWITHARRAY) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option> = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.create_users_with_array_input(param_body.as_ref(), &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + CreateUsersWithArrayInputResponse::SuccessfulOperation + + + => { + response.set_status(StatusCode::try_from(0).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // CreateUsersWithListInput - POST /user/createWithList + &hyper::Method::Post if path.matched(paths::ID_USER_CREATEWITHLIST) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option> = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.create_users_with_list_input(param_body.as_ref(), &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + CreateUsersWithListInputResponse::SuccessfulOperation + + + => { + response.set_status(StatusCode::try_from(0).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + // DeleteUser - DELETE /user/{username} + &hyper::Method::Delete if path.matched(paths::ID_USER_USERNAME) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_USER_USERNAME + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE USER_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_USER_USERNAME.as_str()) + ); + + let param_username = match percent_encoding::percent_decode(path_params["username"].as_bytes()).decode_utf8() { + Ok(param_username) => match param_username.parse::() { + Ok(param_username) => param_username, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter username: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"])))) + }; + + + + + + Box::new(({ + {{ + + Box::new(api_impl.delete_user(param_username, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + DeleteUserResponse::InvalidUsernameSupplied + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + DeleteUserResponse::UserNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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> + + + }, + + + // GetUserByName - GET /user/{username} + &hyper::Method::Get if path.matched(paths::ID_USER_USERNAME) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_USER_USERNAME + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE USER_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_USER_USERNAME.as_str()) + ); + + let param_username = match percent_encoding::percent_decode(path_params["username"].as_bytes()).decode_utf8() { + Ok(param_username) => match param_username.parse::() { + Ok(param_username) => param_username, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter username: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"])))) + }; + + + + + + Box::new(({ + {{ + + Box::new(api_impl.get_user_by_name(param_username, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + GetUserByNameResponse::SuccessfulOperation + + (body) + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + + 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 + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + GetUserByNameResponse::UserNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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> + + + }, + + + // LoginUser - GET /user/login + &hyper::Method::Get if path.matched(paths::ID_USER_LOGIN) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_username = query_params.iter().filter(|e| e.0 == "username").map(|e| e.1.to_owned()) + + .nth(0); + let param_username = match param_username { + Some(param_username) => match param_username.parse::() { + Ok(param_username) => param_username, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse query parameter username - doesn't match schema: {}", e)))), + }, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required query parameter username"))), + }; + let param_password = query_params.iter().filter(|e| e.0 == "password").map(|e| e.1.to_owned()) + + .nth(0); + let param_password = match param_password { + Some(param_password) => match param_password.parse::() { + Ok(param_password) => param_password, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse query parameter password - doesn't match schema: {}", e)))), + }, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required query parameter password"))), + }; + + + + Box::new(({ + {{ + + Box::new(api_impl.login_user(param_username, param_password, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + LoginUserResponse::SuccessfulOperation + + { + body, + x_rate_limit, + + x_expires_after + } + + + => { + response.set_status(StatusCode::try_from(200).unwrap()); + header! { (ResponseXRateLimit, "X-Rate-Limit") => [i32] } + response.headers_mut().set(ResponseXRateLimit(x_rate_limit)); + header! { (ResponseXExpiresAfter, "X-Expires-After") => [chrono::DateTime] } + response.headers_mut().set(ResponseXExpiresAfter(x_expires_after)); + + 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 + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + }, + 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> + + + }, + + + // LogoutUser - GET /user/logout + &hyper::Method::Get if path.matched(paths::ID_USER_LOGOUT) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + + + + + + Box::new(({ + {{ + + Box::new(api_impl.logout_user(&context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + match result { + Ok(rsp) => match rsp { + LogoutUserResponse::SuccessfulOperation + + + => { + response.set_status(StatusCode::try_from(0).unwrap()); + + }, + }, + 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> + + + }, + + + // UpdateUser - PUT /user/{username} + &hyper::Method::Put if path.matched(paths::ID_USER_USERNAME) => { + if context.x_span_id.is_none() { + context.x_span_id = Some(headers.get::().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + } + + + // Path parameters + let path = uri.path().to_string(); + let path_params = + paths::REGEX_USER_USERNAME + .captures(&path) + .unwrap_or_else(|| + panic!("Path {} matched RE USER_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_USER_USERNAME.as_str()) + ); + + let param_username = match percent_encoding::percent_decode(path_params["username"].as_bytes()).decode_utf8() { + Ok(param_username) => match param_username.parse::() { + Ok(param_username) => param_username, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter username: {}", e)))), + }, + Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"])))) + }; + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + Box::new(body.concat2() + .then(move |result| -> Box> { + match result { + Ok(body) => { + + let mut unused_elements = Vec::new(); + let param_body: Option = if !body.is_empty() { + + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter body - doesn't match schema: {}", e)))), + } + + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter body"))), + }; + + + Box::new(api_impl.update_user(param_username, param_body, &context) + .then(move |result| { + let mut response = Response::new(); + context.x_span_id.as_ref().map(|header| response.headers_mut().set(XSpanId(header.clone()))); + + if !unused_elements.is_empty() { + response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + + match result { + Ok(rsp) => match rsp { + UpdateUserResponse::InvalidUserSupplied + + + => { + response.set_status(StatusCode::try_from(400).unwrap()); + + }, + UpdateUserResponse::UserNotFound + + + => { + response.set_status(StatusCode::try_from(404).unwrap()); + + }, + }, + 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) + } + )) + + + }, + Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter body: {}", e)))), + } + }) + ) as Box> + + }, + + + _ => Box::new(future::ok(Response::new().with_status(StatusCode::NotFound))) as Box>, + } + } +} + +/// Utility function to get the multipart boundary marker (if any) from the Headers. +fn multipart_boundary<'a>(headers: &'a Headers) -> Option<&'a str> { + headers.get::().and_then(|content_type| { + let ContentType(ref mime) = *content_type; + if mime.type_() == mime::MULTIPART && mime.subtype() == mime::FORM_DATA { + mime.get_param(mime::BOUNDARY).map(|x| x.as_str()) + } else { + None + } + }) +}