diff --git a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache index 64fb641c762..6625d274b0a 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache @@ -27,7 +27,7 @@ client = [ "serde_ignored", "regex", "percent-encoding", "lazy_static", {{/hasCallbacks}} {{! Anything added to the list below, should probably be added to the callbacks list below }} - "hyper", "hyper-openssl", "native-tls", "openssl", "url" + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ {{#apiUsesMultipart}} @@ -40,7 +40,7 @@ server = [ "hyper_0_10", "mime_multipart", {{/apiUsesMultipartRelated}} {{#hasCallbacks}} - "native-tls", "hyper-openssl", "openssl", + "native-tls", "hyper-openssl", "hyper-tls", "openssl", {{/hasCallbacks}} {{! Anything added to the list below, should probably be added to the callbacks list above }} "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" @@ -49,20 +49,22 @@ conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk- [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.4", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.7.1", optional = true } +hyper-openssl = { version = "0.8", optional = true } openssl = {version = "0.10", optional = true } [dependencies] # Common +async-trait = "0.1.24" chrono = { version = "0.4", features = ["serde"] } -futures = "0.1" -swagger = "4.0" +futures = "0.3" +swagger = "5.0.0-alpha-1" log = "0.4.0" mime = "0.3" -serde = { version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Crates included if required by the API definition @@ -78,27 +80,27 @@ mime_0_2 = { package = "mime", version = "0.2.6", optional = true } multipart = { version = "0.16", default-features = false, optional = true } {{/apiUsesMultipartFormData}} {{#apiUsesUuid}} -uuid = {version = "0.7", features = ["serde", "v4"]} +uuid = {version = "0.8", features = ["serde", "v4"]} {{/apiUsesUuid}} # Common between server and client features -hyper = {version = "0.12", optional = true} +hyper = {version = "0.13", optional = true} {{#apiUsesMultipartRelated}} mime_multipart = {version = "0.5", optional = true} hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true} {{/apiUsesMultipartRelated}} -serde_ignored = {version = "0.0.4", optional = true} -url = {version = "1.5", optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} # Client-specific {{#usesUrlEncodedForm}} -serde_urlencoded = {version = "0.5.1", optional = true} +serde_urlencoded = {version = "0.6.1", optional = true} {{/usesUrlEncodedForm}} # Server, and client callback-specific lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} # Conversion frunk = { version = "0.3.0", optional = true } @@ -109,15 +111,13 @@ frunk-enum-core = { version = "0.2.0", optional = true } [dev-dependencies] clap = "2.25" -error-chain = "0.12" -env_logger = "0.6" -tokio = "0.1.17" -{{^apiUsesUuid}} -uuid = {version = "0.7", features = ["serde", "v4"]} -{{/apiUsesUuid}} +env_logger = "0.7" +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"] } +native-tls = "0.2" +tokio-tls = "0.3" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] -tokio-openssl = "0.3" +tokio-openssl = "0.4" openssl = "0.10" [[example]] diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache index 1cfedfd0884..673a6856f43 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache @@ -1,26 +1,23 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; + {{#apiUsesMultipartFormData}} use mime::Mime; use std::io::Cursor; @@ -30,20 +27,18 @@ use multipart::client::lazy::Multipart; use hyper_0_10::header::{Headers, ContentType}; use mime_multipart::{Node, Part, generate_boundary, write_multipart}; {{/apiUsesMultipartRelated}} -{{#apiUsesUuid}} -use uuid; -{{/apiUsesUuid}} -{{#usesXml}} -use serde_xml_rs; -{{/usesXml}} use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache index fb9028992fd..506cf8c8654 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache @@ -8,11 +8,11 @@ pub mod callbacks; {{/hasCallbacks}} /// 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 { +fn into_base_path(input: impl TryInto, 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 uri = input.try_into()?; - let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?; + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; // Check the scheme if necessary if let Some(correct_scheme) = correct_scheme { @@ -22,38 +22,54 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result +pub struct Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, /// Base path of the API base_path: String, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client {{ base_path: {} }}", self.base_path) } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), base_path: self.base_path.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -66,30 +82,93 @@ impl Client /// /// # Arguments /// - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn try_new_with_connector( + pub fn try_new_with_connector( base_path: &str, protocol: Option<&'static str>, connector: C, - ) -> Result where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + ) -> Result { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Ok(Client { - client_service: Arc::new(client_service), + Ok(Self { + client_service, base_path: into_base_path(base_path, protocol)?, }) } +} +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(|e| ClientInitError::SslError(e))?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Client> +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" pub fn try_new_http( base_path: &str, ) -> Result { @@ -97,11 +176,20 @@ impl Client Self::try_new_with_connector(base_path, Some("http"), http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -114,7 +202,7 @@ impl Client /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -135,7 +223,7 @@ impl Client /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://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 @@ -161,17 +249,24 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn try_new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, base_path: &str, - ) -> Result { - Ok(Client { - client_service: client_service, + ) -> Result + { + Ok(Self { + client_service, base_path: into_base_path(base_path, None)?, }) } @@ -211,16 +306,29 @@ impl fmt::Display for ClientInitError { } } -impl error::Error for ClientInitError { +impl Error for ClientInitError { fn description(&self) -> &str { "Failed to produce a hyper client." } } -impl Api for Client where - C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}}, - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl Api for Client where + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Clone + Send + Sync + 'static, + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + {{#apiInfo}} {{#apis}} {{#operations}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache index cc65e176ac5..9db3e8c2c5c 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache @@ -1,4 +1,4 @@ - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#vendorExtensions}} {{#callbackParams}} @@ -8,8 +8,9 @@ {{#allParams}} param_{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - context: &C) -> Box + Send> + context: &C) -> Result<{{{operationId}}}Response, ApiError> { + let mut client_service = self.client_service.clone(); let mut uri = format!( {{#isCallbackRequest}} "{{vendorExtensions.x-path-format-string}}" @@ -29,105 +30,113 @@ ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); {{#queryParams}} {{^required}} - if let Some(param_{{{paramName}}}) = param_{{{paramName}}} { + if let Some(param_{{{paramName}}}) = param_{{{paramName}}} { {{/required}} - query_string.append_pair("{{{baseName}}}", ¶m_{{{paramName}}}{{#isListContainer}}.iter().map(ToString::to_string).collect::>().join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}); + query_string.append_pair("{{{baseName}}}", ¶m_{{{paramName}}}{{#isListContainer}}.iter().map(ToString::to_string).collect::>().join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}); {{^required}} - } + } {{/required}} {{/queryParams}} {{#authMethods}} {{#isApiKey}} {{#isKeyInQuery}} - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { - if let AuthData::ApiKey(ref api_key) = *auth_data { - query_string.append_pair("{{keyParamName}}", api_key); + if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let AuthData::ApiKey(ref api_key) = *auth_data { + query_string.append_pair("{{keyParamName}}", api_key); + } } - } {{/isKeyInQuery}} {{/isApiKey}} {{/authMethods}} - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("{{{vendorExtensions.HttpMethod}}}") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; {{#vendorExtensions}} {{#consumesMultipart}} - let mut multipart = Multipart::new(); + let (body_string, multipart_header) = { + let mut multipart = Multipart::new(); {{#vendorExtensions}} {{#formParams}} {{#-first}} - // For each parameter, encode as appropriate and add to the multipart body as a stream. + // For each parameter, encode as appropriate and add to the multipart body as a stream. {{/-first}} {{^isByteArray}} {{#jsonSchema}} - let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{paramName}}}) { - Ok(str) => str, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse {{{paramName}}} to string: {}", e)))), - }; + let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{paramName}}}) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to parse {{{paramName}}} to string: {}", e))), + }; - let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec(); + let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec(); + let {{{paramName}}}_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); - let {{{paramName}}}_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); - - let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); - - multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, None as Option<&str>, Some({{{paramName}}}_mime)); + multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, None as Option<&str>, Some({{{paramName}}}_mime)); {{/jsonSchema}} {{/isByteArray}} + {{#isByteArray}} - let {{{paramName}}}_vec = param_{{{paramName}}}.to_vec(); + let {{{paramName}}}_vec = param_{{{paramName}}}.to_vec(); - let {{{paramName}}}_mime = match mime_0_2::Mime::from_str("application/octet-stream") { - Ok(mime) => mime, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to get mime type: {:?}", err)))), - }; + let {{{paramName}}}_mime = match mime_0_2::Mime::from_str("application/octet-stream") { + Ok(mime) => mime, + Err(err) => return Err(ApiError(format!("Unable to get mime type: {:?}", err))), + }; - let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); + let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); - let filename = None as Option<&str> ; - multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, filename, Some({{{paramName}}}_mime)); + let filename = None as Option<&str> ; + multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, filename, Some({{{paramName}}}_mime)); {{/isByteArray}} {{/formParams}} {{/vendorExtensions}} - let mut fields = match multipart.prepare() { - Ok(fields) => fields, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build request: {}", err)))), + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), + }; + + let mut body_string = String::new(); + + match fields.read_to_string(&mut body_string) { + Ok(_) => (), + Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), + } + + let boundary = fields.boundary(); + + let multipart_header = format!("multipart/form-data;boundary={}", boundary); + + (body_string, multipart_header) }; - let mut body_string = String::new(); - match fields.read_to_string(&mut body_string) { - Ok(_) => (), - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build body: {}", err)))), - } - let boundary = fields.boundary(); - - let multipart_header = format!("multipart/form-data;boundary={}", boundary); - *request.body_mut() = Body::from(body_string); request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) }); {{/consumesMultipart}} @@ -146,7 +155,7 @@ let header = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); *request.body_mut() = Body::from(body.into_bytes()); {{/-last}} @@ -209,7 +218,7 @@ &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() ) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); {{/-last}} @@ -264,7 +273,7 @@ let header = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); {{#-last}} @@ -272,14 +281,14 @@ {{/bodyParam}} {{/consumesMultipart}} {{/vendorExtensions}} - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); {{#hasAuthMethods}} - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { {{#authMethods}} @@ -288,7 +297,7 @@ let auth = swagger::auth::Header(basic_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -300,7 +309,7 @@ let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -313,7 +322,7 @@ let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -341,8 +350,8 @@ match header::IntoHeaderValue(param_{{{paramName}}}.clone()).try_into() { Ok(header) => header, Err(e) => { - return Box::new(future::err(ApiError(format!( - "Invalid header {{{paramName}}} - {}", e)))) as Box + Send>; + return Err(ApiError(format!( + "Invalid header {{{paramName}}} - {}", e))); }, }); {{^required}} @@ -356,111 +365,102 @@ {{/isMapContainer}} {{/headerParams}} - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { {{#responses}} - {{{code}}} => { + {{{code}}} => { {{#headers}} - let response_{{{name}}} = match response.headers().get(HeaderName::from_static("{{{nameInLowerCase}}}")) { - Some(response_{{{name}}}) => response_{{{name}}}.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header {{{baseName}}} for response {{{code}}} was not found.")))) as Box + Send>, - }; - let response_{{{name}}} = match TryInto::>::try_into(response_{{{name}}}) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header {{baseName}} for response {{code}} - {}", e)))) as Box + Send>; - }, - }; - let response_{{{name}}} = response_{{{name}}}.0; + let response_{{{name}}} = match response.headers().get(HeaderName::from_static("{{{nameInLowerCase}}}")) { + Some(response_{{{name}}}) => response_{{{name}}}.clone(), + None => { + return Err(ApiError(String::from("Required response header {{{baseName}}} for response {{{code}}} was not found."))); + } + }; + let response_{{{name}}} = match TryInto::>::try_into(response_{{{name}}}) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header {{baseName}} for response {{code}} - {}", e))); + }, + }; + let response_{{{name}}} = response_{{{name}}}.0; {{/headers}} - let body = response.into_body(); - Box::new( + let body = response.into_body(); {{#dataType}} - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; {{#vendorExtensions}} {{#producesBytes}} - Ok(swagger::ByteArray(body.to_vec())) + let body = swagger::ByteArray(body.to_vec()); {{/producesBytes}} {{^producesBytes}} - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; {{#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))) + // 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}}}>(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()) + let body = serde_json::from_str::<{{{dataType}}}>(body)?; {{/producesJson}} {{#producesPlainText}} - Ok(body.to_string()) + let body = body.to_string(); {{/producesPlainText}} - ) {{/producesBytes}} {{/vendorExtensions}} - ) - .map(move |body| { - {{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}} + Ok({{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}} {{^headers}} - (body) + (body) {{/headers}} {{#headers}} {{#-first}} - { - body: body, + { + body: body, {{/-first}} - {{{name}}}: response_{{name}}, + {{{name}}}: response_{{name}}, {{#-last}} - } + } {{/-last}} {{/headers}} - }) + ) {{/dataType}} {{^dataType}} - future::ok( - {{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}} + Ok( + {{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}} {{#headers}} {{#-first}} - { + { {{/-first}} - {{{name}}}: response_{{name}}, + {{{name}}}: response_{{name}}, {{#-last}} - } + } {{/-last}} {{/headers}} - ) + ) {{/dataType}} - ) as Box + Send> - }, -{{/responses}} - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } } - })) +{{/responses}} + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/context.mustache b/modules/openapi-generator/src/main/resources/rust-server/context.mustache index 6c627cbceeb..c8b4d2ef5b2 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/context.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/context.mustache @@ -1,13 +1,12 @@ -use futures::Future; -use hyper; +use futures::future::BoxFuture; use hyper::header::HeaderName; -use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload}; +use hyper::{Error, Request, Response, StatusCode, service::Service}; use url::form_urlencoded; use std::default::Default; use std::io; use std::marker::PhantomData; +use std::task::{Poll, Context}; use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; -use swagger::context::ContextualPayload; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; use crate::Api; @@ -31,58 +30,52 @@ where } // Make a service that adds context. -impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for +impl Service for MakeAddContext where - A: Default + Push, + Target: Send, + A: Default + Push + Send, B: Push, Result = C>, C: Push, Result = D>, D: Send + 'static, - T: hyper::service::MakeService< - &'a SC, - Error = E, - MakeError = ME, - Service = S, - ReqBody = ContextualPayload, - ResBody = OB, - Future = F - >, - S: Service< - Error = E, - ReqBody = ContextualPayload, - ResBody = OB> + 'static, - ME: swagger::ErrorBound, - E: swagger::ErrorBound, - F: Future + Send + 'static, - S::Future: Send, - OB: Payload, + T: Service + Send, + T::Future: Send + 'static { - type ReqBody = hyper::Body; - type ResBody = OB; - type Error = E; - type MakeError = ME; - type Service = AddContext; - type Future = Box + Send + 'static>; + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; - fn make_service(&mut self, ctx: &'a SC) -> Self::Future { - Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s))) + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) } } -/// Middleware to extract authentication data from request -pub struct AddContext { +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, C: Push, Result = D>, - T: Service, { - pub fn new(inner: T) -> AddContext { + pub fn new(inner: T) -> Self { AddContext { inner, marker: PhantomData, @@ -90,24 +83,26 @@ where } } -impl Service for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, C: Push, Result=D>, D: Send + 'static, - T: Service>, - T::Future: Future, Error=T::Error> + Send + 'static + T: Service<(Request, D)> { - type ReqBody = hyper::Body; - type ResBody = T::ResBody; type Error = T::Error; - type Future = Box, Error=T::Error> + Send + 'static>; + type Future = T::Future; + type Response = T::Response; - fn call(&mut self, req: Request) -> Self::Future { - let context = A::default().push(XSpanIdString::get_or_generate(&req)); - let (head, body) = req.into_parts(); - let headers = head.headers.clone(); + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); {{#authMethods}} {{#isBasic}} @@ -119,12 +114,7 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } {{/isBasic}} @@ -137,12 +127,7 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } {{/isOAuth}} @@ -156,18 +141,13 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } {{/isKeyInHeader}} {{#isKeyInQuery}} { - let key = form_urlencoded::parse(head.uri.query().unwrap_or_default().as_bytes()) + let key = form_urlencoded::parse(request.uri().query().unwrap_or_default().as_bytes()) .filter(|e| e.0 == "api_key_query") .map(|e| e.1.clone().into_owned()) .nth(0); @@ -176,11 +156,7 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } {{/isKeyInQuery}} @@ -189,11 +165,7 @@ impl Service for AddContext let context = context.push(None::); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - Box::new(self.inner.call(hyper::Request::from_parts(head, body))) + self.inner.call((request, context)) } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache index b1f7bbeee95..2463d942f99 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache @@ -5,11 +5,18 @@ mod server; {{/hasCallbacks}} #[allow(unused_imports)] -use futures::{Future, future, Stream, stream}; +use futures::{future, Stream, stream}; #[allow(unused_imports)] use {{{externCrateName}}}::{Api, ApiNoContext, Client, ContextWrapperExt, models, - ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, - {{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{{operationId}}}Response, + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} }; use clap::{App, Arg}; @@ -18,7 +25,9 @@ use log::info; // swagger::Has may be unused if there are no examples #[allow(unused_imports)] -use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData}; +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); // rt may be unused if there are no examples #[allow(unused_mut)] @@ -66,21 +75,21 @@ fn main() { matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if matches.is_present("https") { - // Using Simple HTTPS - Client::try_new_https(&base_url) - .expect("Failed to create HTTPS client") - } else { - // Using HTTP - Client::try_new_http( - &base_url) - .expect("Failed to create HTTP client") - }; - - let context: swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString) = + let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, None as Option, XSpanIdString::default()); - let client = client.with_context(context); + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; let mut rt = tokio::runtime::Runtime::new().unwrap(); {{#hasCallbacks}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-client-server.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-client-server.mustache index 43f1ca53a60..126af4cf747 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-client-server.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-client-server.mustache @@ -1,5 +1,5 @@ {{>example-server-common}} -use {{{externCrateName}}}::{CallbackApi, ApiError}; +use {{{externCrateName}}}::CallbackApi; {{#apiInfo}} {{#apis}} {{#operations}} @@ -16,8 +16,12 @@ use {{{externCrateName}}}::{{{operationId}}}Response; {{/apis}} {{/apiInfo}} use {{{externCrateName}}}::client::callbacks::MakeService; +use std::error::Error; +use swagger::ApiError; -impl CallbackApi for Server where C: Has{ +#[async_trait] +impl CallbackApi for Server where C: Has + Send + Sync +{ {{#apiInfo}} {{#apis}} {{#operations}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache index 16fefd9e6eb..b4090357c30 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; -{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}} -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use {{{externCrateName}}}::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = {{{externCrateName}}}::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache index 3d7f7045a77..c0d39f682e5 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache @@ -9,7 +9,8 @@ mod server; /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let matches = App::new("server") @@ -20,5 +21,5 @@ fn main() { let addr = "127.0.0.1:{{{serverPort}}}"; - hyper::rt::run(server::create(addr, matches.is_present("https"))); + server::create(addr, matches.is_present("https")).await; } diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-server-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-server-operation.mustache index f7b1aaa66d0..5caf982d912 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-server-operation.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-server-operation.mustache @@ -1,7 +1,7 @@ {{#summary}} /// {{{summary}}} {{/summary}} - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#vendorExtensions}} {{#callbackParams}} @@ -11,9 +11,9 @@ {{#allParams}} {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - context: &C) -> Box + Send> + context: &C) -> Result<{{{operationId}}}Response, ApiError> { let context = context.clone(); info!("{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{#vendorExtensions}}{{{formatString}}}{{/vendorExtensions}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}, {{{paramName}}}{{/allParams}}, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-server-server.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-server-server.mustache index 18eb8cdd1ef..d04e09aad88 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-server-server.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-server-server.mustache @@ -2,7 +2,6 @@ use {{{externCrateName}}}::{ Api, - ApiError, {{#apiInfo}} {{#apis}} {{#operations}} @@ -14,8 +13,12 @@ use {{{externCrateName}}}::{ {{/apiInfo}} }; use {{{externCrateName}}}::server::MakeService; +use std::error::Error; +use swagger::ApiError; -impl Api for Server where C: Has{ +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ {{#apiInfo}} {{#apis}} {{#operations}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/lib.mustache b/modules/openapi-generator/src/main/resources/rust-server/lib.mustache index e5135683f45..2b5af42776a 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/lib.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/lib.mustache @@ -1,12 +1,12 @@ #![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] +use async_trait::async_trait; use futures::Stream; -use std::io::Error; +use std::error::Error; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import swagger-rs directly")] -pub use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import futures directly")] -pub use futures::Future; +type ServiceError = Box; pub const BASE_PATH: &'static str = "{{{basePathWithoutHost}}}"; {{#appVersion}} @@ -23,7 +23,12 @@ pub const API_VERSION: &'static str = "{{{appVersion}}}"; {{/apis}} {{/apiInfo}} /// API -pub trait Api { +#[async_trait] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + {{#apiInfo}} {{#apis}} {{#operations}} @@ -31,12 +36,12 @@ pub trait Api { {{#summary}} /// {{{summary}}} {{/summary}} - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#allParams}} {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - context: &C) -> Box + Send>; + context: &C) -> Result<{{{operationId}}}Response, ApiError>; {{/operation}} {{/operations}} @@ -44,8 +49,14 @@ pub trait Api { {{/apiInfo}} } -/// API without a `Context` -pub trait ApiNoContext { +/// API where `Context` isn't passed on every API call +#[async_trait] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + {{#apiInfo}} {{#apis}} {{#operations}} @@ -53,12 +64,12 @@ pub trait ApiNoContext { {{#summary}} /// {{{summary}}} {{/summary}} - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#allParams}} {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - ) -> Box + Send>; + ) -> Result<{{{operationId}}}Response, ApiError>; {{/operation}} {{/operations}} @@ -67,18 +78,28 @@ pub trait ApiNoContext { } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a, C> where Self: Sized { +pub trait ContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + {{#apiInfo}} {{#apis}} {{#operations}} @@ -86,14 +107,15 @@ impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { {{#summary}} /// {{{summary}}} {{/summary}} - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#allParams}} {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - ) -> Box + Send> + ) -> Result<{{{operationId}}}Response, ApiError> { - self.api().{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{{paramName}}}, {{/allParams}}&self.context()) + let context = self.context().clone(); + self.api().{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{{paramName}}}, {{/allParams}}&context).await } {{/operation}} @@ -101,6 +123,7 @@ impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { {{/apis}} {{/apiInfo}} } + {{#hasCallbacks}} {{#apiInfo}} @@ -120,7 +143,12 @@ impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { {{/apiInfo}} /// Callback API -pub trait CallbackApi { +#[async_trait] +pub trait CallbackApi { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + {{#apiInfo}} {{#apis}} {{#operations}} @@ -131,7 +159,7 @@ pub trait CallbackApi { {{#summary}} /// {{{summary}}} {{/summary}} - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#vendorExtensions}} {{#callbackParams}} @@ -141,7 +169,7 @@ pub trait CallbackApi { {{#allParams}} {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - context: &C) -> Box + Send>; + context: &C) -> Result<{{{operationId}}}Response, ApiError>; {{/requests}} {{/urls}} @@ -153,7 +181,12 @@ pub trait CallbackApi { } /// Callback API without a `Context` -pub trait CallbackApiNoContext { +#[async_trait] +pub trait CallbackApiNoContext { + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + {{#apiInfo}} {{#apis}} {{#operations}} @@ -164,7 +197,7 @@ pub trait CallbackApiNoContext { {{#summary}} /// {{{summary}}} {{/summary}} - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#vendorExtensions}} {{#callbackParams}} @@ -174,7 +207,7 @@ pub trait CallbackApiNoContext { {{#allParams}} {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - ) -> Box + Send>; + ) -> Result<{{{operationId}}}Response, ApiError>; {{/requests}} {{/urls}} @@ -185,19 +218,28 @@ pub trait CallbackApiNoContext { {{/apiInfo}} } -/// Trait to extend an API to make it easy to bind it to a context. -pub trait CallbackContextWrapperExt<'a, C> where Self: Sized { +pub trait CallbackContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: CallbackApi + Sized, C> CallbackContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> CallbackContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: CallbackApi, C> CallbackApiNoContext for ContextWrapper<'a, T, C> { +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> CallbackApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + {{#apiInfo}} {{#apis}} {{#operations}} @@ -208,7 +250,7 @@ impl<'a, T: CallbackApi, C> CallbackApiNoContext for ContextWrapper<'a, T, C> {{#summary}} /// {{{summary}}} {{/summary}} - fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + async fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( &self, {{#vendorExtensions}} {{#callbackParams}} @@ -218,8 +260,9 @@ impl<'a, T: CallbackApi, C> CallbackApiNoContext for ContextWrapper<'a, T, C> {{#allParams}} {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}, {{/allParams}} - ) -> Box + Send> + ) -> Result<{{{operationId}}}Response, ApiError> { + let context = self.context().clone(); self.api().{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( {{#vendorExtensions}} {{#callbackParams}} @@ -229,7 +272,7 @@ impl<'a, T: CallbackApi, C> CallbackApiNoContext for ContextWrapper<'a, T, C> {{#allParams}} {{{paramName}}}, {{/allParams}} - &self.context()) + &context).await } {{/requests}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache index 76f25f90aa7..c51299077f7 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache @@ -17,29 +17,45 @@ use crate::{{{operationId}}}Response; {{/apiInfo}} /// A client that implements the API by making HTTP calls out to a server. -pub struct Client +pub struct Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client") } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -53,26 +69,33 @@ impl Client /// # Arguments /// /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn new_with_connector( - connector: C, - ) -> Self where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + pub fn new_with_connector(connector: C) -> Self { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Client { - client_service: Arc::new(client_service), + Self { + client_service, } } +} +impl Client> +{ /// Create an HTTP client. pub fn new_http() -> Self { let http_connector = Connector::builder().build(); Self::new_with_connector(http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server. #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] pub fn new_https() -> Result @@ -132,24 +155,43 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, ) -> Self { Client { - client_service: client_service, + client_service, } } } -impl CallbackApi for Client where - C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}}, - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl CallbackApi for Client where + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync, + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(Box::new(e))), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + {{#apiInfo}} {{#apis}} {{#operations}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache index 2edcdd9b98e..9aa79b47ea4 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache @@ -1,38 +1,31 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; +use url::form_urlencoded; {{#apiUsesMultipartRelated}} use hyper_0_10::header::{Headers, ContentType}; use mime_0_2::{TopLevel, SubLevel, Mime as Mime2}; use mime_multipart::{read_multipart_body, Node, Part}; {{/apiUsesMultipartRelated}} -{{#apiUsesUuid}} -use uuid; -{{/apiUsesUuid}} {{#apiUsesMultipartFormData}} use multipart::server::Multipart; use multipart::server::save::SaveResult; {{/apiUsesMultipartFormData}} -{{#usesXml}} -use serde_xml_rs; -{{/usesXml}} #[allow(unused_imports)] use crate::models; use crate::header; pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache index 238ddb03b72..b2c7afd5fdf 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache @@ -1,12 +1,14 @@ -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -16,21 +18,21 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache index cbb011fe9a3..f3306f76a87 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache @@ -4,10 +4,10 @@ { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; {{#authMethods}} {{#isOAuth}} @@ -22,14 +22,14 @@ if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } {{/isOAuth}} @@ -41,10 +41,10 @@ {{#consumesMultipart}} let boundary = match swagger::multipart::boundary(&headers) { Some(boundary) => boundary.to_string(), - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Couldn't find valid multipart body".to_string())) - .expect("Unable to create Bad Request response for incorrect boundary"))), + .expect("Unable to create Bad Request response for incorrect boundary")), }; {{/consumesMultipart}} @@ -64,15 +64,15 @@ 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter {{{baseName}}}: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; {{/pathParams}} @@ -97,19 +97,19 @@ Some(result.0), {{/required}} Err(err) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Invalid header {{{baseName}}} - {}", err))) - .expect("Unable to create Bad Request response for invalid header {{{baseName}}}"))); + .expect("Unable to create Bad Request response for invalid header {{{baseName}}}")); }, }, None => { {{#required}} - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required header {{{baseName}}}")) - .expect("Unable to create Bad Request response for missing required header {{{baseName}}}"))); + .expect("Unable to create Bad Request response for missing required header {{{baseName}}}")); {{/required}} {{^required}} None @@ -143,15 +143,15 @@ 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}"))), + .expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")), }, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required query parameter {{{baseName}}}")) - .expect("Unable to create Bad Request response for missing qeury parameter {{{baseName}}}"))), + .expect("Unable to create Bad Request response for missing qeury parameter {{{baseName}}}")), }; {{/required}} {{^required}} @@ -169,9 +169,8 @@ // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { {{#vendorExtensions}} {{^consumesPlainText}} @@ -191,10 +190,10 @@ }) { Ok(param_{{{paramName}}}) => param_{{{paramName}}}, {{#required}} - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to schema")), {{/required}} {{^required}} Err(_) => None, @@ -208,10 +207,10 @@ {{#isString}} match String::from_utf8(body.to_vec()) { Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}), - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to UTF-8"))), + .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to UTF-8")), } {{/isString}} {{/consumesPlainText}} @@ -222,10 +221,10 @@ {{#required}} let param_{{{paramName}}} = match param_{{{paramName}}} { Some(param_{{{paramName}}}) => param_{{{paramName}}}, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter {{{baseName}}}")) - .expect("Unable to create Bad Request response for missing body parameter {{{baseName}}}"))), + .expect("Unable to create Bad Request response for missing body parameter {{{baseName}}}")), }; {{/required}} {{/-first}} @@ -240,9 +239,8 @@ // Form 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| -> Self::Future { - match result { + let result = body.to_raw(); + match result.await { Ok(body) => { use std::io::Read; @@ -252,10 +250,10 @@ entries }, _ => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Unable to process all message parts"))) - .expect("Unable to create Bad Request response due to failure to process all message"))) + .expect("Unable to create Bad Request response due to failure to process all message")) }, }; {{#formParams}} @@ -278,11 +276,11 @@ let {{{paramName}}}_model: {{{dataType}}} = match serde_json::from_str(&data) { Ok(model) => model, Err(e) => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("{{{paramName}}} data does not match API definition : {}", e))) - .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}"))) + .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")) } }; {{{paramName}}}_model @@ -294,11 +292,11 @@ }, None => { {{#required}} - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Missing required form parameter {{{paramName}}}"))) - .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}"))) + .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")) {{/required}} {{^required}} None @@ -313,8 +311,6 @@ {{^consumesMultipart}} {{^bodyParams}} {{#vendorExtensions}} - Box::new({ - {{ {{#formParams}} {{#-first}} // Form parameters @@ -332,9 +328,8 @@ // 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| -> Self::Future { - match result { + let result = body.to_raw(); + match result.await { Ok(body) => { let mut unused_elements: Vec = vec![]; @@ -354,10 +349,10 @@ multi_part_headers.set(ContentType(content_type_mime)); }, Err(e) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(e)) - .expect("Unable to create Bad Request response due to unable to read content-type header for {{operationId}}"))); + .expect("Unable to create Bad Request response due to unable to read content-type header for {{operationId}}")); } } @@ -366,10 +361,10 @@ let nodes = match read_multipart_body(&mut&*body, &multi_part_headers, false) { Ok(nodes) => nodes, Err(e) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Could not read multipart body for {{operationId}}: {}", e))) - .expect("Unable to create Bad Request response due to unable to read multipart body for {{operationId}}"))); + .expect("Unable to create Bad Request response due to unable to read multipart body for {{operationId}}")); } }; @@ -391,10 +386,10 @@ unused_elements.push(path.to_string()); }) { Ok(json_data) => json_data, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter {{dataType}} due to schema"))) + .expect("Unable to create Bad Request response for invalid body parameter {{dataType}} due to schema")) }; // Push JSON part to return object. param_{{{paramName}}}.get_or_insert(json_data); @@ -427,10 +422,10 @@ {{#required}} let param_{{{paramName}}} = match param_required_binary_field { Some(x) => x, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Missing required multipart/related parameter {{{paramName}}}"))) - .expect("Unable to create Bad Request response for missing multipart/related parameter {{{paramName}}} due to schema"))) + .expect("Unable to create Bad Request response for missing multipart/related parameter {{{paramName}}} due to schema")) }; {{/required}} {{#-last}} @@ -439,8 +434,7 @@ {{/formParams}} {{/consumesMultipartRelated}} {{/vendorExtensions}} - Box::new( - api_impl.{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( + let result = api_impl.{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}( {{#vendorExtensions}} {{#callbackParams}} callback_{{.}}, @@ -450,9 +444,9 @@ param_{{{paramName}}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}} &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -505,7 +499,7 @@ let {{{name}}} = match header::IntoHeaderValue({{{name}}}).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling {{name}} header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -569,26 +563,18 @@ }, } - future::ok(response) - } - )) + Ok(response) {{#vendorExtensions}} {{^consumesMultipart}} {{^bodyParams}} {{#vendorExtensions}} {{#consumesMultipartRelated}} }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter {{{baseName}}}: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}"))), + .expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}")), } - }) - ) as Self::Future -{{/consumesMultipartRelated}} -{{^consumesMultipartRelated}} - }} - }) as Self::Future {{/consumesMultipartRelated}} {{/vendorExtensions}} {{/bodyParams}} @@ -597,28 +583,23 @@ {{#bodyParams}} {{#-first}} }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter {{{baseName}}}: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}"))), + .expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}")), } - }) - ) as Self::Future {{/-first}} {{/bodyParams}} {{#vendorExtensions}} {{#consumesMultipart}} {{^bodyParams}} {{#vendorExtensions}} - as Self::Future }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read multipart body"))) - .expect("Unable to create Bad Request response due to unable read multipart body"))), + .expect("Unable to create Bad Request response due to unable read multipart body")), } - }) - ) {{/vendorExtensions}} {{/bodyParams}} {{/consumesMultipart}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache index 568c8fb801d..25e9c12a5b3 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache @@ -1,18 +1,6 @@ - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache index da785bbbfb4..76c0e9a8540 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache @@ -1,22 +1,23 @@ -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -25,23 +26,38 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static + Send + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; {{! This match statement is duplicated below in `parse_operation_id()`. diff --git a/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml b/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml index 2caa6327e8f..eaca5af92e2 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml @@ -12,7 +12,7 @@ client = [ "mime_0_2", "multipart", "multipart/client", "swagger/multipart", "hyper_0_10", "mime_multipart", - "hyper", "hyper-openssl", "native-tls", "openssl", "url" + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "mime_0_2", @@ -24,20 +24,22 @@ conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk- [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.4", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.7.1", optional = true } +hyper-openssl = { version = "0.8", optional = true } openssl = {version = "0.10", optional = true } [dependencies] # Common +async-trait = "0.1.24" chrono = { version = "0.4", features = ["serde"] } -futures = "0.1" -swagger = "4.0" +futures = "0.3" +swagger = "5.0.0-alpha-1" log = "0.4.0" mime = "0.3" -serde = { version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Crates included if required by the API definition @@ -45,18 +47,18 @@ mime_0_2 = { package = "mime", version = "0.2.6", optional = true } multipart = { version = "0.16", default-features = false, optional = true } # Common between server and client features -hyper = {version = "0.12", optional = true} +hyper = {version = "0.13", optional = true} mime_multipart = {version = "0.5", optional = true} hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true} -serde_ignored = {version = "0.0.4", optional = true} -url = {version = "1.5", optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} # Client-specific # Server, and client callback-specific lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} # Conversion frunk = { version = "0.3.0", optional = true } @@ -67,13 +69,13 @@ frunk-enum-core = { version = "0.2.0", optional = true } [dev-dependencies] clap = "2.25" -error-chain = "0.12" -env_logger = "0.6" -tokio = "0.1.17" -uuid = {version = "0.7", features = ["serde", "v4"]} +env_logger = "0.7" +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"] } +native-tls = "0.2" +tokio-tls = "0.3" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] -tokio-openssl = "0.3" +tokio-openssl = "0.4" openssl = "0.10" [[example]] diff --git a/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs index b6ac0eea5f1..2723cbfc98d 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs @@ -2,13 +2,12 @@ #[allow(unused_imports)] -use futures::{Future, future, Stream, stream}; +use futures::{future, Stream, stream}; #[allow(unused_imports)] use multipart_v3::{Api, ApiNoContext, Client, ContextWrapperExt, models, - ApiError, MultipartRelatedRequestPostResponse, MultipartRequestPostResponse, - MultipleIdenticalMimeTypesPostResponse + MultipleIdenticalMimeTypesPostResponse, }; use clap::{App, Arg}; @@ -17,7 +16,9 @@ use log::info; // swagger::Has may be unused if there are no examples #[allow(unused_imports)] -use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData}; +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); // rt may be unused if there are no examples #[allow(unused_mut)] @@ -55,21 +56,21 @@ fn main() { matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if matches.is_present("https") { - // Using Simple HTTPS - Client::try_new_https(&base_url) - .expect("Failed to create HTTPS client") - } else { - // Using HTTP - Client::try_new_http( - &base_url) - .expect("Failed to create HTTP client") - }; - - let context: swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString) = + let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, None as Option, XSpanIdString::default()); - let client = client.with_context(context); + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; let mut rt = tokio::runtime::Runtime::new().unwrap(); diff --git a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs index 02fc2a751b0..834961ce82e 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs @@ -9,7 +9,8 @@ mod server; /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let matches = App::new("server") @@ -20,5 +21,5 @@ fn main() { let addr = "127.0.0.1:8080"; - hyper::rt::run(server::create(addr, matches.is_present("https"))); + server::create(addr, matches.is_present("https")).await; } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs index 4c6938ce12c..b8977da45a3 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; - -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use multipart_v3::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = multipart_v3::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } @@ -105,48 +96,51 @@ impl Server { use multipart_v3::{ Api, - ApiError, MultipartRelatedRequestPostResponse, MultipartRequestPostResponse, MultipleIdenticalMimeTypesPostResponse, }; use multipart_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; -impl Api for Server where C: Has{ - fn multipart_related_request_post( +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn multipart_related_request_post( &self, required_binary_field: swagger::ByteArray, object_field: Option, optional_binary_field: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("multipart_related_request_post({:?}, {:?}, {:?}) - X-Span-ID: {:?}", required_binary_field, object_field, optional_binary_field, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn multipart_request_post( + async fn multipart_request_post( &self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option, object_field: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("multipart_request_post(\"{}\", {:?}, {:?}, {:?}) - X-Span-ID: {:?}", string_field, binary_field, optional_string_field, object_field, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn multiple_identical_mime_types_post( + async fn multiple_identical_mime_types_post( &self, binary1: Option, binary2: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("multiple_identical_mime_types_post({:?}, {:?}) - X-Span-ID: {:?}", binary1, binary2, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs index ed3ab5d92b7..44319896f1e 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs @@ -1,26 +1,23 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; + use mime::Mime; use std::io::Cursor; use multipart::client::lazy::Multipart; @@ -30,13 +27,17 @@ use mime_multipart::{Node, Part, generate_boundary, write_multipart}; use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); use crate::{Api, MultipartRelatedRequestPostResponse, @@ -45,11 +46,11 @@ use crate::{Api, }; /// 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 { +fn into_base_path(input: impl TryInto, 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 uri = input.try_into()?; - let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?; + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; // Check the scheme if necessary if let Some(correct_scheme) = correct_scheme { @@ -59,38 +60,54 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result +pub struct Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, /// Base path of the API base_path: String, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client {{ base_path: {} }}", self.base_path) } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), base_path: self.base_path.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -103,30 +120,93 @@ impl Client /// /// # Arguments /// - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn try_new_with_connector( + pub fn try_new_with_connector( base_path: &str, protocol: Option<&'static str>, connector: C, - ) -> Result where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + ) -> Result { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Ok(Client { - client_service: Arc::new(client_service), + Ok(Self { + client_service, base_path: into_base_path(base_path, protocol)?, }) } +} +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(|e| ClientInitError::SslError(e))?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Client> +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" pub fn try_new_http( base_path: &str, ) -> Result { @@ -134,11 +214,20 @@ impl Client Self::try_new_with_connector(base_path, Some("http"), http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -151,7 +240,7 @@ impl Client /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -172,7 +261,7 @@ impl Client /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://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 @@ -198,17 +287,24 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn try_new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, base_path: &str, - ) -> Result { - Ok(Client { - client_service: client_service, + ) -> Result + { + Ok(Self { + client_service, base_path: into_base_path(base_path, None)?, }) } @@ -248,47 +344,63 @@ impl fmt::Display for ClientInitError { } } -impl error::Error for ClientInitError { +impl Error for ClientInitError { fn description(&self) -> &str { "Failed to produce a hyper client." } } -impl Api for Client where - C: Has , - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl Api for Client where + C: Has + Clone + Send + Sync + 'static, + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - fn multipart_related_request_post( + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn multipart_related_request_post( &self, param_required_binary_field: swagger::ByteArray, param_object_field: Option, param_optional_binary_field: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/multipart_related_request", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Construct the Body for a multipart/related request. The mime 0.2.6 library @@ -359,229 +471,230 @@ impl Api for Client where &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() ) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 201 => { - let body = response.into_body(); - Box::new( - future::ok( - MultipartRelatedRequestPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + Ok( + MultipartRelatedRequestPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn multipart_request_post( + async fn multipart_request_post( &self, param_string_field: String, param_binary_field: swagger::ByteArray, param_optional_string_field: Option, param_object_field: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/multipart_request", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let mut multipart = Multipart::new(); + let (body_string, multipart_header) = { + let mut multipart = Multipart::new(); - // For each parameter, encode as appropriate and add to the multipart body as a stream. + // For each parameter, encode as appropriate and add to the multipart body as a stream. - let string_field_str = match serde_json::to_string(¶m_string_field) { - Ok(str) => str, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse string_field to string: {}", e)))), + let string_field_str = match serde_json::to_string(¶m_string_field) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to parse string_field to string: {}", e))), + }; + + let string_field_vec = string_field_str.as_bytes().to_vec(); + let string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let string_field_cursor = Cursor::new(string_field_vec); + + multipart.add_stream("string_field", string_field_cursor, None as Option<&str>, Some(string_field_mime)); + + + let optional_string_field_str = match serde_json::to_string(¶m_optional_string_field) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to parse optional_string_field to string: {}", e))), + }; + + let optional_string_field_vec = optional_string_field_str.as_bytes().to_vec(); + let optional_string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let optional_string_field_cursor = Cursor::new(optional_string_field_vec); + + multipart.add_stream("optional_string_field", optional_string_field_cursor, None as Option<&str>, Some(optional_string_field_mime)); + + + let object_field_str = match serde_json::to_string(¶m_object_field) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to parse object_field to string: {}", e))), + }; + + let object_field_vec = object_field_str.as_bytes().to_vec(); + let object_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let object_field_cursor = Cursor::new(object_field_vec); + + multipart.add_stream("object_field", object_field_cursor, None as Option<&str>, Some(object_field_mime)); + + + + let binary_field_vec = param_binary_field.to_vec(); + + let binary_field_mime = match mime_0_2::Mime::from_str("application/octet-stream") { + Ok(mime) => mime, + Err(err) => return Err(ApiError(format!("Unable to get mime type: {:?}", err))), + }; + + let binary_field_cursor = Cursor::new(binary_field_vec); + + let filename = None as Option<&str> ; + multipart.add_stream("binary_field", binary_field_cursor, filename, Some(binary_field_mime)); + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), + }; + + let mut body_string = String::new(); + + match fields.read_to_string(&mut body_string) { + Ok(_) => (), + Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), + } + + let boundary = fields.boundary(); + + let multipart_header = format!("multipart/form-data;boundary={}", boundary); + + (body_string, multipart_header) }; - let string_field_vec = string_field_str.as_bytes().to_vec(); - - let string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); - - let string_field_cursor = Cursor::new(string_field_vec); - - multipart.add_stream("string_field", string_field_cursor, None as Option<&str>, Some(string_field_mime)); - - let optional_string_field_str = match serde_json::to_string(¶m_optional_string_field) { - Ok(str) => str, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse optional_string_field to string: {}", e)))), - }; - - let optional_string_field_vec = optional_string_field_str.as_bytes().to_vec(); - - let optional_string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); - - let optional_string_field_cursor = Cursor::new(optional_string_field_vec); - - multipart.add_stream("optional_string_field", optional_string_field_cursor, None as Option<&str>, Some(optional_string_field_mime)); - - let object_field_str = match serde_json::to_string(¶m_object_field) { - Ok(str) => str, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse object_field to string: {}", e)))), - }; - - let object_field_vec = object_field_str.as_bytes().to_vec(); - - let object_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); - - let object_field_cursor = Cursor::new(object_field_vec); - - multipart.add_stream("object_field", object_field_cursor, None as Option<&str>, Some(object_field_mime)); - - let binary_field_vec = param_binary_field.to_vec(); - - let binary_field_mime = match mime_0_2::Mime::from_str("application/octet-stream") { - Ok(mime) => mime, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to get mime type: {:?}", err)))), - }; - - let binary_field_cursor = Cursor::new(binary_field_vec); - - let filename = None as Option<&str> ; - multipart.add_stream("binary_field", binary_field_cursor, filename, Some(binary_field_mime)); - let mut fields = match multipart.prepare() { - Ok(fields) => fields, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build request: {}", err)))), - }; - - let mut body_string = String::new(); - match fields.read_to_string(&mut body_string) { - Ok(_) => (), - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build body: {}", err)))), - } - let boundary = fields.boundary(); - - let multipart_header = format!("multipart/form-data;boundary={}", boundary); - *request.body_mut() = Body::from(body_string); request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 201 => { - let body = response.into_body(); - Box::new( - future::ok( - MultipartRequestPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + Ok( + MultipartRequestPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn multiple_identical_mime_types_post( + async fn multiple_identical_mime_types_post( &self, param_binary1: Option, param_binary2: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/multiple-identical-mime-types", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Construct the Body for a multipart/related request. The mime 0.2.6 library @@ -637,48 +750,43 @@ impl Api for Client where &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() ) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - MultipleIdenticalMimeTypesPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + MultipleIdenticalMimeTypesPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs index d14e73f822d..fadd880b965 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs @@ -1,13 +1,12 @@ -use futures::Future; -use hyper; +use futures::future::BoxFuture; use hyper::header::HeaderName; -use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload}; +use hyper::{Error, Request, Response, StatusCode, service::Service}; use url::form_urlencoded; use std::default::Default; use std::io; use std::marker::PhantomData; +use std::task::{Poll, Context}; use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; -use swagger::context::ContextualPayload; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; use crate::Api; @@ -31,58 +30,52 @@ where } // Make a service that adds context. -impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for +impl Service for MakeAddContext where - A: Default + Push, + Target: Send, + A: Default + Push + Send, B: Push, Result = C>, C: Push, Result = D>, D: Send + 'static, - T: hyper::service::MakeService< - &'a SC, - Error = E, - MakeError = ME, - Service = S, - ReqBody = ContextualPayload, - ResBody = OB, - Future = F - >, - S: Service< - Error = E, - ReqBody = ContextualPayload, - ResBody = OB> + 'static, - ME: swagger::ErrorBound, - E: swagger::ErrorBound, - F: Future + Send + 'static, - S::Future: Send, - OB: Payload, + T: Service + Send, + T::Future: Send + 'static { - type ReqBody = hyper::Body; - type ResBody = OB; - type Error = E; - type MakeError = ME; - type Service = AddContext; - type Future = Box + Send + 'static>; + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; - fn make_service(&mut self, ctx: &'a SC) -> Self::Future { - Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s))) + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) } } -/// Middleware to extract authentication data from request -pub struct AddContext { +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, C: Push, Result = D>, - T: Service, { - pub fn new(inner: T) -> AddContext { + pub fn new(inner: T) -> Self { AddContext { inner, marker: PhantomData, @@ -90,33 +83,31 @@ where } } -impl Service for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, C: Push, Result=D>, D: Send + 'static, - T: Service>, - T::Future: Future, Error=T::Error> + Send + 'static + T: Service<(Request, D)> { - type ReqBody = hyper::Body; - type ResBody = T::ResBody; type Error = T::Error; - type Future = Box, Error=T::Error> + Send + 'static>; + type Future = T::Future; + type Response = T::Response; - fn call(&mut self, req: Request) -> Self::Future { - let context = A::default().push(XSpanIdString::get_or_generate(&req)); - let (head, body) = req.into_parts(); - let headers = head.headers.clone(); + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); let context = context.push(None::); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - Box::new(self.inner.call(hyper::Request::from_parts(head, body))) + self.inner.call((request, context)) } } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs index b1ab43ac849..2415ea2ce4e 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs @@ -1,12 +1,12 @@ #![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] +use async_trait::async_trait; use futures::Stream; -use std::io::Error; +use std::error::Error; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import swagger-rs directly")] -pub use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import futures directly")] -pub use futures::Future; +type ServiceError = Box; pub const BASE_PATH: &'static str = ""; pub const API_VERSION: &'static str = "1.0.7"; @@ -30,100 +30,125 @@ pub enum MultipleIdenticalMimeTypesPostResponse { } /// API -pub trait Api { - fn multipart_related_request_post( +#[async_trait] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn multipart_related_request_post( &self, required_binary_field: swagger::ByteArray, object_field: Option, optional_binary_field: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn multipart_request_post( + async fn multipart_request_post( &self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option, object_field: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn multiple_identical_mime_types_post( + async fn multiple_identical_mime_types_post( &self, binary1: Option, binary2: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; } -/// API without a `Context` -pub trait ApiNoContext { - fn multipart_related_request_post( +/// API where `Context` isn't passed on every API call +#[async_trait] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn multipart_related_request_post( &self, required_binary_field: swagger::ByteArray, object_field: Option, optional_binary_field: Option, - ) -> Box + Send>; + ) -> Result; - fn multipart_request_post( + async fn multipart_request_post( &self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option, object_field: Option, - ) -> Box + Send>; + ) -> Result; - fn multiple_identical_mime_types_post( + async fn multiple_identical_mime_types_post( &self, binary1: Option, binary2: Option, - ) -> Box + Send>; + ) -> Result; } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a, C> where Self: Sized { +pub trait ContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { - fn multipart_related_request_post( +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn multipart_related_request_post( &self, required_binary_field: swagger::ByteArray, object_field: Option, optional_binary_field: Option, - ) -> Box + Send> + ) -> Result { - self.api().multipart_related_request_post(required_binary_field, object_field, optional_binary_field, &self.context()) + let context = self.context().clone(); + self.api().multipart_related_request_post(required_binary_field, object_field, optional_binary_field, &context).await } - fn multipart_request_post( + async fn multipart_request_post( &self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option, object_field: Option, - ) -> Box + Send> + ) -> Result { - self.api().multipart_request_post(string_field, binary_field, optional_string_field, object_field, &self.context()) + let context = self.context().clone(); + self.api().multipart_request_post(string_field, binary_field, optional_string_field, object_field, &context).await } - fn multiple_identical_mime_types_post( + async fn multiple_identical_mime_types_post( &self, binary1: Option, binary2: Option, - ) -> Box + Send> + ) -> Result { - self.api().multiple_identical_mime_types_post(binary1, binary2, &self.context()) + let context = self.context().clone(); + self.api().multiple_identical_mime_types_post(binary1, binary2, &context).await } } + #[cfg(feature = "client")] pub mod client; diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs index eb870f1833e..72cf6b4f20e 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs @@ -1,20 +1,17 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; +use url::form_urlencoded; use hyper_0_10::header::{Headers, ContentType}; use mime_0_2::{TopLevel, SubLevel, Mime as Mime2}; use mime_multipart::{read_multipart_body, Node, Part}; @@ -27,6 +24,8 @@ use crate::header; pub use crate::context; +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + use crate::{Api, MultipartRelatedRequestPostResponse, MultipartRequestPostResponse, @@ -49,15 +48,17 @@ mod paths { pub(crate) static ID_MULTIPLE_IDENTICAL_MIME_TYPES: usize = 2; } -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -67,44 +68,45 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -113,23 +115,38 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has + 'static + Send + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; match &method { @@ -138,9 +155,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw(); + match result.await { Ok(body) => { let mut unused_elements: Vec = vec![]; @@ -160,10 +176,10 @@ where multi_part_headers.set(ContentType(content_type_mime)); }, Err(e) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(e)) - .expect("Unable to create Bad Request response due to unable to read content-type header for MultipartRelatedRequestPost"))); + .expect("Unable to create Bad Request response due to unable to read content-type header for MultipartRelatedRequestPost")); } } @@ -172,10 +188,10 @@ where let nodes = match read_multipart_body(&mut&*body, &multi_part_headers, false) { Ok(nodes) => nodes, Err(e) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Could not read multipart body for MultipartRelatedRequestPost: {}", e))) - .expect("Unable to create Bad Request response due to unable to read multipart body for MultipartRelatedRequestPost"))); + .expect("Unable to create Bad Request response due to unable to read multipart body for MultipartRelatedRequestPost")); } }; @@ -195,10 +211,10 @@ where unused_elements.push(path.to_string()); }) { Ok(json_data) => json_data, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter models::MultipartRequestObjectField - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter models::MultipartRequestObjectField due to schema"))) + .expect("Unable to create Bad Request response for invalid body parameter models::MultipartRequestObjectField due to schema")) }; // Push JSON part to return object. param_object_field.get_or_insert(json_data); @@ -226,21 +242,20 @@ where // Check that the required multipart chunks are present. let param_required_binary_field = match param_required_binary_field { Some(x) => x, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Missing required multipart/related parameter required_binary_field"))) - .expect("Unable to create Bad Request response for missing multipart/related parameter required_binary_field due to schema"))) + .expect("Unable to create Bad Request response for missing multipart/related parameter required_binary_field due to schema")) }; - Box::new( - api_impl.multipart_related_request_post( + let result = api_impl.multipart_related_request_post( param_required_binary_field, param_object_field, param_optional_binary_field, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -260,35 +275,30 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter Default: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter Default"))), + .expect("Unable to create Bad Request response due to unable to read body parameter Default")), } - }) - ) as Self::Future }, // MultipartRequestPost - POST /multipart_request &hyper::Method::POST if path.matched(paths::ID_MULTIPART_REQUEST) => { let boundary = match swagger::multipart::boundary(&headers) { Some(boundary) => boundary.to_string(), - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Couldn't find valid multipart body".to_string())) - .expect("Unable to create Bad Request response for incorrect boundary"))), + .expect("Unable to create Bad Request response for incorrect boundary")), }; // Form 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| -> Self::Future { - match result { + let result = body.to_raw(); + match result.await { Ok(body) => { use std::io::Read; @@ -298,10 +308,10 @@ where entries }, _ => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Unable to process all message parts"))) - .expect("Unable to create Bad Request response due to failure to process all message"))) + .expect("Unable to create Bad Request response due to failure to process all message")) }, }; let field_string_field = entries.fields.remove("string_field"); @@ -313,21 +323,21 @@ where let string_field_model: String = match serde_json::from_str(&data) { Ok(model) => model, Err(e) => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("string_field data does not match API definition : {}", e))) - .expect("Unable to create Bad Request due to missing required form parameter string_field"))) + .expect("Unable to create Bad Request due to missing required form parameter string_field")) } }; string_field_model }, None => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Missing required form parameter string_field"))) - .expect("Unable to create Bad Request due to missing required form parameter string_field"))) + .expect("Unable to create Bad Request due to missing required form parameter string_field")) } }; let field_optional_string_field = entries.fields.remove("optional_string_field"); @@ -340,11 +350,11 @@ where let optional_string_field_model: String = match serde_json::from_str(&data) { Ok(model) => model, Err(e) => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("optional_string_field data does not match API definition : {}", e))) - .expect("Unable to create Bad Request due to missing required form parameter optional_string_field"))) + .expect("Unable to create Bad Request due to missing required form parameter optional_string_field")) } }; optional_string_field_model @@ -364,11 +374,11 @@ where let object_field_model: models::MultipartRequestObjectField = match serde_json::from_str(&data) { Ok(model) => model, Err(e) => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("object_field data does not match API definition : {}", e))) - .expect("Unable to create Bad Request due to missing required form parameter object_field"))) + .expect("Unable to create Bad Request due to missing required form parameter object_field")) } }; object_field_model @@ -387,23 +397,22 @@ where swagger::ByteArray(data) }, None => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Missing required form parameter binary_field"))) - .expect("Unable to create Bad Request due to missing required form parameter binary_field"))) + .expect("Unable to create Bad Request due to missing required form parameter binary_field")) } }; - Box::new( - api_impl.multipart_request_post( + let result = api_impl.multipart_request_post( param_string_field, param_binary_field, param_optional_string_field, param_object_field, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -423,18 +432,13 @@ where }, } - future::ok(response) - } - )) - as Self::Future + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read multipart body"))) - .expect("Unable to create Bad Request response due to unable read multipart body"))), + .expect("Unable to create Bad Request response due to unable read multipart body")), } - }) - ) }, // MultipleIdenticalMimeTypesPost - POST /multiple-identical-mime-types @@ -442,9 +446,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw(); + match result.await { Ok(body) => { let mut unused_elements: Vec = vec![]; @@ -464,10 +467,10 @@ where multi_part_headers.set(ContentType(content_type_mime)); }, Err(e) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(e)) - .expect("Unable to create Bad Request response due to unable to read content-type header for MultipleIdenticalMimeTypesPost"))); + .expect("Unable to create Bad Request response due to unable to read content-type header for MultipleIdenticalMimeTypesPost")); } } @@ -476,10 +479,10 @@ where let nodes = match read_multipart_body(&mut&*body, &multi_part_headers, false) { Ok(nodes) => nodes, Err(e) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Could not read multipart body for MultipleIdenticalMimeTypesPost: {}", e))) - .expect("Unable to create Bad Request response due to unable to read multipart body for MultipleIdenticalMimeTypesPost"))); + .expect("Unable to create Bad Request response due to unable to read multipart body for MultipleIdenticalMimeTypesPost")); } }; @@ -512,14 +515,13 @@ where // Check that the required multipart chunks are present. - Box::new( - api_impl.multiple_identical_mime_types_post( + let result = api_impl.multiple_identical_mime_types_post( param_binary1, param_binary2, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -539,39 +541,23 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter Default: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter Default"))), + .expect("Unable to create Bad Request response due to unable to read body parameter Default")), } - }) - ) as Self::Future }, _ if path.matched(paths::ID_MULTIPART_RELATED_REQUEST) => method_not_allowed(), _ if path.matched(paths::ID_MULTIPART_REQUEST) => method_not_allowed(), _ if path.matched(paths::ID_MULTIPLE_IDENTICAL_MIME_TYPES) => method_not_allowed(), - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } /// Request parser for `Api`. diff --git a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml index b8dc9850d73..da632fac28d 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "hyper", "hyper-openssl", "native-tls", "openssl", "url" + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" @@ -18,35 +18,37 @@ conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk- [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.4", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.7.1", optional = true } +hyper-openssl = { version = "0.8", optional = true } openssl = {version = "0.10", optional = true } [dependencies] # Common +async-trait = "0.1.24" chrono = { version = "0.4", features = ["serde"] } -futures = "0.1" -swagger = "4.0" +futures = "0.3" +swagger = "5.0.0-alpha-1" log = "0.4.0" mime = "0.3" -serde = { version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Crates included if required by the API definition # Common between server and client features -hyper = {version = "0.12", optional = true} -serde_ignored = {version = "0.0.4", optional = true} -url = {version = "1.5", optional = true} +hyper = {version = "0.13", optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} # Client-specific # Server, and client callback-specific lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} # Conversion frunk = { version = "0.3.0", optional = true } @@ -57,13 +59,13 @@ frunk-enum-core = { version = "0.2.0", optional = true } [dev-dependencies] clap = "2.25" -error-chain = "0.12" -env_logger = "0.6" -tokio = "0.1.17" -uuid = {version = "0.7", features = ["serde", "v4"]} +env_logger = "0.7" +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"] } +native-tls = "0.2" +tokio-tls = "0.3" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] -tokio-openssl = "0.3" +tokio-openssl = "0.4" openssl = "0.10" [[example]] diff --git a/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs index 1f404ee95b6..ce34c07c8d5 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs @@ -2,11 +2,10 @@ #[allow(unused_imports)] -use futures::{Future, future, Stream, stream}; +use futures::{future, Stream, stream}; #[allow(unused_imports)] use no_example_v3::{Api, ApiNoContext, Client, ContextWrapperExt, models, - ApiError, - OpGetResponse + OpGetResponse, }; use clap::{App, Arg}; @@ -15,7 +14,9 @@ use log::info; // swagger::Has may be unused if there are no examples #[allow(unused_imports)] -use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData}; +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); // rt may be unused if there are no examples #[allow(unused_mut)] @@ -50,21 +51,21 @@ fn main() { matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if matches.is_present("https") { - // Using Simple HTTPS - Client::try_new_https(&base_url) - .expect("Failed to create HTTPS client") - } else { - // Using HTTP - Client::try_new_http( - &base_url) - .expect("Failed to create HTTP client") - }; - - let context: swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString) = + let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, None as Option, XSpanIdString::default()); - let client = client.with_context(context); + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; let mut rt = tokio::runtime::Runtime::new().unwrap(); diff --git a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs index 30b1c5c5e12..d1a25ec9b63 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs @@ -9,7 +9,8 @@ mod server; /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let matches = App::new("server") @@ -20,5 +21,5 @@ fn main() { let addr = "127.0.0.1:8080"; - hyper::rt::run(server::create(addr, matches.is_present("https"))); + server::create(addr, matches.is_present("https")).await; } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs index 0ec693c32e5..5da31b0d716 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; - -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use no_example_v3::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = no_example_v3::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } @@ -105,20 +96,23 @@ impl Server { use no_example_v3::{ Api, - ApiError, OpGetResponse, }; use no_example_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; -impl Api for Server where C: Has{ - fn op_get( +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn op_get( &self, inline_object: models::InlineObject, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op_get({:?}) - X-Span-ID: {:?}", inline_object, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs index 4e55ac6c63d..5948c84d2eb 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs @@ -1,48 +1,49 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; + use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); use crate::{Api, OpGetResponse }; /// 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 { +fn into_base_path(input: impl TryInto, 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 uri = input.try_into()?; - let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?; + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; // Check the scheme if necessary if let Some(correct_scheme) = correct_scheme { @@ -52,38 +53,54 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result +pub struct Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, /// Base path of the API base_path: String, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client {{ base_path: {} }}", self.base_path) } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), base_path: self.base_path.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -96,30 +113,93 @@ impl Client /// /// # Arguments /// - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn try_new_with_connector( + pub fn try_new_with_connector( base_path: &str, protocol: Option<&'static str>, connector: C, - ) -> Result where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + ) -> Result { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Ok(Client { - client_service: Arc::new(client_service), + Ok(Self { + client_service, base_path: into_base_path(base_path, protocol)?, }) } +} +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(|e| ClientInitError::SslError(e))?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Client> +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" pub fn try_new_http( base_path: &str, ) -> Result { @@ -127,11 +207,20 @@ impl Client Self::try_new_with_connector(base_path, Some("http"), http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -144,7 +233,7 @@ impl Client /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -165,7 +254,7 @@ impl Client /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://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 @@ -191,17 +280,24 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn try_new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, base_path: &str, - ) -> Result { - Ok(Client { - client_service: client_service, + ) -> Result + { + Ok(Self { + client_service, base_path: into_base_path(base_path, None)?, }) } @@ -241,45 +337,61 @@ impl fmt::Display for ClientInitError { } } -impl error::Error for ClientInitError { +impl Error for ClientInitError { fn description(&self) -> &str { "Failed to produce a hyper client." } } -impl Api for Client where - C: Has , - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl Api for Client where + C: Has + Clone + Send + Sync + 'static, + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - fn op_get( + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn op_get( &self, param_inline_object: models::InlineObject, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Body parameter @@ -290,48 +402,43 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - OpGetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + OpGetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs index d14e73f822d..fadd880b965 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs @@ -1,13 +1,12 @@ -use futures::Future; -use hyper; +use futures::future::BoxFuture; use hyper::header::HeaderName; -use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload}; +use hyper::{Error, Request, Response, StatusCode, service::Service}; use url::form_urlencoded; use std::default::Default; use std::io; use std::marker::PhantomData; +use std::task::{Poll, Context}; use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; -use swagger::context::ContextualPayload; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; use crate::Api; @@ -31,58 +30,52 @@ where } // Make a service that adds context. -impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for +impl Service for MakeAddContext where - A: Default + Push, + Target: Send, + A: Default + Push + Send, B: Push, Result = C>, C: Push, Result = D>, D: Send + 'static, - T: hyper::service::MakeService< - &'a SC, - Error = E, - MakeError = ME, - Service = S, - ReqBody = ContextualPayload, - ResBody = OB, - Future = F - >, - S: Service< - Error = E, - ReqBody = ContextualPayload, - ResBody = OB> + 'static, - ME: swagger::ErrorBound, - E: swagger::ErrorBound, - F: Future + Send + 'static, - S::Future: Send, - OB: Payload, + T: Service + Send, + T::Future: Send + 'static { - type ReqBody = hyper::Body; - type ResBody = OB; - type Error = E; - type MakeError = ME; - type Service = AddContext; - type Future = Box + Send + 'static>; + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; - fn make_service(&mut self, ctx: &'a SC) -> Self::Future { - Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s))) + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) } } -/// Middleware to extract authentication data from request -pub struct AddContext { +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, C: Push, Result = D>, - T: Service, { - pub fn new(inner: T) -> AddContext { + pub fn new(inner: T) -> Self { AddContext { inner, marker: PhantomData, @@ -90,33 +83,31 @@ where } } -impl Service for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, C: Push, Result=D>, D: Send + 'static, - T: Service>, - T::Future: Future, Error=T::Error> + Send + 'static + T: Service<(Request, D)> { - type ReqBody = hyper::Body; - type ResBody = T::ResBody; type Error = T::Error; - type Future = Box, Error=T::Error> + Send + 'static>; + type Future = T::Future; + type Response = T::Response; - fn call(&mut self, req: Request) -> Self::Future { - let context = A::default().push(XSpanIdString::get_or_generate(&req)); - let (head, body) = req.into_parts(); - let headers = head.headers.clone(); + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); let context = context.push(None::); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - Box::new(self.inner.call(hyper::Request::from_parts(head, body))) + self.inner.call((request, context)) } } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs index 0a6aa8ad57e..a6c48e87c07 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs @@ -1,12 +1,12 @@ #![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] +use async_trait::async_trait; use futures::Stream; -use std::io::Error; +use std::error::Error; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import swagger-rs directly")] -pub use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import futures directly")] -pub use futures::Future; +type ServiceError = Box; pub const BASE_PATH: &'static str = ""; pub const API_VERSION: &'static str = "0.0.1"; @@ -18,46 +18,69 @@ pub enum OpGetResponse { } /// API -pub trait Api { - fn op_get( +#[async_trait] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn op_get( &self, inline_object: models::InlineObject, - context: &C) -> Box + Send>; + context: &C) -> Result; } -/// API without a `Context` -pub trait ApiNoContext { - fn op_get( +/// API where `Context` isn't passed on every API call +#[async_trait] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn op_get( &self, inline_object: models::InlineObject, - ) -> Box + Send>; + ) -> Result; } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a, C> where Self: Sized { +pub trait ContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { - fn op_get( +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn op_get( &self, inline_object: models::InlineObject, - ) -> Box + Send> + ) -> Result { - self.api().op_get(inline_object, &self.context()) + let context = self.context().clone(); + self.api().op_get(inline_object, &context).await } } + #[cfg(feature = "client")] pub mod client; diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs index 3c1062d0f9b..0610da8c15b 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs @@ -1,20 +1,17 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; +use url::form_urlencoded; #[allow(unused_imports)] use crate::models; @@ -22,6 +19,8 @@ use crate::header; pub use crate::context; +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + use crate::{Api, OpGetResponse }; @@ -38,15 +37,17 @@ mod paths { pub(crate) static ID_OP: usize = 0; } -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -56,44 +57,45 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -102,23 +104,38 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has + 'static + Send + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; match &method { @@ -127,9 +144,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_inline_object: Option = if !body.is_empty() { @@ -139,29 +155,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_inline_object) => param_inline_object, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter InlineObject - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter InlineObject due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter InlineObject due to schema")), } } else { None }; let param_inline_object = match param_inline_object { Some(param_inline_object) => param_inline_object, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter InlineObject")) - .expect("Unable to create Bad Request response for missing body parameter InlineObject"))), + .expect("Unable to create Bad Request response for missing body parameter InlineObject")), }; - Box::new( - api_impl.op_get( + let result = api_impl.op_get( param_inline_object, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -188,37 +203,21 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter InlineObject: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter InlineObject"))), + .expect("Unable to create Bad Request response due to unable to read body parameter InlineObject")), } - }) - ) as Self::Future }, _ if path.matched(paths::ID_OP) => method_not_allowed(), - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } /// Request parser for `Api`. diff --git a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml index 67413a16903..0f19d1f064a 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml @@ -10,49 +10,51 @@ edition = "2018" default = ["client", "server"] client = [ "serde_ignored", "regex", "percent-encoding", "lazy_static", - "hyper", "hyper-openssl", "native-tls", "openssl", "url" + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ - "native-tls", "hyper-openssl", "openssl", + "native-tls", "hyper-openssl", "hyper-tls", "openssl", "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.4", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.7.1", optional = true } +hyper-openssl = { version = "0.8", optional = true } openssl = {version = "0.10", optional = true } [dependencies] # Common +async-trait = "0.1.24" chrono = { version = "0.4", features = ["serde"] } -futures = "0.1" -swagger = "4.0" +futures = "0.3" +swagger = "5.0.0-alpha-1" log = "0.4.0" mime = "0.3" -serde = { version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Crates included if required by the API definition # TODO: this should be updated to point at the official crate once # https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master"} -uuid = {version = "0.7", features = ["serde", "v4"]} +uuid = {version = "0.8", features = ["serde", "v4"]} # Common between server and client features -hyper = {version = "0.12", optional = true} -serde_ignored = {version = "0.0.4", optional = true} -url = {version = "1.5", optional = true} +hyper = {version = "0.13", optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} # Client-specific # Server, and client callback-specific lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} # Conversion frunk = { version = "0.3.0", optional = true } @@ -63,12 +65,13 @@ frunk-enum-core = { version = "0.2.0", optional = true } [dev-dependencies] clap = "2.25" -error-chain = "0.12" -env_logger = "0.6" -tokio = "0.1.17" +env_logger = "0.7" +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"] } +native-tls = "0.2" +tokio-tls = "0.3" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] -tokio-openssl = "0.3" +tokio-openssl = "0.4" openssl = "0.10" [[example]] diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs index 20d587392f5..633d4e31914 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs @@ -3,10 +3,9 @@ mod server; #[allow(unused_imports)] -use futures::{Future, future, Stream, stream}; +use futures::{future, Stream, stream}; #[allow(unused_imports)] use openapi_v3::{Api, ApiNoContext, Client, ContextWrapperExt, models, - ApiError, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, EnumInPathPathParamGetResponse, @@ -29,7 +28,7 @@ use openapi_v3::{Api, ApiNoContext, Client, ContextWrapperExt, models, XmlPostResponse, XmlPutResponse, CreateRepoResponse, - GetRepoInfoResponse + GetRepoInfoResponse, }; use clap::{App, Arg}; @@ -38,7 +37,9 @@ use log::info; // swagger::Has may be unused if there are no examples #[allow(unused_imports)] -use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData}; +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); // rt may be unused if there are no examples #[allow(unused_mut)] @@ -95,21 +96,21 @@ fn main() { matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if matches.is_present("https") { - // Using Simple HTTPS - Client::try_new_https(&base_url) - .expect("Failed to create HTTPS client") - } else { - // Using HTTP - Client::try_new_http( - &base_url) - .expect("Failed to create HTTP client") - }; - - let context: swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString) = + let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, None as Option, XSpanIdString::default()); - let client = client.with_context(context); + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; let mut rt = tokio::runtime::Runtime::new().unwrap(); diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs index 2e2a3036b65..9d295a0f9e3 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; -use uuid; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use openapi_v3::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = openapi_v3::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } @@ -102,31 +93,35 @@ impl Server { } } -use openapi_v3::{CallbackApi, ApiError}; +use openapi_v3::CallbackApi; use openapi_v3::CallbackCallbackWithHeaderPostResponse; use openapi_v3::CallbackCallbackPostResponse; use openapi_v3::client::callbacks::MakeService; +use std::error::Error; +use swagger::ApiError; -impl CallbackApi for Server where C: Has{ - fn callback_callback_with_header_post( +#[async_trait] +impl CallbackApi for Server where C: Has + Send + Sync +{ + async fn callback_callback_with_header_post( &self, callback_request_query_url: String, information: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("callback_callback_with_header_post({:?}) - X-Span-ID: {:?}", information, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn callback_callback_post( + async fn callback_callback_post( &self, callback_request_query_url: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("callback_callback_post() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs index bc1abfaa554..448771feb06 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs @@ -9,7 +9,8 @@ mod server; /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let matches = App::new("server") @@ -20,5 +21,5 @@ fn main() { let addr = "127.0.0.1:8080"; - hyper::rt::run(server::create(addr, matches.is_present("https"))); + server::create(addr, matches.is_present("https")).await; } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs index 0326561a01d..9377679f314 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; -use uuid; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use openapi_v3::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = openapi_v3::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } @@ -105,7 +96,6 @@ impl Server { use openapi_v3::{ Api, - ApiError, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, EnumInPathPathParamGetResponse, @@ -131,233 +121,237 @@ use openapi_v3::{ GetRepoInfoResponse, }; use openapi_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; -impl Api for Server where C: Has{ - fn callback_with_header_post( +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn callback_with_header_post( &self, url: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("callback_with_header_post(\"{}\") - X-Span-ID: {:?}", url, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn complex_query_param_get( + async fn complex_query_param_get( &self, list_of_strings: Option<&Vec>, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("complex_query_param_get({:?}) - X-Span-ID: {:?}", list_of_strings, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn enum_in_path_path_param_get( + async fn enum_in_path_path_param_get( &self, path_param: models::StringEnum, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("enum_in_path_path_param_get({:?}) - X-Span-ID: {:?}", path_param, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn mandatory_request_header_get( + async fn mandatory_request_header_get( &self, x_header: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("mandatory_request_header_get(\"{}\") - X-Span-ID: {:?}", x_header, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn merge_patch_json_get( + async fn merge_patch_json_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("merge_patch_json_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Get some stuff. - fn multiget_get( + async fn multiget_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("multiget_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn multiple_auth_scheme_get( + async fn multiple_auth_scheme_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("multiple_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn override_server_get( + async fn override_server_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("override_server_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Get some stuff with parameters. - fn paramget_get( + async fn paramget_get( &self, uuid: Option, some_object: Option, some_list: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("paramget_get({:?}, {:?}, {:?}) - X-Span-ID: {:?}", uuid, some_object, some_list, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn readonly_auth_scheme_get( + async fn readonly_auth_scheme_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("readonly_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn register_callback_post( + async fn register_callback_post( &self, url: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("register_callback_post(\"{}\") - X-Span-ID: {:?}", url, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn required_octet_stream_put( + async fn required_octet_stream_put( &self, body: swagger::ByteArray, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("required_octet_stream_put({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn responses_with_headers_get( + async fn responses_with_headers_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("responses_with_headers_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn rfc7807_get( + async fn rfc7807_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("rfc7807_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn untyped_property_get( + async fn untyped_property_get( &self, object_untyped_props: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("untyped_property_get({:?}) - X-Span-ID: {:?}", object_untyped_props, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn uuid_get( + async fn uuid_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("uuid_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn xml_extra_post( + async fn xml_extra_post( &self, duplicate_xml_object: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("xml_extra_post({:?}) - X-Span-ID: {:?}", duplicate_xml_object, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn xml_other_post( + async fn xml_other_post( &self, another_xml_object: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("xml_other_post({:?}) - X-Span-ID: {:?}", another_xml_object, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn xml_other_put( + async fn xml_other_put( &self, another_xml_array: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("xml_other_put({:?}) - X-Span-ID: {:?}", another_xml_array, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Post an array - fn xml_post( + async fn xml_post( &self, xml_array: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("xml_post({:?}) - X-Span-ID: {:?}", xml_array, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn xml_put( + async fn xml_put( &self, xml_object: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("xml_put({:?}) - X-Span-ID: {:?}", xml_object, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn create_repo( + async fn create_repo( &self, object_param: models::ObjectParam, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("create_repo({:?}) - X-Span-ID: {:?}", object_param, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn get_repo_info( + async fn get_repo_info( &self, repo_id: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("get_repo_info(\"{}\") - X-Span-ID: {:?}", repo_id, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs index 7ed0cb95aac..e20da072d9d 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs @@ -1,22 +1,17 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; -use uuid; -use serde_xml_rs; +use url::form_urlencoded; #[allow(unused_imports)] use crate::models; @@ -24,6 +19,8 @@ use crate::header; pub use crate::context; +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + use crate::CallbackApi as Api; use crate::CallbackCallbackWithHeaderPostResponse; use crate::CallbackCallbackPostResponse; @@ -53,15 +50,17 @@ mod paths { } -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -71,45 +70,46 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -118,23 +118,38 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has + Has> + 'static + Send + C: Has + Has> + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; match &method { @@ -158,10 +173,10 @@ where Ok(result) => Some(result.0), Err(err) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Invalid header Information - {}", err))) - .expect("Unable to create Bad Request response for invalid header Information"))); + .expect("Unable to create Bad Request response for invalid header Information")); }, }, @@ -170,16 +185,13 @@ where } }; - Box::new({ - {{ - Box::new( - api_impl.callback_callback_with_header_post( + let result = api_impl.callback_callback_with_header_post( callback_request_query_url, param_information, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -199,11 +211,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // CallbackCallbackPost - POST /{$request.query.url}/callback @@ -218,15 +226,12 @@ where ); let callback_request_query_url = path_params["request_query_url"].to_string(); - Box::new({ - {{ - Box::new( - api_impl.callback_callback_post( + let result = api_impl.callback_callback_post( callback_request_query_url, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -246,32 +251,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, _ if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK) => method_not_allowed(), _ if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER) => method_not_allowed(), - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } /// Request parser for `Api`. diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs index 063ec490254..46a80096974 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs @@ -1,39 +1,38 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; -use uuid; -use serde_xml_rs; + use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); use crate::{Api, CallbackWithHeaderPostResponse, @@ -64,11 +63,11 @@ use crate::{Api, pub mod callbacks; /// 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 { +fn into_base_path(input: impl TryInto, 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 uri = input.try_into()?; - let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?; + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; // Check the scheme if necessary if let Some(correct_scheme) = correct_scheme { @@ -78,38 +77,54 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result +pub struct Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, /// Base path of the API base_path: String, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client {{ base_path: {} }}", self.base_path) } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), base_path: self.base_path.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -122,30 +137,93 @@ impl Client /// /// # Arguments /// - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn try_new_with_connector( + pub fn try_new_with_connector( base_path: &str, protocol: Option<&'static str>, connector: C, - ) -> Result where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + ) -> Result { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Ok(Client { - client_service: Arc::new(client_service), + Ok(Self { + client_service, base_path: into_base_path(base_path, protocol)?, }) } +} +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(|e| ClientInitError::SslError(e))?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Client> +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" pub fn try_new_http( base_path: &str, ) -> Result { @@ -153,11 +231,20 @@ impl Client Self::try_new_with_connector(base_path, Some("http"), http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -170,7 +257,7 @@ impl Client /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -191,7 +278,7 @@ impl Client /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://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 @@ -217,17 +304,24 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn try_new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, base_path: &str, - ) -> Result { - Ok(Client { - client_service: client_service, + ) -> Result + { + Ok(Self { + client_service, base_path: into_base_path(base_path, None)?, }) } @@ -267,169 +361,179 @@ impl fmt::Display for ClientInitError { } } -impl error::Error for ClientInitError { +impl Error for ClientInitError { fn description(&self) -> &str { "Failed to produce a hyper client." } } -impl Api for Client where - C: Has + Has>, - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl Api for Client where + C: Has + Has> + Clone + Send + Sync + 'static, + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - fn callback_with_header_post( + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn callback_with_header_post( &self, param_url: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/callback-with-header", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("url", ¶m_url.to_string()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("url", ¶m_url.to_string()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_body(); - Box::new( - future::ok( - CallbackWithHeaderPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + Ok( + CallbackWithHeaderPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn complex_query_param_get( + async fn complex_query_param_get( &self, param_list_of_strings: Option<&Vec>, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/complex-query-param", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - if let Some(param_list_of_strings) = param_list_of_strings { - query_string.append_pair("list-of-strings", ¶m_list_of_strings.iter().map(ToString::to_string).collect::>().join(",")); - } - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_list_of_strings) = param_list_of_strings { + query_string.append_pair("list-of-strings", ¶m_list_of_strings.iter().map(ToString::to_string).collect::>().join(",")); + } + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - ComplexQueryParamGetResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + ComplexQueryParamGetResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn enum_in_path_path_param_get( + async fn enum_in_path_path_param_get( &self, param_path_param: models::StringEnum, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/enum_in_path/{path_param}", self.base_path @@ -437,102 +541,102 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - EnumInPathPathParamGetResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + EnumInPathPathParamGetResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn mandatory_request_header_get( + async fn mandatory_request_header_get( &self, param_x_header: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/mandatory-request-header", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); // Header parameters @@ -541,372 +645,311 @@ impl Api for Client where match header::IntoHeaderValue(param_x_header.clone()).try_into() { Ok(header) => header, Err(e) => { - return Box::new(future::err(ApiError(format!( - "Invalid header x_header - {}", e)))) as Box + Send>; + return Err(ApiError(format!( + "Invalid header x_header - {}", e))); }, }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - MandatoryRequestHeaderGetResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + MandatoryRequestHeaderGetResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn merge_patch_json_get( + async fn merge_patch_json_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/merge-patch-json", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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| { - MergePatchJsonGetResponse::Merge - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(MergePatchJsonGetResponse::Merge + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn multiget_get( + async fn multiget_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/multiget", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - ) - .map(move |body| { - MultigetGetResponse::JSONRsp - (body) - }) - ) as Box + Send> - }, - 201 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - // ToDo: this will move to swagger-rs and become a standard From conversion trait - // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream - serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e))) - ) - ) - .map(move |body| { - MultigetGetResponse::XMLRsp - (body) - }) - ) as Box + Send> - }, - 202 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - Ok(swagger::ByteArray(body.to_vec())) - ) - .map(move |body| { - MultigetGetResponse::OctetRsp - (body) - }) - ) as Box + Send> - }, - 203 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - Ok(body.to_string()) - ) - ) - .map(move |body| { - MultigetGetResponse::StringRsp - (body) - }) - ) as Box + Send> - }, - 204 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - ) - .map(move |body| { - MultigetGetResponse::DuplicateResponseLongText - (body) - }) - ) as Box + Send> - }, - 205 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - ) - .map(move |body| { - MultigetGetResponse::DuplicateResponseLongText_2 - (body) - }) - ) as Box + Send> - }, - 206 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - serde_json::from_str::(body) - .map_err(|e| e.into()) - ) - ) - .map(move |body| { - MultigetGetResponse::DuplicateResponseLongText_3 - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(MultigetGetResponse::JSONRsp + (body) + ) } - })) + 201 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(MultigetGetResponse::XMLRsp + (body) + ) + } + 202 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = swagger::ByteArray(body.to_vec()); + Ok(MultigetGetResponse::OctetRsp + (body) + ) + } + 203 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = body.to_string(); + Ok(MultigetGetResponse::StringRsp + (body) + ) + } + 204 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(MultigetGetResponse::DuplicateResponseLongText + (body) + ) + } + 205 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(MultigetGetResponse::DuplicateResponseLongText_2 + (body) + ) + } + 206 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(MultigetGetResponse::DuplicateResponseLongText_3 + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn multiple_auth_scheme_get( + async fn multiple_auth_scheme_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/multiple_auth_scheme", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -916,251 +959,239 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - MultipleAuthSchemeGetResponse::CheckThatLimitingToMultipleRequiredAuthSchemesWorks - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + MultipleAuthSchemeGetResponse::CheckThatLimitingToMultipleRequiredAuthSchemesWorks + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn override_server_get( + async fn override_server_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/override/override-server", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_body(); - Box::new( - future::ok( - OverrideServerGetResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + Ok( + OverrideServerGetResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn paramget_get( + async fn paramget_get( &self, param_uuid: Option, param_some_object: Option, param_some_list: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/paramget", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - if let Some(param_uuid) = param_uuid { - query_string.append_pair("uuid", ¶m_uuid.to_string()); - } - if let Some(param_some_object) = param_some_object { - query_string.append_pair("someObject", ¶m_some_object.to_string()); - } - if let Some(param_some_list) = param_some_list { - query_string.append_pair("someList", ¶m_some_list.to_string()); - } - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_uuid) = param_uuid { + query_string.append_pair("uuid", ¶m_uuid.to_string()); + } + if let Some(param_some_object) = param_some_object { + query_string.append_pair("someObject", ¶m_some_object.to_string()); + } + if let Some(param_some_list) = param_some_list { + query_string.append_pair("someList", ¶m_some_list.to_string()); + } + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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| { - ParamgetGetResponse::JSONRsp - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(ParamgetGetResponse::JSONRsp + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn readonly_auth_scheme_get( + async fn readonly_auth_scheme_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/readonly_auth_scheme", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -1170,143 +1201,139 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - ReadonlyAuthSchemeGetResponse::CheckThatLimitingToASingleRequiredAuthSchemeWorks - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + ReadonlyAuthSchemeGetResponse::CheckThatLimitingToASingleRequiredAuthSchemeWorks + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn register_callback_post( + async fn register_callback_post( &self, param_url: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/register-callback", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("url", ¶m_url.to_string()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("url", ¶m_url.to_string()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_body(); - Box::new( - future::ok( - RegisterCallbackPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + Ok( + RegisterCallbackPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn required_octet_stream_put( + async fn required_octet_stream_put( &self, param_body: swagger::ByteArray, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/required_octet_stream", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PUT") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_body.0; @@ -1315,363 +1342,338 @@ impl Api for Client where let header = "application/octet-stream"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - RequiredOctetStreamPutResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + RequiredOctetStreamPutResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn responses_with_headers_get( + async fn responses_with_headers_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/responses_with_headers", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let response_success_info = match response.headers().get(HeaderName::from_static("success-info")) { - Some(response_success_info) => response_success_info.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header Success-Info for response 200 was not found.")))) as Box + Send>, - }; - let response_success_info = match TryInto::>::try_into(response_success_info) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header Success-Info for response 200 - {}", e)))) as Box + Send>; - }, - }; - let response_success_info = response_success_info.0; + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; - let response_bool_header = match response.headers().get(HeaderName::from_static("bool-header")) { - Some(response_bool_header) => response_bool_header.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header Bool-Header for response 200 was not found.")))) as Box + Send>, - }; - let response_bool_header = match TryInto::>::try_into(response_bool_header) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header Bool-Header for response 200 - {}", e)))) as Box + Send>; - }, - }; - let response_bool_header = response_bool_header.0; + match response.status().as_u16() { + 200 => { + let response_success_info = match response.headers().get(HeaderName::from_static("success-info")) { + Some(response_success_info) => response_success_info.clone(), + None => { + return Err(ApiError(String::from("Required response header Success-Info for response 200 was not found."))); + } + }; + let response_success_info = match TryInto::>::try_into(response_success_info) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Success-Info for response 200 - {}", e))); + }, + }; + let response_success_info = response_success_info.0; - let response_object_header = match response.headers().get(HeaderName::from_static("object-header")) { - Some(response_object_header) => response_object_header.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header Object-Header for response 200 was not found.")))) as Box + Send>, - }; - let response_object_header = match TryInto::>::try_into(response_object_header) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header Object-Header for response 200 - {}", e)))) as Box + Send>; - }, - }; - let response_object_header = response_object_header.0; + let response_bool_header = match response.headers().get(HeaderName::from_static("bool-header")) { + Some(response_bool_header) => response_bool_header.clone(), + None => { + return Err(ApiError(String::from("Required response header Bool-Header for response 200 was not found."))); + } + }; + let response_bool_header = match TryInto::>::try_into(response_bool_header) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Bool-Header for response 200 - {}", e))); + }, + }; + let response_bool_header = response_bool_header.0; - let body = response.into_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| { - ResponsesWithHeadersGetResponse::Success - { - body: body, - success_info: response_success_info, - bool_header: response_bool_header, - object_header: response_object_header, - } - }) - ) as Box + Send> - }, - 412 => { - let response_further_info = match response.headers().get(HeaderName::from_static("further-info")) { - Some(response_further_info) => response_further_info.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header Further-Info for response 412 was not found.")))) as Box + Send>, - }; - let response_further_info = match TryInto::>::try_into(response_further_info) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header Further-Info for response 412 - {}", e)))) as Box + Send>; - }, - }; - let response_further_info = response_further_info.0; + let response_object_header = match response.headers().get(HeaderName::from_static("object-header")) { + Some(response_object_header) => response_object_header.clone(), + None => { + return Err(ApiError(String::from("Required response header Object-Header for response 200 was not found."))); + } + }; + let response_object_header = match TryInto::>::try_into(response_object_header) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Object-Header for response 200 - {}", e))); + }, + }; + let response_object_header = response_object_header.0; - let response_failure_info = match response.headers().get(HeaderName::from_static("failure-info")) { - Some(response_failure_info) => response_failure_info.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header Failure-Info for response 412 was not found.")))) as Box + Send>, - }; - let response_failure_info = match TryInto::>::try_into(response_failure_info) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header Failure-Info for response 412 - {}", e)))) as Box + Send>; - }, - }; - let response_failure_info = response_failure_info.0; - - let body = response.into_body(); - Box::new( - future::ok( - ResponsesWithHeadersGetResponse::PreconditionFailed - { - further_info: response_further_info, - failure_info: response_failure_info, - } - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(ResponsesWithHeadersGetResponse::Success + { + body: body, + success_info: response_success_info, + bool_header: response_bool_header, + object_header: response_object_header, + } + ) } - })) + 412 => { + let response_further_info = match response.headers().get(HeaderName::from_static("further-info")) { + Some(response_further_info) => response_further_info.clone(), + None => { + return Err(ApiError(String::from("Required response header Further-Info for response 412 was not found."))); + } + }; + let response_further_info = match TryInto::>::try_into(response_further_info) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Further-Info for response 412 - {}", e))); + }, + }; + let response_further_info = response_further_info.0; + + let response_failure_info = match response.headers().get(HeaderName::from_static("failure-info")) { + Some(response_failure_info) => response_failure_info.clone(), + None => { + return Err(ApiError(String::from("Required response header Failure-Info for response 412 was not found."))); + } + }; + let response_failure_info = match TryInto::>::try_into(response_failure_info) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Failure-Info for response 412 - {}", e))); + }, + }; + let response_failure_info = response_failure_info.0; + + let body = response.into_body(); + Ok( + ResponsesWithHeadersGetResponse::PreconditionFailed + { + further_info: response_further_info, + failure_info: response_failure_info, + } + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn rfc7807_get( + async fn rfc7807_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/rfc7807", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_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| { - Rfc7807GetResponse::OK - (body) - }) - ) as Box + Send> - }, - 404 => { - let body = response.into_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| { - Rfc7807GetResponse::NotFound - (body) - }) - ) as Box + Send> - }, - 406 => { - let body = response.into_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| { - Rfc7807GetResponse::NotAcceptable - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(Rfc7807GetResponse::OK + (body) + ) } - })) + 404 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(Rfc7807GetResponse::NotFound + (body) + ) + } + 406 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(Rfc7807GetResponse::NotAcceptable + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn untyped_property_get( + async fn untyped_property_get( &self, param_object_untyped_props: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/untyped_property", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_object_untyped_props.map(|ref body| { @@ -1684,161 +1686,151 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - UntypedPropertyGetResponse::CheckThatUntypedPropertiesWorks - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + UntypedPropertyGetResponse::CheckThatUntypedPropertiesWorks + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn uuid_get( + async fn uuid_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/uuid", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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| { - UuidGetResponse::DuplicateResponseLongText - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(UuidGetResponse::DuplicateResponseLongText + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn xml_extra_post( + async fn xml_extra_post( &self, param_duplicate_xml_object: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/xml_extra", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_duplicate_xml_object.map(|ref body| { @@ -1851,86 +1843,82 @@ impl Api for Client where let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 201 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlExtraPostResponse::OK - ) - ) as Box + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlExtraPostResponse::BadRequest - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + Ok( + XmlExtraPostResponse::OK + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + XmlExtraPostResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn xml_other_post( + async fn xml_other_post( &self, param_another_xml_object: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/xml_other", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_another_xml_object.map(|ref body| { @@ -1943,100 +1931,91 @@ impl Api for Client where let header = "text/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 201 => { - let body = response.into_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| { - XmlOtherPostResponse::OK - (body) - }) - ) as Box + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlOtherPostResponse::BadRequest - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(XmlOtherPostResponse::OK + (body) + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + XmlOtherPostResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn xml_other_put( + async fn xml_other_put( &self, param_another_xml_array: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/xml_other", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PUT") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_another_xml_array.map(|ref body| { @@ -2049,86 +2028,82 @@ impl Api for Client where let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 201 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlOtherPutResponse::OK - ) - ) as Box + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlOtherPutResponse::BadRequest - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + Ok( + XmlOtherPutResponse::OK + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + XmlOtherPutResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn xml_post( + async fn xml_post( &self, param_xml_array: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/xml", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_xml_array.map(|ref body| { @@ -2141,86 +2116,82 @@ impl Api for Client where let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 201 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlPostResponse::OK - ) - ) as Box + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlPostResponse::BadRequest - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + Ok( + XmlPostResponse::OK + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + XmlPostResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn xml_put( + async fn xml_put( &self, param_xml_object: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/xml", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PUT") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_xml_object.map(|ref body| { @@ -2234,87 +2205,83 @@ impl Api for Client where let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 201 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlPutResponse::OK - ) - ) as Box + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - XmlPutResponse::BadRequest - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + Ok( + XmlPutResponse::OK + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + XmlPutResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn create_repo( + async fn create_repo( &self, param_object_param: models::ObjectParam, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/repos", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Body parameter @@ -2324,54 +2291,50 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - CreateRepoResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + CreateRepoResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn get_repo_info( + async fn get_repo_info( &self, param_repo_id: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/repos/{repo_id}", self.base_path @@ -2379,77 +2342,68 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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| { - GetRepoInfoResponse::OK - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(GetRepoInfoResponse::OK + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs index 3f15f7b0a77..6f030053252 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs @@ -1,13 +1,12 @@ -use futures::Future; -use hyper; +use futures::future::BoxFuture; use hyper::header::HeaderName; -use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload}; +use hyper::{Error, Request, Response, StatusCode, service::Service}; use url::form_urlencoded; use std::default::Default; use std::io; use std::marker::PhantomData; +use std::task::{Poll, Context}; use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; -use swagger::context::ContextualPayload; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; use crate::Api; @@ -31,58 +30,52 @@ where } // Make a service that adds context. -impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for +impl Service for MakeAddContext where - A: Default + Push, + Target: Send, + A: Default + Push + Send, B: Push, Result = C>, C: Push, Result = D>, D: Send + 'static, - T: hyper::service::MakeService< - &'a SC, - Error = E, - MakeError = ME, - Service = S, - ReqBody = ContextualPayload, - ResBody = OB, - Future = F - >, - S: Service< - Error = E, - ReqBody = ContextualPayload, - ResBody = OB> + 'static, - ME: swagger::ErrorBound, - E: swagger::ErrorBound, - F: Future + Send + 'static, - S::Future: Send, - OB: Payload, + T: Service + Send, + T::Future: Send + 'static { - type ReqBody = hyper::Body; - type ResBody = OB; - type Error = E; - type MakeError = ME; - type Service = AddContext; - type Future = Box + Send + 'static>; + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; - fn make_service(&mut self, ctx: &'a SC) -> Self::Future { - Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s))) + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) } } -/// Middleware to extract authentication data from request -pub struct AddContext { +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, C: Push, Result = D>, - T: Service, { - pub fn new(inner: T) -> AddContext { + pub fn new(inner: T) -> Self { AddContext { inner, marker: PhantomData, @@ -90,24 +83,26 @@ where } } -impl Service for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, C: Push, Result=D>, D: Send + 'static, - T: Service>, - T::Future: Future, Error=T::Error> + Send + 'static + T: Service<(Request, D)> { - type ReqBody = hyper::Body; - type ResBody = T::ResBody; type Error = T::Error; - type Future = Box, Error=T::Error> + Send + 'static>; + type Future = T::Future; + type Response = T::Response; - fn call(&mut self, req: Request) -> Self::Future { - let context = A::default().push(XSpanIdString::get_or_generate(&req)); - let (head, body) = req.into_parts(); - let headers = head.headers.clone(); + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); { use swagger::auth::Bearer; @@ -117,22 +112,13 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } let context = context.push(None::); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - Box::new(self.inner.call(hyper::Request::from_parts(head, body))) + self.inner.call((request, context)) } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs index 1f786e6fbfe..fee0011bc98 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs @@ -1,12 +1,12 @@ #![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] +use async_trait::async_trait; use futures::Stream; -use std::io::Error; +use std::error::Error; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import swagger-rs directly")] -pub use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import futures directly")] -pub use futures::Future; +type ServiceError = Box; pub const BASE_PATH: &'static str = ""; pub const API_VERSION: &'static str = "1.0.7"; @@ -225,433 +225,478 @@ pub enum GetRepoInfoResponse { } /// API -pub trait Api { - fn callback_with_header_post( +#[async_trait] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn callback_with_header_post( &self, url: String, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn complex_query_param_get( + async fn complex_query_param_get( &self, list_of_strings: Option<&Vec>, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn enum_in_path_path_param_get( + async fn enum_in_path_path_param_get( &self, path_param: models::StringEnum, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn mandatory_request_header_get( + async fn mandatory_request_header_get( &self, x_header: String, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn merge_patch_json_get( + async fn merge_patch_json_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Get some stuff. - fn multiget_get( + async fn multiget_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn multiple_auth_scheme_get( + async fn multiple_auth_scheme_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn override_server_get( + async fn override_server_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Get some stuff with parameters. - fn paramget_get( + async fn paramget_get( &self, uuid: Option, some_object: Option, some_list: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn readonly_auth_scheme_get( + async fn readonly_auth_scheme_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn register_callback_post( + async fn register_callback_post( &self, url: String, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn required_octet_stream_put( + async fn required_octet_stream_put( &self, body: swagger::ByteArray, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn responses_with_headers_get( + async fn responses_with_headers_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn rfc7807_get( + async fn rfc7807_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn untyped_property_get( + async fn untyped_property_get( &self, object_untyped_props: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn uuid_get( + async fn uuid_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn xml_extra_post( + async fn xml_extra_post( &self, duplicate_xml_object: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn xml_other_post( + async fn xml_other_post( &self, another_xml_object: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn xml_other_put( + async fn xml_other_put( &self, another_xml_array: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Post an array - fn xml_post( + async fn xml_post( &self, xml_array: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn xml_put( + async fn xml_put( &self, xml_object: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn create_repo( + async fn create_repo( &self, object_param: models::ObjectParam, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn get_repo_info( + async fn get_repo_info( &self, repo_id: String, - context: &C) -> Box + Send>; + context: &C) -> Result; } -/// API without a `Context` -pub trait ApiNoContext { - fn callback_with_header_post( +/// API where `Context` isn't passed on every API call +#[async_trait] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn callback_with_header_post( &self, url: String, - ) -> Box + Send>; + ) -> Result; - fn complex_query_param_get( + async fn complex_query_param_get( &self, list_of_strings: Option<&Vec>, - ) -> Box + Send>; + ) -> Result; - fn enum_in_path_path_param_get( + async fn enum_in_path_path_param_get( &self, path_param: models::StringEnum, - ) -> Box + Send>; + ) -> Result; - fn mandatory_request_header_get( + async fn mandatory_request_header_get( &self, x_header: String, - ) -> Box + Send>; + ) -> Result; - fn merge_patch_json_get( + async fn merge_patch_json_get( &self, - ) -> Box + Send>; + ) -> Result; /// Get some stuff. - fn multiget_get( + async fn multiget_get( &self, - ) -> Box + Send>; + ) -> Result; - fn multiple_auth_scheme_get( + async fn multiple_auth_scheme_get( &self, - ) -> Box + Send>; + ) -> Result; - fn override_server_get( + async fn override_server_get( &self, - ) -> Box + Send>; + ) -> Result; /// Get some stuff with parameters. - fn paramget_get( + async fn paramget_get( &self, uuid: Option, some_object: Option, some_list: Option, - ) -> Box + Send>; + ) -> Result; - fn readonly_auth_scheme_get( + async fn readonly_auth_scheme_get( &self, - ) -> Box + Send>; + ) -> Result; - fn register_callback_post( + async fn register_callback_post( &self, url: String, - ) -> Box + Send>; + ) -> Result; - fn required_octet_stream_put( + async fn required_octet_stream_put( &self, body: swagger::ByteArray, - ) -> Box + Send>; + ) -> Result; - fn responses_with_headers_get( + async fn responses_with_headers_get( &self, - ) -> Box + Send>; + ) -> Result; - fn rfc7807_get( + async fn rfc7807_get( &self, - ) -> Box + Send>; + ) -> Result; - fn untyped_property_get( + async fn untyped_property_get( &self, object_untyped_props: Option, - ) -> Box + Send>; + ) -> Result; - fn uuid_get( + async fn uuid_get( &self, - ) -> Box + Send>; + ) -> Result; - fn xml_extra_post( + async fn xml_extra_post( &self, duplicate_xml_object: Option, - ) -> Box + Send>; + ) -> Result; - fn xml_other_post( + async fn xml_other_post( &self, another_xml_object: Option, - ) -> Box + Send>; + ) -> Result; - fn xml_other_put( + async fn xml_other_put( &self, another_xml_array: Option, - ) -> Box + Send>; + ) -> Result; /// Post an array - fn xml_post( + async fn xml_post( &self, xml_array: Option, - ) -> Box + Send>; + ) -> Result; - fn xml_put( + async fn xml_put( &self, xml_object: Option, - ) -> Box + Send>; + ) -> Result; - fn create_repo( + async fn create_repo( &self, object_param: models::ObjectParam, - ) -> Box + Send>; + ) -> Result; - fn get_repo_info( + async fn get_repo_info( &self, repo_id: String, - ) -> Box + Send>; + ) -> Result; } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a, C> where Self: Sized { +pub trait ContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { - fn callback_with_header_post( +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn callback_with_header_post( &self, url: String, - ) -> Box + Send> + ) -> Result { - self.api().callback_with_header_post(url, &self.context()) + let context = self.context().clone(); + self.api().callback_with_header_post(url, &context).await } - fn complex_query_param_get( + async fn complex_query_param_get( &self, list_of_strings: Option<&Vec>, - ) -> Box + Send> + ) -> Result { - self.api().complex_query_param_get(list_of_strings, &self.context()) + let context = self.context().clone(); + self.api().complex_query_param_get(list_of_strings, &context).await } - fn enum_in_path_path_param_get( + async fn enum_in_path_path_param_get( &self, path_param: models::StringEnum, - ) -> Box + Send> + ) -> Result { - self.api().enum_in_path_path_param_get(path_param, &self.context()) + let context = self.context().clone(); + self.api().enum_in_path_path_param_get(path_param, &context).await } - fn mandatory_request_header_get( + async fn mandatory_request_header_get( &self, x_header: String, - ) -> Box + Send> + ) -> Result { - self.api().mandatory_request_header_get(x_header, &self.context()) + let context = self.context().clone(); + self.api().mandatory_request_header_get(x_header, &context).await } - fn merge_patch_json_get( + async fn merge_patch_json_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().merge_patch_json_get(&self.context()) + let context = self.context().clone(); + self.api().merge_patch_json_get(&context).await } /// Get some stuff. - fn multiget_get( + async fn multiget_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().multiget_get(&self.context()) + let context = self.context().clone(); + self.api().multiget_get(&context).await } - fn multiple_auth_scheme_get( + async fn multiple_auth_scheme_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().multiple_auth_scheme_get(&self.context()) + let context = self.context().clone(); + self.api().multiple_auth_scheme_get(&context).await } - fn override_server_get( + async fn override_server_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().override_server_get(&self.context()) + let context = self.context().clone(); + self.api().override_server_get(&context).await } /// Get some stuff with parameters. - fn paramget_get( + async fn paramget_get( &self, uuid: Option, some_object: Option, some_list: Option, - ) -> Box + Send> + ) -> Result { - self.api().paramget_get(uuid, some_object, some_list, &self.context()) + let context = self.context().clone(); + self.api().paramget_get(uuid, some_object, some_list, &context).await } - fn readonly_auth_scheme_get( + async fn readonly_auth_scheme_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().readonly_auth_scheme_get(&self.context()) + let context = self.context().clone(); + self.api().readonly_auth_scheme_get(&context).await } - fn register_callback_post( + async fn register_callback_post( &self, url: String, - ) -> Box + Send> + ) -> Result { - self.api().register_callback_post(url, &self.context()) + let context = self.context().clone(); + self.api().register_callback_post(url, &context).await } - fn required_octet_stream_put( + async fn required_octet_stream_put( &self, body: swagger::ByteArray, - ) -> Box + Send> + ) -> Result { - self.api().required_octet_stream_put(body, &self.context()) + let context = self.context().clone(); + self.api().required_octet_stream_put(body, &context).await } - fn responses_with_headers_get( + async fn responses_with_headers_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().responses_with_headers_get(&self.context()) + let context = self.context().clone(); + self.api().responses_with_headers_get(&context).await } - fn rfc7807_get( + async fn rfc7807_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().rfc7807_get(&self.context()) + let context = self.context().clone(); + self.api().rfc7807_get(&context).await } - fn untyped_property_get( + async fn untyped_property_get( &self, object_untyped_props: Option, - ) -> Box + Send> + ) -> Result { - self.api().untyped_property_get(object_untyped_props, &self.context()) + let context = self.context().clone(); + self.api().untyped_property_get(object_untyped_props, &context).await } - fn uuid_get( + async fn uuid_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().uuid_get(&self.context()) + let context = self.context().clone(); + self.api().uuid_get(&context).await } - fn xml_extra_post( + async fn xml_extra_post( &self, duplicate_xml_object: Option, - ) -> Box + Send> + ) -> Result { - self.api().xml_extra_post(duplicate_xml_object, &self.context()) + let context = self.context().clone(); + self.api().xml_extra_post(duplicate_xml_object, &context).await } - fn xml_other_post( + async fn xml_other_post( &self, another_xml_object: Option, - ) -> Box + Send> + ) -> Result { - self.api().xml_other_post(another_xml_object, &self.context()) + let context = self.context().clone(); + self.api().xml_other_post(another_xml_object, &context).await } - fn xml_other_put( + async fn xml_other_put( &self, another_xml_array: Option, - ) -> Box + Send> + ) -> Result { - self.api().xml_other_put(another_xml_array, &self.context()) + let context = self.context().clone(); + self.api().xml_other_put(another_xml_array, &context).await } /// Post an array - fn xml_post( + async fn xml_post( &self, xml_array: Option, - ) -> Box + Send> + ) -> Result { - self.api().xml_post(xml_array, &self.context()) + let context = self.context().clone(); + self.api().xml_post(xml_array, &context).await } - fn xml_put( + async fn xml_put( &self, xml_object: Option, - ) -> Box + Send> + ) -> Result { - self.api().xml_put(xml_object, &self.context()) + let context = self.context().clone(); + self.api().xml_put(xml_object, &context).await } - fn create_repo( + async fn create_repo( &self, object_param: models::ObjectParam, - ) -> Box + Send> + ) -> Result { - self.api().create_repo(object_param, &self.context()) + let context = self.context().clone(); + self.api().create_repo(object_param, &context).await } - fn get_repo_info( + async fn get_repo_info( &self, repo_id: String, - ) -> Box + Send> + ) -> Result { - self.api().get_repo_info(repo_id, &self.context()) + let context = self.context().clone(); + self.api().get_repo_info(repo_id, &context).await } } + #[derive(Debug, PartialEq)] pub enum CallbackCallbackWithHeaderPostResponse { /// OK @@ -666,68 +711,89 @@ pub enum CallbackCallbackPostResponse { /// Callback API -pub trait CallbackApi { - fn callback_callback_with_header_post( +#[async_trait] +pub trait CallbackApi { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn callback_callback_with_header_post( &self, callback_request_query_url: String, information: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn callback_callback_post( + async fn callback_callback_post( &self, callback_request_query_url: String, - context: &C) -> Box + Send>; + context: &C) -> Result; } /// Callback API without a `Context` -pub trait CallbackApiNoContext { - fn callback_callback_with_header_post( +#[async_trait] +pub trait CallbackApiNoContext { + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn callback_callback_with_header_post( &self, callback_request_query_url: String, information: Option, - ) -> Box + Send>; + ) -> Result; - fn callback_callback_post( + async fn callback_callback_post( &self, callback_request_query_url: String, - ) -> Box + Send>; + ) -> Result; } -/// Trait to extend an API to make it easy to bind it to a context. -pub trait CallbackContextWrapperExt<'a, C> where Self: Sized { +pub trait CallbackContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: CallbackApi + Sized, C> CallbackContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> CallbackContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: CallbackApi, C> CallbackApiNoContext for ContextWrapper<'a, T, C> { - fn callback_callback_with_header_post( +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> CallbackApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn callback_callback_with_header_post( &self, callback_request_query_url: String, information: Option, - ) -> Box + Send> + ) -> Result { + let context = self.context().clone(); self.api().callback_callback_with_header_post( callback_request_query_url, information, - &self.context()) + &context).await } - fn callback_callback_post( + async fn callback_callback_post( &self, callback_request_query_url: String, - ) -> Box + Send> + ) -> Result { + let context = self.context().clone(); self.api().callback_callback_post( callback_request_query_url, - &self.context()) + &context).await } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs index 1d52c326e27..0f3ab78824a 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs @@ -1,68 +1,83 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; -use uuid; -use serde_xml_rs; + use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); use crate::CallbackApi; use crate::CallbackCallbackWithHeaderPostResponse; use crate::CallbackCallbackPostResponse; /// A client that implements the API by making HTTP calls out to a server. -pub struct Client +pub struct Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client") } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -76,26 +91,33 @@ impl Client /// # Arguments /// /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn new_with_connector( - connector: C, - ) -> Self where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + pub fn new_with_connector(connector: C) -> Self { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Client { - client_service: Arc::new(client_service), + Self { + client_service, } } +} +impl Client> +{ /// Create an HTTP client. pub fn new_http() -> Self { let http_connector = Connector::builder().build(); Self::new_with_connector(http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server. #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] pub fn new_https() -> Result @@ -155,60 +177,82 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, { /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, ) -> Self { Client { - client_service: client_service, + client_service, } } } -impl CallbackApi for Client where - C: Has + Has>, - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl CallbackApi for Client where + C: Has + Has> + Send + Sync, + S: Service< + Request, + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - fn callback_callback_with_header_post( + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(Box::new(e))), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn callback_callback_with_header_post( &self, callback_request_query_url: String, param_information: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{request_query_url}/callback-with-header" ,request_query_url=callback_request_query_url ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); // Header parameters @@ -219,119 +263,112 @@ impl CallbackApi for Client where match header::IntoHeaderValue(param_information.clone()).try_into() { Ok(header) => header, Err(e) => { - return Box::new(future::err(ApiError(format!( - "Invalid header information - {}", e)))) as Box + Send>; + return Err(ApiError(format!( + "Invalid header information - {}", e))); }, }); }, None => {} } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_body(); - Box::new( - future::ok( - CallbackCallbackWithHeaderPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + Ok( + CallbackCallbackWithHeaderPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn callback_callback_post( + async fn callback_callback_post( &self, callback_request_query_url: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{request_query_url}/callback" ,request_query_url=callback_request_query_url ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_body(); - Box::new( - future::ok( - CallbackCallbackPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + Ok( + CallbackCallbackPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs index c13904fe064..1244ae2af5b 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs @@ -1,22 +1,17 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; -use uuid; -use serde_xml_rs; +use url::form_urlencoded; #[allow(unused_imports)] use crate::models; @@ -24,6 +19,8 @@ use crate::header; pub use crate::context; +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + use crate::{Api, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, @@ -114,15 +111,17 @@ mod paths { pub(crate) static ID_XML_OTHER: usize = 20; } -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -132,44 +131,45 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -178,23 +178,38 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has + Has> + 'static + Send + C: Has + Has> + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; match &method { @@ -207,26 +222,23 @@ where let param_url = match param_url { Some(param_url) => match param_url.parse::() { Ok(param_url) => param_url, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid query parameter url"))), + .expect("Unable to create Bad Request response for invalid query parameter url")), }, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required query parameter url")) - .expect("Unable to create Bad Request response for missing qeury parameter url"))), + .expect("Unable to create Bad Request response for missing qeury parameter url")), }; - Box::new({ - {{ - Box::new( - api_impl.callback_with_header_post( + let result = api_impl.callback_with_header_post( param_url, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -246,11 +258,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // ComplexQueryParamGet - GET /complex-query-param @@ -266,15 +274,12 @@ where None }; - Box::new({ - {{ - Box::new( - api_impl.complex_query_param_get( + let result = api_impl.complex_query_param_get( param_list_of_strings.as_ref(), &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -294,11 +299,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // EnumInPathPathParamGet - GET /enum_in_path/{path_param} @@ -315,26 +316,23 @@ where let param_path_param = match percent_encoding::percent_decode(path_params["path_param"].as_bytes()).decode_utf8() { Ok(param_path_param) => match param_path_param.parse::() { Ok(param_path_param) => param_path_param, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter path_param: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.enum_in_path_path_param_get( + let result = api_impl.enum_in_path_path_param_get( param_path_param, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -354,11 +352,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // MandatoryRequestHeaderGet - GET /mandatory-request-header @@ -371,30 +365,27 @@ where Ok(result) => result.0, Err(err) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Invalid header X-Header - {}", err))) - .expect("Unable to create Bad Request response for invalid header X-Header"))); + .expect("Unable to create Bad Request response for invalid header X-Header")); }, }, None => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required header X-Header")) - .expect("Unable to create Bad Request response for missing required header X-Header"))); + .expect("Unable to create Bad Request response for missing required header X-Header")); } }; - Box::new({ - {{ - Box::new( - api_impl.mandatory_request_header_get( + let result = api_impl.mandatory_request_header_get( param_x_header, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -414,23 +405,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // MergePatchJsonGet - GET /merge-patch-json &hyper::Method::GET if path.matched(paths::ID_MERGE_PATCH_JSON) => { - Box::new({ - {{ - Box::new( - api_impl.merge_patch_json_get( + let result = api_impl.merge_patch_json_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -457,23 +441,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // MultigetGet - GET /multiget &hyper::Method::GET if path.matched(paths::ID_MULTIGET) => { - Box::new({ - {{ - Box::new( - api_impl.multiget_get( + let result = api_impl.multiget_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -566,11 +543,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // MultipleAuthSchemeGet - GET /multiple_auth_scheme @@ -578,10 +551,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -593,26 +566,23 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } - Box::new({ - {{ - Box::new( - api_impl.multiple_auth_scheme_get( + let result = api_impl.multiple_auth_scheme_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -632,23 +602,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // OverrideServerGet - GET /override-server &hyper::Method::GET if path.matched(paths::ID_OVERRIDE_SERVER) => { - Box::new({ - {{ - Box::new( - api_impl.override_server_get( + let result = api_impl.override_server_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -668,11 +631,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // ParamgetGet - GET /paramget @@ -689,17 +648,14 @@ where .nth(0); let param_some_list = param_some_list.and_then(|param_some_list| param_some_list.parse::<>().ok()); - Box::new({ - {{ - Box::new( - api_impl.paramget_get( + let result = api_impl.paramget_get( param_uuid, param_some_object, param_some_list, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -726,11 +682,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // ReadonlyAuthSchemeGet - GET /readonly_auth_scheme @@ -738,10 +690,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -752,26 +704,23 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } - Box::new({ - {{ - Box::new( - api_impl.readonly_auth_scheme_get( + let result = api_impl.readonly_auth_scheme_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -791,11 +740,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // RegisterCallbackPost - POST /register-callback @@ -807,26 +752,23 @@ where let param_url = match param_url { Some(param_url) => match param_url.parse::() { Ok(param_url) => param_url, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid query parameter url"))), + .expect("Unable to create Bad Request response for invalid query parameter url")), }, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required query parameter url")) - .expect("Unable to create Bad Request response for missing qeury parameter url"))), + .expect("Unable to create Bad Request response for missing qeury parameter url")), }; - Box::new({ - {{ - Box::new( - api_impl.register_callback_post( + let result = api_impl.register_callback_post( param_url, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -846,11 +788,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // RequiredOctetStreamPut - PUT /required_octet_stream @@ -858,9 +796,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let param_body: Option = if !body.is_empty() { Some(swagger::ByteArray(body.to_vec())) @@ -869,19 +806,18 @@ where }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.required_octet_stream_put( + let result = api_impl.required_octet_stream_put( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -901,29 +837,22 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // ResponsesWithHeadersGet - GET /responses_with_headers &hyper::Method::GET if path.matched(paths::ID_RESPONSES_WITH_HEADERS) => { - Box::new({ - {{ - Box::new( - api_impl.responses_with_headers_get( + let result = api_impl.responses_with_headers_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -941,7 +870,7 @@ where let success_info = match header::IntoHeaderValue(success_info).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling success_info header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -951,7 +880,7 @@ where let bool_header = match header::IntoHeaderValue(bool_header).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling bool_header header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -961,7 +890,7 @@ where let object_header = match header::IntoHeaderValue(object_header).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling object_header header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -997,7 +926,7 @@ where let further_info = match header::IntoHeaderValue(further_info).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling further_info header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -1007,7 +936,7 @@ where let failure_info = match header::IntoHeaderValue(failure_info).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling failure_info header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -1033,23 +962,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Rfc7807Get - GET /rfc7807 &hyper::Method::GET if path.matched(paths::ID_RFC7807) => { - Box::new({ - {{ - Box::new( - api_impl.rfc7807_get( + let result = api_impl.rfc7807_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1098,11 +1020,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // UntypedPropertyGet - GET /untyped_property @@ -1110,9 +1028,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_object_untyped_props: Option = if !body.is_empty() { @@ -1128,13 +1045,12 @@ where None }; - Box::new( - api_impl.untyped_property_get( + let result = api_impl.untyped_property_get( param_object_untyped_props, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1161,29 +1077,22 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter ObjectUntypedProps: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter ObjectUntypedProps"))), + .expect("Unable to create Bad Request response due to unable to read body parameter ObjectUntypedProps")), } - }) - ) as Self::Future }, // UuidGet - GET /uuid &hyper::Method::GET if path.matched(paths::ID_UUID) => { - Box::new({ - {{ - Box::new( - api_impl.uuid_get( + let result = api_impl.uuid_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1210,11 +1119,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // XmlExtraPost - POST /xml_extra @@ -1222,9 +1127,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_duplicate_xml_object: Option = if !body.is_empty() { @@ -1240,13 +1144,12 @@ where None }; - Box::new( - api_impl.xml_extra_post( + let result = api_impl.xml_extra_post( param_duplicate_xml_object, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1277,17 +1180,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter DuplicateXmlObject: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter DuplicateXmlObject"))), + .expect("Unable to create Bad Request response due to unable to read body parameter DuplicateXmlObject")), } - }) - ) as Self::Future }, // XmlOtherPost - POST /xml_other @@ -1295,9 +1194,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_another_xml_object: Option = if !body.is_empty() { @@ -1313,13 +1211,12 @@ where None }; - Box::new( - api_impl.xml_other_post( + let result = api_impl.xml_other_post( param_another_xml_object, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1361,17 +1258,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter AnotherXmlObject: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter AnotherXmlObject"))), + .expect("Unable to create Bad Request response due to unable to read body parameter AnotherXmlObject")), } - }) - ) as Self::Future }, // XmlOtherPut - PUT /xml_other @@ -1379,9 +1272,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_another_xml_array: Option = if !body.is_empty() { @@ -1397,13 +1289,12 @@ where None }; - Box::new( - api_impl.xml_other_put( + let result = api_impl.xml_other_put( param_another_xml_array, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1434,17 +1325,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter AnotherXmlArray: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter AnotherXmlArray"))), + .expect("Unable to create Bad Request response due to unable to read body parameter AnotherXmlArray")), } - }) - ) as Self::Future }, // XmlPost - POST /xml @@ -1452,9 +1339,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_xml_array: Option = if !body.is_empty() { @@ -1470,13 +1356,12 @@ where None }; - Box::new( - api_impl.xml_post( + let result = api_impl.xml_post( param_xml_array, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1507,17 +1392,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter XmlArray: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter XmlArray"))), + .expect("Unable to create Bad Request response due to unable to read body parameter XmlArray")), } - }) - ) as Self::Future }, // XmlPut - PUT /xml @@ -1525,9 +1406,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_xml_object: Option = if !body.is_empty() { @@ -1543,13 +1423,12 @@ where None }; - Box::new( - api_impl.xml_put( + let result = api_impl.xml_put( param_xml_object, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1580,17 +1459,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter XmlObject: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter XmlObject"))), + .expect("Unable to create Bad Request response due to unable to read body parameter XmlObject")), } - }) - ) as Self::Future }, // CreateRepo - POST /repos @@ -1598,9 +1473,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_object_param: Option = if !body.is_empty() { @@ -1610,29 +1484,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_object_param) => param_object_param, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter ObjectParam - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter ObjectParam due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter ObjectParam due to schema")), } } else { None }; let param_object_param = match param_object_param { Some(param_object_param) => param_object_param, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter ObjectParam")) - .expect("Unable to create Bad Request response for missing body parameter ObjectParam"))), + .expect("Unable to create Bad Request response for missing body parameter ObjectParam")), }; - Box::new( - api_impl.create_repo( + let result = api_impl.create_repo( param_object_param, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1659,17 +1532,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter ObjectParam: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter ObjectParam"))), + .expect("Unable to create Bad Request response due to unable to read body parameter ObjectParam")), } - }) - ) as Self::Future }, // GetRepoInfo - GET /repos/{repoId} @@ -1686,26 +1555,23 @@ where let param_repo_id = match percent_encoding::percent_decode(path_params["repoId"].as_bytes()).decode_utf8() { Ok(param_repo_id) => match param_repo_id.parse::() { Ok(param_repo_id) => param_repo_id, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter repoId: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["repoId"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.get_repo_info( + let result = api_impl.get_repo_info( param_repo_id, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1732,11 +1598,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, _ if path.matched(paths::ID_CALLBACK_WITH_HEADER) => method_not_allowed(), @@ -1760,23 +1622,11 @@ where _ if path.matched(paths::ID_XML) => method_not_allowed(), _ if path.matched(paths::ID_XML_EXTRA) => method_not_allowed(), _ if path.matched(paths::ID_XML_OTHER) => method_not_allowed(), - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } /// Request parser for `Api`. diff --git a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml index 5785f23fafc..793ffbb6c00 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "hyper", "hyper-openssl", "native-tls", "openssl", "url" + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" @@ -18,35 +18,37 @@ conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk- [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.4", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.7.1", optional = true } +hyper-openssl = { version = "0.8", optional = true } openssl = {version = "0.10", optional = true } [dependencies] # Common +async-trait = "0.1.24" chrono = { version = "0.4", features = ["serde"] } -futures = "0.1" -swagger = "4.0" +futures = "0.3" +swagger = "5.0.0-alpha-1" log = "0.4.0" mime = "0.3" -serde = { version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Crates included if required by the API definition # Common between server and client features -hyper = {version = "0.12", optional = true} -serde_ignored = {version = "0.0.4", optional = true} -url = {version = "1.5", optional = true} +hyper = {version = "0.13", optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} # Client-specific # Server, and client callback-specific lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} # Conversion frunk = { version = "0.3.0", optional = true } @@ -57,13 +59,13 @@ frunk-enum-core = { version = "0.2.0", optional = true } [dev-dependencies] clap = "2.25" -error-chain = "0.12" -env_logger = "0.6" -tokio = "0.1.17" -uuid = {version = "0.7", features = ["serde", "v4"]} +env_logger = "0.7" +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"] } +native-tls = "0.2" +tokio-tls = "0.3" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] -tokio-openssl = "0.3" +tokio-openssl = "0.4" openssl = "0.10" [[example]] diff --git a/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs index 9a9e8fa74ac..4b79043b5cc 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs @@ -2,10 +2,9 @@ #[allow(unused_imports)] -use futures::{Future, future, Stream, stream}; +use futures::{future, Stream, stream}; #[allow(unused_imports)] use ops_v3::{Api, ApiNoContext, Client, ContextWrapperExt, models, - ApiError, Op10GetResponse, Op11GetResponse, Op12GetResponse, @@ -42,7 +41,7 @@ use ops_v3::{Api, ApiNoContext, Client, ContextWrapperExt, models, Op6GetResponse, Op7GetResponse, Op8GetResponse, - Op9GetResponse + Op9GetResponse, }; use clap::{App, Arg}; @@ -51,7 +50,9 @@ use log::info; // swagger::Has may be unused if there are no examples #[allow(unused_imports)] -use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData}; +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); // rt may be unused if there are no examples #[allow(unused_mut)] @@ -123,21 +124,21 @@ fn main() { matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if matches.is_present("https") { - // Using Simple HTTPS - Client::try_new_https(&base_url) - .expect("Failed to create HTTPS client") - } else { - // Using HTTP - Client::try_new_http( - &base_url) - .expect("Failed to create HTTP client") - }; - - let context: swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString) = + let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, None as Option, XSpanIdString::default()); - let client = client.with_context(context); + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; let mut rt = tokio::runtime::Runtime::new().unwrap(); diff --git a/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs index c6ddb834be8..2e7d3031162 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs @@ -9,7 +9,8 @@ mod server; /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let matches = App::new("server") @@ -20,5 +21,5 @@ fn main() { let addr = "127.0.0.1:8080"; - hyper::rt::run(server::create(addr, matches.is_present("https"))); + server::create(addr, matches.is_present("https")).await; } diff --git a/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs index 62fb2ae73b4..144be9030d7 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; - -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use ops_v3::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = ops_v3::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } @@ -105,7 +96,6 @@ impl Server { use ops_v3::{ Api, - ApiError, Op10GetResponse, Op11GetResponse, Op12GetResponse, @@ -145,339 +135,343 @@ use ops_v3::{ Op9GetResponse, }; use ops_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; -impl Api for Server where C: Has{ - fn op10_get( +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn op10_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op10_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op11_get( + async fn op11_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op11_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op12_get( + async fn op12_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op12_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op13_get( + async fn op13_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op13_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op14_get( + async fn op14_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op14_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op15_get( + async fn op15_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op15_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op16_get( + async fn op16_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op16_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op17_get( + async fn op17_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op17_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op18_get( + async fn op18_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op18_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op19_get( + async fn op19_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op19_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op1_get( + async fn op1_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op1_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op20_get( + async fn op20_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op20_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op21_get( + async fn op21_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op21_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op22_get( + async fn op22_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op22_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op23_get( + async fn op23_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op23_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op24_get( + async fn op24_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op24_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op25_get( + async fn op25_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op25_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op26_get( + async fn op26_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op26_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op27_get( + async fn op27_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op27_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op28_get( + async fn op28_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op28_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op29_get( + async fn op29_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op29_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op2_get( + async fn op2_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op2_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op30_get( + async fn op30_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op30_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op31_get( + async fn op31_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op31_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op32_get( + async fn op32_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op32_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op33_get( + async fn op33_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op33_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op34_get( + async fn op34_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op34_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op35_get( + async fn op35_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op35_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op36_get( + async fn op36_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op36_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op37_get( + async fn op37_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op37_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op3_get( + async fn op3_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op3_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op4_get( + async fn op4_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op4_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op5_get( + async fn op5_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op5_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op6_get( + async fn op6_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op6_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op7_get( + async fn op7_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op7_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op8_get( + async fn op8_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op8_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn op9_get( + async fn op9_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("op9_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs index 05ee715c58f..48817db8753 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs @@ -1,37 +1,38 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; + use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); use crate::{Api, Op10GetResponse, @@ -74,11 +75,11 @@ use crate::{Api, }; /// 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 { +fn into_base_path(input: impl TryInto, 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 uri = input.try_into()?; - let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?; + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; // Check the scheme if necessary if let Some(correct_scheme) = correct_scheme { @@ -88,38 +89,54 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result +pub struct Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, /// Base path of the API base_path: String, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client {{ base_path: {} }}", self.base_path) } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), base_path: self.base_path.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -132,30 +149,93 @@ impl Client /// /// # Arguments /// - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn try_new_with_connector( + pub fn try_new_with_connector( base_path: &str, protocol: Option<&'static str>, connector: C, - ) -> Result where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + ) -> Result { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Ok(Client { - client_service: Arc::new(client_service), + Ok(Self { + client_service, base_path: into_base_path(base_path, protocol)?, }) } +} +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(|e| ClientInitError::SslError(e))?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Client> +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" pub fn try_new_http( base_path: &str, ) -> Result { @@ -163,11 +243,20 @@ impl Client Self::try_new_with_connector(base_path, Some("http"), http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -180,7 +269,7 @@ impl Client /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -201,7 +290,7 @@ impl Client /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://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 @@ -227,17 +316,24 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn try_new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, base_path: &str, - ) -> Result { - Ok(Client { - client_service: client_service, + ) -> Result + { + Ok(Self { + client_service, base_path: into_base_path(base_path, None)?, }) } @@ -277,2641 +373,2580 @@ impl fmt::Display for ClientInitError { } } -impl error::Error for ClientInitError { +impl Error for ClientInitError { fn description(&self) -> &str { "Failed to produce a hyper client." } } -impl Api for Client where - C: Has , - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl Api for Client where + C: Has + Clone + Send + Sync + 'static, + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - fn op10_get( + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn op10_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op10", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op10GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op10GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op11_get( + async fn op11_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op11", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op11GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op11GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op12_get( + async fn op12_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op12", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op12GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op12GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op13_get( + async fn op13_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op13", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op13GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op13GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op14_get( + async fn op14_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op14", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op14GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op14GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op15_get( + async fn op15_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op15", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op15GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op15GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op16_get( + async fn op16_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op16", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op16GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op16GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op17_get( + async fn op17_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op17", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op17GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op17GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op18_get( + async fn op18_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op18", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op18GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op18GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op19_get( + async fn op19_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op19", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op19GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op19GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op1_get( + async fn op1_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op1", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op1GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op1GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op20_get( + async fn op20_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op20", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op20GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op20GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op21_get( + async fn op21_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op21", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op21GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op21GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op22_get( + async fn op22_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op22", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op22GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op22GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op23_get( + async fn op23_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op23", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op23GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op23GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op24_get( + async fn op24_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op24", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op24GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op24GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op25_get( + async fn op25_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op25", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op25GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op25GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op26_get( + async fn op26_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op26", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op26GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op26GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op27_get( + async fn op27_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op27", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op27GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op27GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op28_get( + async fn op28_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op28", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op28GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op28GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op29_get( + async fn op29_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op29", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op29GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op29GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op2_get( + async fn op2_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op2", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op2GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op2GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op30_get( + async fn op30_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op30", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op30GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op30GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op31_get( + async fn op31_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op31", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op31GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op31GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op32_get( + async fn op32_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op32", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op32GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op32GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op33_get( + async fn op33_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op33", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op33GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op33GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op34_get( + async fn op34_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op34", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op34GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op34GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op35_get( + async fn op35_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op35", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op35GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op35GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op36_get( + async fn op36_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op36", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op36GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op36GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op37_get( + async fn op37_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op37", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op37GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op37GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op3_get( + async fn op3_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op3", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op3GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op3GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op4_get( + async fn op4_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op4", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op4GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op4GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op5_get( + async fn op5_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op5", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op5GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op5GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op6_get( + async fn op6_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op6", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op6GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op6GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op7_get( + async fn op7_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op7", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op7GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op7GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op8_get( + async fn op8_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op8", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op8GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op8GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn op9_get( + async fn op9_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/op9", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Op9GetResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Op9GetResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/context.rs b/samples/server/petstore/rust-server/output/ops-v3/src/context.rs index d14e73f822d..fadd880b965 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/context.rs @@ -1,13 +1,12 @@ -use futures::Future; -use hyper; +use futures::future::BoxFuture; use hyper::header::HeaderName; -use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload}; +use hyper::{Error, Request, Response, StatusCode, service::Service}; use url::form_urlencoded; use std::default::Default; use std::io; use std::marker::PhantomData; +use std::task::{Poll, Context}; use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; -use swagger::context::ContextualPayload; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; use crate::Api; @@ -31,58 +30,52 @@ where } // Make a service that adds context. -impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for +impl Service for MakeAddContext where - A: Default + Push, + Target: Send, + A: Default + Push + Send, B: Push, Result = C>, C: Push, Result = D>, D: Send + 'static, - T: hyper::service::MakeService< - &'a SC, - Error = E, - MakeError = ME, - Service = S, - ReqBody = ContextualPayload, - ResBody = OB, - Future = F - >, - S: Service< - Error = E, - ReqBody = ContextualPayload, - ResBody = OB> + 'static, - ME: swagger::ErrorBound, - E: swagger::ErrorBound, - F: Future + Send + 'static, - S::Future: Send, - OB: Payload, + T: Service + Send, + T::Future: Send + 'static { - type ReqBody = hyper::Body; - type ResBody = OB; - type Error = E; - type MakeError = ME; - type Service = AddContext; - type Future = Box + Send + 'static>; + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; - fn make_service(&mut self, ctx: &'a SC) -> Self::Future { - Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s))) + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) } } -/// Middleware to extract authentication data from request -pub struct AddContext { +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, C: Push, Result = D>, - T: Service, { - pub fn new(inner: T) -> AddContext { + pub fn new(inner: T) -> Self { AddContext { inner, marker: PhantomData, @@ -90,33 +83,31 @@ where } } -impl Service for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, C: Push, Result=D>, D: Send + 'static, - T: Service>, - T::Future: Future, Error=T::Error> + Send + 'static + T: Service<(Request, D)> { - type ReqBody = hyper::Body; - type ResBody = T::ResBody; type Error = T::Error; - type Future = Box, Error=T::Error> + Send + 'static>; + type Future = T::Future; + type Response = T::Response; - fn call(&mut self, req: Request) -> Self::Future { - let context = A::default().push(XSpanIdString::get_or_generate(&req)); - let (head, body) = req.into_parts(); - let headers = head.headers.clone(); + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); let context = context.push(None::); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - Box::new(self.inner.call(hyper::Request::from_parts(head, body))) + self.inner.call((request, context)) } } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs b/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs index 6cb9e0f31c2..11ba5e4a64a 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs @@ -1,12 +1,12 @@ #![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] +use async_trait::async_trait; use futures::Stream; -use std::io::Error; +use std::error::Error; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import swagger-rs directly")] -pub use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import futures directly")] -pub use futures::Future; +type ServiceError = Box; pub const BASE_PATH: &'static str = ""; pub const API_VERSION: &'static str = "0.0.1"; @@ -234,583 +234,642 @@ pub enum Op9GetResponse { } /// API -pub trait Api { - fn op10_get( - &self, - context: &C) -> Box + Send>; +#[async_trait] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } - fn op11_get( + async fn op10_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op12_get( + async fn op11_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op13_get( + async fn op12_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op14_get( + async fn op13_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op15_get( + async fn op14_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op16_get( + async fn op15_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op17_get( + async fn op16_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op18_get( + async fn op17_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op19_get( + async fn op18_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op1_get( + async fn op19_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op20_get( + async fn op1_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op21_get( + async fn op20_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op22_get( + async fn op21_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op23_get( + async fn op22_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op24_get( + async fn op23_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op25_get( + async fn op24_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op26_get( + async fn op25_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op27_get( + async fn op26_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op28_get( + async fn op27_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op29_get( + async fn op28_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op2_get( + async fn op29_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op30_get( + async fn op2_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op31_get( + async fn op30_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op32_get( + async fn op31_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op33_get( + async fn op32_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op34_get( + async fn op33_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op35_get( + async fn op34_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op36_get( + async fn op35_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op37_get( + async fn op36_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op3_get( + async fn op37_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op4_get( + async fn op3_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op5_get( + async fn op4_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op6_get( + async fn op5_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op7_get( + async fn op6_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op8_get( + async fn op7_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn op9_get( + async fn op8_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; + + async fn op9_get( + &self, + context: &C) -> Result; } -/// API without a `Context` -pub trait ApiNoContext { - fn op10_get( - &self, - ) -> Box + Send>; +/// API where `Context` isn't passed on every API call +#[async_trait] +pub trait ApiNoContext { - fn op11_get( - &self, - ) -> Box + Send>; + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn op12_get( - &self, - ) -> Box + Send>; + fn context(&self) -> &C; - fn op13_get( + async fn op10_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op14_get( + async fn op11_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op15_get( + async fn op12_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op16_get( + async fn op13_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op17_get( + async fn op14_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op18_get( + async fn op15_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op19_get( + async fn op16_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op1_get( + async fn op17_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op20_get( + async fn op18_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op21_get( + async fn op19_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op22_get( + async fn op1_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op23_get( + async fn op20_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op24_get( + async fn op21_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op25_get( + async fn op22_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op26_get( + async fn op23_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op27_get( + async fn op24_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op28_get( + async fn op25_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op29_get( + async fn op26_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op2_get( + async fn op27_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op30_get( + async fn op28_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op31_get( + async fn op29_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op32_get( + async fn op2_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op33_get( + async fn op30_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op34_get( + async fn op31_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op35_get( + async fn op32_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op36_get( + async fn op33_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op37_get( + async fn op34_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op3_get( + async fn op35_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op4_get( + async fn op36_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op5_get( + async fn op37_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op6_get( + async fn op3_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op7_get( + async fn op4_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op8_get( + async fn op5_get( &self, - ) -> Box + Send>; + ) -> Result; - fn op9_get( + async fn op6_get( &self, - ) -> Box + Send>; + ) -> Result; + + async fn op7_get( + &self, + ) -> Result; + + async fn op8_get( + &self, + ) -> Result; + + async fn op9_get( + &self, + ) -> Result; } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a, C> where Self: Sized { +pub trait ContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { - fn op10_get( - &self, - ) -> Box + Send> - { - self.api().op10_get(&self.context()) +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) } - fn op11_get( - &self, - ) -> Box + Send> - { - self.api().op11_get(&self.context()) + fn context(&self) -> &C { + ContextWrapper::context(self) } - fn op12_get( + async fn op10_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op12_get(&self.context()) + let context = self.context().clone(); + self.api().op10_get(&context).await } - fn op13_get( + async fn op11_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op13_get(&self.context()) + let context = self.context().clone(); + self.api().op11_get(&context).await } - fn op14_get( + async fn op12_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op14_get(&self.context()) + let context = self.context().clone(); + self.api().op12_get(&context).await } - fn op15_get( + async fn op13_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op15_get(&self.context()) + let context = self.context().clone(); + self.api().op13_get(&context).await } - fn op16_get( + async fn op14_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op16_get(&self.context()) + let context = self.context().clone(); + self.api().op14_get(&context).await } - fn op17_get( + async fn op15_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op17_get(&self.context()) + let context = self.context().clone(); + self.api().op15_get(&context).await } - fn op18_get( + async fn op16_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op18_get(&self.context()) + let context = self.context().clone(); + self.api().op16_get(&context).await } - fn op19_get( + async fn op17_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op19_get(&self.context()) + let context = self.context().clone(); + self.api().op17_get(&context).await } - fn op1_get( + async fn op18_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op1_get(&self.context()) + let context = self.context().clone(); + self.api().op18_get(&context).await } - fn op20_get( + async fn op19_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op20_get(&self.context()) + let context = self.context().clone(); + self.api().op19_get(&context).await } - fn op21_get( + async fn op1_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op21_get(&self.context()) + let context = self.context().clone(); + self.api().op1_get(&context).await } - fn op22_get( + async fn op20_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op22_get(&self.context()) + let context = self.context().clone(); + self.api().op20_get(&context).await } - fn op23_get( + async fn op21_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op23_get(&self.context()) + let context = self.context().clone(); + self.api().op21_get(&context).await } - fn op24_get( + async fn op22_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op24_get(&self.context()) + let context = self.context().clone(); + self.api().op22_get(&context).await } - fn op25_get( + async fn op23_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op25_get(&self.context()) + let context = self.context().clone(); + self.api().op23_get(&context).await } - fn op26_get( + async fn op24_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op26_get(&self.context()) + let context = self.context().clone(); + self.api().op24_get(&context).await } - fn op27_get( + async fn op25_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op27_get(&self.context()) + let context = self.context().clone(); + self.api().op25_get(&context).await } - fn op28_get( + async fn op26_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op28_get(&self.context()) + let context = self.context().clone(); + self.api().op26_get(&context).await } - fn op29_get( + async fn op27_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op29_get(&self.context()) + let context = self.context().clone(); + self.api().op27_get(&context).await } - fn op2_get( + async fn op28_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op2_get(&self.context()) + let context = self.context().clone(); + self.api().op28_get(&context).await } - fn op30_get( + async fn op29_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op30_get(&self.context()) + let context = self.context().clone(); + self.api().op29_get(&context).await } - fn op31_get( + async fn op2_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op31_get(&self.context()) + let context = self.context().clone(); + self.api().op2_get(&context).await } - fn op32_get( + async fn op30_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op32_get(&self.context()) + let context = self.context().clone(); + self.api().op30_get(&context).await } - fn op33_get( + async fn op31_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op33_get(&self.context()) + let context = self.context().clone(); + self.api().op31_get(&context).await } - fn op34_get( + async fn op32_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op34_get(&self.context()) + let context = self.context().clone(); + self.api().op32_get(&context).await } - fn op35_get( + async fn op33_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op35_get(&self.context()) + let context = self.context().clone(); + self.api().op33_get(&context).await } - fn op36_get( + async fn op34_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op36_get(&self.context()) + let context = self.context().clone(); + self.api().op34_get(&context).await } - fn op37_get( + async fn op35_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op37_get(&self.context()) + let context = self.context().clone(); + self.api().op35_get(&context).await } - fn op3_get( + async fn op36_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op3_get(&self.context()) + let context = self.context().clone(); + self.api().op36_get(&context).await } - fn op4_get( + async fn op37_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op4_get(&self.context()) + let context = self.context().clone(); + self.api().op37_get(&context).await } - fn op5_get( + async fn op3_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op5_get(&self.context()) + let context = self.context().clone(); + self.api().op3_get(&context).await } - fn op6_get( + async fn op4_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op6_get(&self.context()) + let context = self.context().clone(); + self.api().op4_get(&context).await } - fn op7_get( + async fn op5_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op7_get(&self.context()) + let context = self.context().clone(); + self.api().op5_get(&context).await } - fn op8_get( + async fn op6_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op8_get(&self.context()) + let context = self.context().clone(); + self.api().op6_get(&context).await } - fn op9_get( + async fn op7_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().op9_get(&self.context()) + let context = self.context().clone(); + self.api().op7_get(&context).await + } + + async fn op8_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op8_get(&context).await + } + + async fn op9_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op9_get(&context).await } } + #[cfg(feature = "client")] pub mod client; diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs index 39fc3172378..12ea69e707f 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs @@ -1,20 +1,17 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; +use url::form_urlencoded; #[allow(unused_imports)] use crate::models; @@ -22,6 +19,8 @@ use crate::header; pub use crate::context; +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + use crate::{Api, Op10GetResponse, Op11GetResponse, @@ -146,15 +145,17 @@ mod paths { pub(crate) static ID_OP9: usize = 36; } -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -164,44 +165,45 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -210,36 +212,48 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has + 'static + Send + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; match &method { // Op10Get - GET /op10 &hyper::Method::GET if path.matched(paths::ID_OP10) => { - Box::new({ - {{ - Box::new( - api_impl.op10_get( + let result = api_impl.op10_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -259,23 +273,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op11Get - GET /op11 &hyper::Method::GET if path.matched(paths::ID_OP11) => { - Box::new({ - {{ - Box::new( - api_impl.op11_get( + let result = api_impl.op11_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -295,23 +302,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op12Get - GET /op12 &hyper::Method::GET if path.matched(paths::ID_OP12) => { - Box::new({ - {{ - Box::new( - api_impl.op12_get( + let result = api_impl.op12_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -331,23 +331,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op13Get - GET /op13 &hyper::Method::GET if path.matched(paths::ID_OP13) => { - Box::new({ - {{ - Box::new( - api_impl.op13_get( + let result = api_impl.op13_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -367,23 +360,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op14Get - GET /op14 &hyper::Method::GET if path.matched(paths::ID_OP14) => { - Box::new({ - {{ - Box::new( - api_impl.op14_get( + let result = api_impl.op14_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -403,23 +389,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op15Get - GET /op15 &hyper::Method::GET if path.matched(paths::ID_OP15) => { - Box::new({ - {{ - Box::new( - api_impl.op15_get( + let result = api_impl.op15_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -439,23 +418,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op16Get - GET /op16 &hyper::Method::GET if path.matched(paths::ID_OP16) => { - Box::new({ - {{ - Box::new( - api_impl.op16_get( + let result = api_impl.op16_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -475,23 +447,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op17Get - GET /op17 &hyper::Method::GET if path.matched(paths::ID_OP17) => { - Box::new({ - {{ - Box::new( - api_impl.op17_get( + let result = api_impl.op17_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -511,23 +476,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op18Get - GET /op18 &hyper::Method::GET if path.matched(paths::ID_OP18) => { - Box::new({ - {{ - Box::new( - api_impl.op18_get( + let result = api_impl.op18_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -547,23 +505,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op19Get - GET /op19 &hyper::Method::GET if path.matched(paths::ID_OP19) => { - Box::new({ - {{ - Box::new( - api_impl.op19_get( + let result = api_impl.op19_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -583,23 +534,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op1Get - GET /op1 &hyper::Method::GET if path.matched(paths::ID_OP1) => { - Box::new({ - {{ - Box::new( - api_impl.op1_get( + let result = api_impl.op1_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -619,23 +563,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op20Get - GET /op20 &hyper::Method::GET if path.matched(paths::ID_OP20) => { - Box::new({ - {{ - Box::new( - api_impl.op20_get( + let result = api_impl.op20_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -655,23 +592,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op21Get - GET /op21 &hyper::Method::GET if path.matched(paths::ID_OP21) => { - Box::new({ - {{ - Box::new( - api_impl.op21_get( + let result = api_impl.op21_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -691,23 +621,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op22Get - GET /op22 &hyper::Method::GET if path.matched(paths::ID_OP22) => { - Box::new({ - {{ - Box::new( - api_impl.op22_get( + let result = api_impl.op22_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -727,23 +650,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op23Get - GET /op23 &hyper::Method::GET if path.matched(paths::ID_OP23) => { - Box::new({ - {{ - Box::new( - api_impl.op23_get( + let result = api_impl.op23_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -763,23 +679,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op24Get - GET /op24 &hyper::Method::GET if path.matched(paths::ID_OP24) => { - Box::new({ - {{ - Box::new( - api_impl.op24_get( + let result = api_impl.op24_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -799,23 +708,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op25Get - GET /op25 &hyper::Method::GET if path.matched(paths::ID_OP25) => { - Box::new({ - {{ - Box::new( - api_impl.op25_get( + let result = api_impl.op25_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -835,23 +737,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op26Get - GET /op26 &hyper::Method::GET if path.matched(paths::ID_OP26) => { - Box::new({ - {{ - Box::new( - api_impl.op26_get( + let result = api_impl.op26_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -871,23 +766,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op27Get - GET /op27 &hyper::Method::GET if path.matched(paths::ID_OP27) => { - Box::new({ - {{ - Box::new( - api_impl.op27_get( + let result = api_impl.op27_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -907,23 +795,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op28Get - GET /op28 &hyper::Method::GET if path.matched(paths::ID_OP28) => { - Box::new({ - {{ - Box::new( - api_impl.op28_get( + let result = api_impl.op28_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -943,23 +824,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op29Get - GET /op29 &hyper::Method::GET if path.matched(paths::ID_OP29) => { - Box::new({ - {{ - Box::new( - api_impl.op29_get( + let result = api_impl.op29_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -979,23 +853,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op2Get - GET /op2 &hyper::Method::GET if path.matched(paths::ID_OP2) => { - Box::new({ - {{ - Box::new( - api_impl.op2_get( + let result = api_impl.op2_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1015,23 +882,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op30Get - GET /op30 &hyper::Method::GET if path.matched(paths::ID_OP30) => { - Box::new({ - {{ - Box::new( - api_impl.op30_get( + let result = api_impl.op30_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1051,23 +911,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op31Get - GET /op31 &hyper::Method::GET if path.matched(paths::ID_OP31) => { - Box::new({ - {{ - Box::new( - api_impl.op31_get( + let result = api_impl.op31_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1087,23 +940,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op32Get - GET /op32 &hyper::Method::GET if path.matched(paths::ID_OP32) => { - Box::new({ - {{ - Box::new( - api_impl.op32_get( + let result = api_impl.op32_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1123,23 +969,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op33Get - GET /op33 &hyper::Method::GET if path.matched(paths::ID_OP33) => { - Box::new({ - {{ - Box::new( - api_impl.op33_get( + let result = api_impl.op33_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1159,23 +998,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op34Get - GET /op34 &hyper::Method::GET if path.matched(paths::ID_OP34) => { - Box::new({ - {{ - Box::new( - api_impl.op34_get( + let result = api_impl.op34_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1195,23 +1027,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op35Get - GET /op35 &hyper::Method::GET if path.matched(paths::ID_OP35) => { - Box::new({ - {{ - Box::new( - api_impl.op35_get( + let result = api_impl.op35_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1231,23 +1056,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op36Get - GET /op36 &hyper::Method::GET if path.matched(paths::ID_OP36) => { - Box::new({ - {{ - Box::new( - api_impl.op36_get( + let result = api_impl.op36_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1267,23 +1085,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op37Get - GET /op37 &hyper::Method::GET if path.matched(paths::ID_OP37) => { - Box::new({ - {{ - Box::new( - api_impl.op37_get( + let result = api_impl.op37_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1303,23 +1114,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op3Get - GET /op3 &hyper::Method::GET if path.matched(paths::ID_OP3) => { - Box::new({ - {{ - Box::new( - api_impl.op3_get( + let result = api_impl.op3_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1339,23 +1143,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op4Get - GET /op4 &hyper::Method::GET if path.matched(paths::ID_OP4) => { - Box::new({ - {{ - Box::new( - api_impl.op4_get( + let result = api_impl.op4_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1375,23 +1172,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op5Get - GET /op5 &hyper::Method::GET if path.matched(paths::ID_OP5) => { - Box::new({ - {{ - Box::new( - api_impl.op5_get( + let result = api_impl.op5_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1411,23 +1201,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op6Get - GET /op6 &hyper::Method::GET if path.matched(paths::ID_OP6) => { - Box::new({ - {{ - Box::new( - api_impl.op6_get( + let result = api_impl.op6_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1447,23 +1230,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op7Get - GET /op7 &hyper::Method::GET if path.matched(paths::ID_OP7) => { - Box::new({ - {{ - Box::new( - api_impl.op7_get( + let result = api_impl.op7_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1483,23 +1259,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op8Get - GET /op8 &hyper::Method::GET if path.matched(paths::ID_OP8) => { - Box::new({ - {{ - Box::new( - api_impl.op8_get( + let result = api_impl.op8_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1519,23 +1288,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // Op9Get - GET /op9 &hyper::Method::GET if path.matched(paths::ID_OP9) => { - Box::new({ - {{ - Box::new( - api_impl.op9_get( + let result = api_impl.op9_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1555,11 +1317,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, _ if path.matched(paths::ID_OP1) => method_not_allowed(), @@ -1599,23 +1357,11 @@ where _ if path.matched(paths::ID_OP7) => method_not_allowed(), _ if path.matched(paths::ID_OP8) => method_not_allowed(), _ if path.matched(paths::ID_OP9) => method_not_allowed(), - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } /// Request parser for `Api`. diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml index 1ee9b478cdb..869f0b722d7 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml @@ -12,7 +12,7 @@ client = [ "mime_0_2", "multipart", "multipart/client", "swagger/multipart", "serde_urlencoded", - "hyper", "hyper-openssl", "native-tls", "openssl", "url" + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "mime_0_2", @@ -23,20 +23,22 @@ conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk- [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.4", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.7.1", optional = true } +hyper-openssl = { version = "0.8", optional = true } openssl = {version = "0.10", optional = true } [dependencies] # Common +async-trait = "0.1.24" chrono = { version = "0.4", features = ["serde"] } -futures = "0.1" -swagger = "4.0" +futures = "0.3" +swagger = "5.0.0-alpha-1" log = "0.4.0" mime = "0.3" -serde = { version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Crates included if required by the API definition @@ -45,20 +47,20 @@ serde_json = "1.0" serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master"} mime_0_2 = { package = "mime", version = "0.2.6", optional = true } multipart = { version = "0.16", default-features = false, optional = true } -uuid = {version = "0.7", features = ["serde", "v4"]} +uuid = {version = "0.8", features = ["serde", "v4"]} # Common between server and client features -hyper = {version = "0.12", optional = true} -serde_ignored = {version = "0.0.4", optional = true} -url = {version = "1.5", optional = true} +hyper = {version = "0.13", optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} # Client-specific -serde_urlencoded = {version = "0.5.1", optional = true} +serde_urlencoded = {version = "0.6.1", optional = true} # Server, and client callback-specific lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} # Conversion frunk = { version = "0.3.0", optional = true } @@ -69,12 +71,13 @@ frunk-enum-core = { version = "0.2.0", optional = true } [dev-dependencies] clap = "2.25" -error-chain = "0.12" -env_logger = "0.6" -tokio = "0.1.17" +env_logger = "0.7" +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"] } +native-tls = "0.2" +tokio-tls = "0.3" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] -tokio-openssl = "0.3" +tokio-openssl = "0.4" openssl = "0.10" [[example]] diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs index 289c8b8ed58..27bf15f0c0a 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs @@ -2,10 +2,9 @@ #[allow(unused_imports)] -use futures::{Future, future, Stream, stream}; +use futures::{future, Stream, stream}; #[allow(unused_imports)] use petstore_with_fake_endpoints_models_for_testing::{Api, ApiNoContext, Client, ContextWrapperExt, models, - ApiError, TestSpecialTagsResponse, Call123exampleResponse, FakeOuterBooleanSerializeResponse, @@ -40,7 +39,7 @@ use petstore_with_fake_endpoints_models_for_testing::{Api, ApiNoContext, Client, GetUserByNameResponse, LoginUserResponse, LogoutUserResponse, - UpdateUserResponse + UpdateUserResponse, }; use clap::{App, Arg}; @@ -49,7 +48,9 @@ use log::info; // swagger::Has may be unused if there are no examples #[allow(unused_imports)] -use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData}; +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); // rt may be unused if there are no examples #[allow(unused_mut)] @@ -109,21 +110,21 @@ fn main() { matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if matches.is_present("https") { - // Using Simple HTTPS - Client::try_new_https(&base_url) - .expect("Failed to create HTTPS client") - } else { - // Using HTTP - Client::try_new_http( - &base_url) - .expect("Failed to create HTTP client") - }; - - let context: swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString) = + let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, None as Option, XSpanIdString::default()); - let client = client.with_context(context); + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; let mut rt = tokio::runtime::Runtime::new().unwrap(); diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs index dd00042a44b..89c605578a1 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs @@ -9,7 +9,8 @@ mod server; /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let matches = App::new("server") @@ -20,5 +21,5 @@ fn main() { let addr = "127.0.0.1:80"; - hyper::rt::run(server::create(addr, matches.is_present("https"))); + server::create(addr, matches.is_present("https")).await; } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs index d80bdcd6d25..76d906cb18d 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; -use uuid; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use petstore_with_fake_endpoints_models_for_testing::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = petstore_with_fake_endpoints_models_for_testing::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } @@ -105,7 +96,6 @@ impl Server { use petstore_with_fake_endpoints_models_for_testing::{ Api, - ApiError, TestSpecialTagsResponse, Call123exampleResponse, FakeOuterBooleanSerializeResponse, @@ -143,111 +133,115 @@ use petstore_with_fake_endpoints_models_for_testing::{ UpdateUserResponse, }; use petstore_with_fake_endpoints_models_for_testing::server::MakeService; +use std::error::Error; +use swagger::ApiError; -impl Api for Server where C: Has{ +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ /// To test special tags - fn test_special_tags( + async fn test_special_tags( &self, body: models::Client, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_special_tags({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn call123example( + async fn call123example( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("call123example() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn fake_outer_boolean_serialize( + async fn fake_outer_boolean_serialize( &self, body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("fake_outer_boolean_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn fake_outer_composite_serialize( + async fn fake_outer_composite_serialize( &self, body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("fake_outer_composite_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn fake_outer_number_serialize( + async fn fake_outer_number_serialize( &self, body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("fake_outer_number_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn fake_outer_string_serialize( + async fn fake_outer_string_serialize( &self, body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("fake_outer_string_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn fake_response_with_numerical_description( + async fn fake_response_with_numerical_description( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("fake_response_with_numerical_description() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn hyphen_param( + async fn hyphen_param( &self, hyphen_param: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("hyphen_param(\"{}\") - X-Span-ID: {:?}", hyphen_param, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn test_body_with_query_params( + async fn test_body_with_query_params( &self, query: String, body: models::User, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_body_with_query_params(\"{}\", {:?}) - X-Span-ID: {:?}", query, body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// To test \"client\" model - fn test_client_model( + async fn test_client_model( &self, body: models::Client, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_client_model({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters( + async fn test_endpoint_parameters( &self, number: f64, double: f64, @@ -263,15 +257,15 @@ impl Api for Server where C: Has{ date_time: Option>, password: Option, callback: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_endpoint_parameters({}, {}, \"{}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// To test enum parameters - fn test_enum_parameters( + async fn test_enum_parameters( &self, enum_header_string_array: Option<&Vec>, enum_header_string: Option, @@ -280,270 +274,270 @@ impl Api for Server where C: Has{ enum_query_integer: Option, enum_query_double: Option, enum_form_string: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// test inline additionalProperties - fn test_inline_additional_properties( + async fn test_inline_additional_properties( &self, param: std::collections::HashMap, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_inline_additional_properties({:?}) - X-Span-ID: {:?}", param, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// test json serialization of form data - fn test_json_form_data( + async fn test_json_form_data( &self, param: String, param2: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_json_form_data(\"{}\", \"{}\") - X-Span-ID: {:?}", param, param2, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// To test class name in snake case - fn test_classname( + async fn test_classname( &self, body: models::Client, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("test_classname({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Add a new pet to the store - fn add_pet( + async fn add_pet( &self, body: models::Pet, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("add_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Deletes a pet - fn delete_pet( + async fn delete_pet( &self, pet_id: i64, api_key: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("delete_pet({}, {:?}) - X-Span-ID: {:?}", pet_id, api_key, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Finds Pets by status - fn find_pets_by_status( + async fn find_pets_by_status( &self, status: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("find_pets_by_status({:?}) - X-Span-ID: {:?}", status, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Finds Pets by tags - fn find_pets_by_tags( + async fn find_pets_by_tags( &self, tags: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("find_pets_by_tags({:?}) - X-Span-ID: {:?}", tags, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Find pet by ID - fn get_pet_by_id( + async fn get_pet_by_id( &self, pet_id: i64, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("get_pet_by_id({}) - X-Span-ID: {:?}", pet_id, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Update an existing pet - fn update_pet( + async fn update_pet( &self, body: models::Pet, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("update_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Updates a pet in the store with form data - fn update_pet_with_form( + async fn update_pet_with_form( &self, pet_id: i64, name: Option, status: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("update_pet_with_form({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, name, status, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// uploads an image - fn upload_file( + async fn upload_file( &self, pet_id: i64, additional_metadata: Option, file: Option, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("upload_file({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, additional_metadata, file, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Delete purchase order by ID - fn delete_order( + async fn delete_order( &self, order_id: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("delete_order(\"{}\") - X-Span-ID: {:?}", order_id, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Returns pet inventories by status - fn get_inventory( + async fn get_inventory( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("get_inventory() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Find purchase order by ID - fn get_order_by_id( + async fn get_order_by_id( &self, order_id: i64, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("get_order_by_id({}) - X-Span-ID: {:?}", order_id, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Place an order for a pet - fn place_order( + async fn place_order( &self, body: models::Order, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("place_order({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Create user - fn create_user( + async fn create_user( &self, body: models::User, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("create_user({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Creates list of users with given input array - fn create_users_with_array_input( + async fn create_users_with_array_input( &self, body: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("create_users_with_array_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Creates list of users with given input array - fn create_users_with_list_input( + async fn create_users_with_list_input( &self, body: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("create_users_with_list_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Delete user - fn delete_user( + async fn delete_user( &self, username: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("delete_user(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Get user by user name - fn get_user_by_name( + async fn get_user_by_name( &self, username: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("get_user_by_name(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Logs user into the system - fn login_user( + async fn login_user( &self, username: String, password: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("login_user(\"{}\", \"{}\") - X-Span-ID: {:?}", username, password, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Logs out current logged in user session - fn logout_user( + async fn logout_user( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("logout_user() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Updated user - fn update_user( + async fn update_user( &self, username: String, body: models::User, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("update_user(\"{}\", {:?}) - X-Span-ID: {:?}", username, body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs index a6fd7282c34..f6e3986c318 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs @@ -1,42 +1,41 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; + use mime::Mime; use std::io::Cursor; use multipart::client::lazy::Multipart; -use uuid; -use serde_xml_rs; use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); use crate::{Api, TestSpecialTagsResponse, @@ -77,11 +76,11 @@ use crate::{Api, }; /// 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 { +fn into_base_path(input: impl TryInto, 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 uri = input.try_into()?; - let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?; + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; // Check the scheme if necessary if let Some(correct_scheme) = correct_scheme { @@ -91,38 +90,54 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result +pub struct Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, /// Base path of the API base_path: String, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client {{ base_path: {} }}", self.base_path) } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), base_path: self.base_path.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -135,30 +150,93 @@ impl Client /// /// # Arguments /// - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn try_new_with_connector( + pub fn try_new_with_connector( base_path: &str, protocol: Option<&'static str>, connector: C, - ) -> Result where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + ) -> Result { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Ok(Client { - client_service: Arc::new(client_service), + Ok(Self { + client_service, base_path: into_base_path(base_path, protocol)?, }) } +} +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(|e| ClientInitError::SslError(e))?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Client> +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" pub fn try_new_http( base_path: &str, ) -> Result { @@ -166,11 +244,20 @@ impl Client Self::try_new_with_connector(base_path, Some("http"), http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -183,7 +270,7 @@ impl Client /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -204,7 +291,7 @@ impl Client /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://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 @@ -230,17 +317,24 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn try_new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, base_path: &str, - ) -> Result { - Ok(Client { - client_service: client_service, + ) -> Result + { + Ok(Self { + client_service, base_path: into_base_path(base_path, None)?, }) } @@ -280,45 +374,61 @@ impl fmt::Display for ClientInitError { } } -impl error::Error for ClientInitError { +impl Error for ClientInitError { fn description(&self) -> &str { "Failed to produce a hyper client." } } -impl Api for Client where - C: Has + Has>, - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl Api for Client where + C: Has + Has> + Clone + Send + Sync + 'static, + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - fn test_special_tags( + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn test_special_tags( &self, param_body: models::Client, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/another-fake/dummy", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PATCH") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Body parameter @@ -329,162 +439,152 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(TestSpecialTagsResponse::SuccessfulOperation + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn call123example( + async fn call123example( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/operation-with-numeric-id", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - Call123exampleResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + Call123exampleResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn fake_outer_boolean_serialize( + async fn fake_outer_boolean_serialize( &self, param_body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/outer/boolean", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_body.map(|ref body| { @@ -497,90 +597,82 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(FakeOuterBooleanSerializeResponse::OutputBoolean + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn fake_outer_composite_serialize( + async fn fake_outer_composite_serialize( &self, param_body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/outer/composite", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_body.map(|ref body| { @@ -593,90 +685,82 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(FakeOuterCompositeSerializeResponse::OutputComposite + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn fake_outer_number_serialize( + async fn fake_outer_number_serialize( &self, param_body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/outer/number", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_body.map(|ref body| { @@ -689,90 +773,82 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(FakeOuterNumberSerializeResponse::OutputNumber + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn fake_outer_string_serialize( + async fn fake_outer_string_serialize( &self, param_body: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/outer/string", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_body.map(|ref body| { @@ -785,137 +861,125 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(FakeOuterStringSerializeResponse::OutputString + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn fake_response_with_numerical_description( + async fn fake_response_with_numerical_description( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/response-with-numerical-description", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - FakeResponseWithNumericalDescriptionResponse::Status200 - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + FakeResponseWithNumericalDescriptionResponse::Status200 + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn hyphen_param( + async fn hyphen_param( &self, param_hyphen_param: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/hyphenParam/{hyphen_param}", self.base_path @@ -923,98 +987,98 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - HyphenParamResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + HyphenParamResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn test_body_with_query_params( + async fn test_body_with_query_params( &self, param_query: String, param_body: models::User, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/body-with-query-params", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("query", ¶m_query.to_string()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("query", ¶m_query.to_string()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PUT") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); @@ -1023,78 +1087,76 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - TestBodyWithQueryParamsResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + TestBodyWithQueryParamsResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn test_client_model( + async fn test_client_model( &self, param_body: models::Client, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PATCH") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); @@ -1103,62 +1165,51 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(TestClientModelResponse::SuccessfulOperation + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn test_endpoint_parameters( + async fn test_endpoint_parameters( &self, param_number: f64, param_double: f64, @@ -1174,32 +1225,35 @@ impl Api for Client where param_date_time: Option>, param_password: Option, param_callback: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let params = &[ @@ -1223,23 +1277,23 @@ impl Api for Client where let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); *request.body_mut() = Body::from(body.into_bytes()); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Basic(ref basic_header) => { let auth = swagger::auth::Header(basic_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -1249,50 +1303,43 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - TestEndpointParametersResponse::InvalidUsernameSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - TestEndpointParametersResponse::UserNotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 400 => { + let body = response.into_body(); + Ok( + TestEndpointParametersResponse::InvalidUsernameSupplied + ) } - })) + 404 => { + let body = response.into_body(); + Ok( + TestEndpointParametersResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn test_enum_parameters( + async fn test_enum_parameters( &self, param_enum_header_string_array: Option<&Vec>, param_enum_header_string: Option, @@ -1301,44 +1348,47 @@ impl Api for Client where param_enum_query_integer: Option, param_enum_query_double: Option, param_enum_form_string: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - if let Some(param_enum_query_string_array) = param_enum_query_string_array { - query_string.append_pair("enum_query_string_array", ¶m_enum_query_string_array.iter().map(ToString::to_string).collect::>().join(",")); - } - if let Some(param_enum_query_string) = param_enum_query_string { - query_string.append_pair("enum_query_string", ¶m_enum_query_string.to_string()); - } - if let Some(param_enum_query_integer) = param_enum_query_integer { - query_string.append_pair("enum_query_integer", ¶m_enum_query_integer.to_string()); - } - if let Some(param_enum_query_double) = param_enum_query_double { - query_string.append_pair("enum_query_double", ¶m_enum_query_double.to_string()); - } - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_enum_query_string_array) = param_enum_query_string_array { + query_string.append_pair("enum_query_string_array", ¶m_enum_query_string_array.iter().map(ToString::to_string).collect::>().join(",")); + } + if let Some(param_enum_query_string) = param_enum_query_string { + query_string.append_pair("enum_query_string", ¶m_enum_query_string.to_string()); + } + if let Some(param_enum_query_integer) = param_enum_query_integer { + query_string.append_pair("enum_query_integer", ¶m_enum_query_integer.to_string()); + } + if let Some(param_enum_query_double) = param_enum_query_double { + query_string.append_pair("enum_query_double", ¶m_enum_query_double.to_string()); + } + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let params = &[ @@ -1349,13 +1399,13 @@ impl Api for Client where let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); *request.body_mut() = Body::from(body.into_bytes()); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); // Header parameters @@ -1366,8 +1416,8 @@ impl Api for Client where match header::IntoHeaderValue(param_enum_header_string_array.clone()).try_into() { Ok(header) => header, Err(e) => { - return Box::new(future::err(ApiError(format!( - "Invalid header enum_header_string_array - {}", e)))) as Box + Send>; + return Err(ApiError(format!( + "Invalid header enum_header_string_array - {}", e))); }, }); }, @@ -1381,86 +1431,82 @@ impl Api for Client where match header::IntoHeaderValue(param_enum_header_string.clone()).try_into() { Ok(header) => header, Err(e) => { - return Box::new(future::err(ApiError(format!( - "Invalid header enum_header_string - {}", e)))) as Box + Send>; + return Err(ApiError(format!( + "Invalid header enum_header_string - {}", e))); }, }); }, None => {} } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - TestEnumParametersResponse::InvalidRequest - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - TestEnumParametersResponse::NotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 400 => { + let body = response.into_body(); + Ok( + TestEnumParametersResponse::InvalidRequest + ) } - })) + 404 => { + let body = response.into_body(); + Ok( + TestEnumParametersResponse::NotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn test_inline_additional_properties( + async fn test_inline_additional_properties( &self, param_param: std::collections::HashMap, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/inline-additionalProperties", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_param).expect("impossible to fail to serialize"); @@ -1469,79 +1515,77 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - TestInlineAdditionalPropertiesResponse::SuccessfulOperation - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + TestInlineAdditionalPropertiesResponse::SuccessfulOperation + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn test_json_form_data( + async fn test_json_form_data( &self, param_param: String, param_param2: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake/jsonFormData", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let params = &[ @@ -1553,84 +1597,82 @@ impl Api for Client where let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); *request.body_mut() = Body::from(body.into_bytes()); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - TestJsonFormDataResponse::SuccessfulOperation - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + TestJsonFormDataResponse::SuccessfulOperation + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn test_classname( + async fn test_classname( &self, param_body: models::Client, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/fake_classname_test", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { - if let AuthData::ApiKey(ref api_key) = *auth_data { - query_string.append_pair("api_key_query", api_key); + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let AuthData::ApiKey(ref api_key) = *auth_data { + query_string.append_pair("api_key_query", api_key); + } } - } - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PATCH") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Body parameter @@ -1641,98 +1683,90 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { _ => {} } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(TestClassnameResponse::SuccessfulOperation + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn add_pet( + async fn add_pet( &self, param_body: models::Pet, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Body parameter @@ -1742,22 +1776,22 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -1767,47 +1801,43 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 405 => { - let body = response.into_body(); - Box::new( - future::ok( - AddPetResponse::InvalidInput - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 405 => { + let body = response.into_body(); + Ok( + AddPetResponse::InvalidInput + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn delete_pet( + async fn delete_pet( &self, param_pet_id: i64, param_api_key: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet/{pet_id}", self.base_path @@ -1815,40 +1845,42 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("DELETE") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -1866,95 +1898,93 @@ impl Api for Client where match header::IntoHeaderValue(param_api_key.clone()).try_into() { Ok(header) => header, Err(e) => { - return Box::new(future::err(ApiError(format!( - "Invalid header api_key - {}", e)))) as Box + Send>; + return Err(ApiError(format!( + "Invalid header api_key - {}", e))); }, }); }, None => {} } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - DeletePetResponse::InvalidPetValue - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 400 => { + let body = response.into_body(); + Ok( + DeletePetResponse::InvalidPetValue + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn find_pets_by_status( + async fn find_pets_by_status( &self, param_status: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet/findByStatus", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("status", ¶m_status.iter().map(ToString::to_string).collect::>().join(",")); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("status", ¶m_status.iter().map(ToString::to_string).collect::>().join(",")); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -1964,109 +1994,100 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - FindPetsByStatusResponse::InvalidStatusValue - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(FindPetsByStatusResponse::SuccessfulOperation + (body) + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + FindPetsByStatusResponse::InvalidStatusValue + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn find_pets_by_tags( + async fn find_pets_by_tags( &self, param_tags: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet/findByTags", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("tags", ¶m_tags.iter().map(ToString::to_string).collect::>().join(",")); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("tags", ¶m_tags.iter().map(ToString::to_string).collect::>().join(",")); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -2076,68 +2097,57 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - FindPetsByTagsResponse::InvalidTagValue - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(FindPetsByTagsResponse::SuccessfulOperation + (body) + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + FindPetsByTagsResponse::InvalidTagValue + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn get_pet_by_id( + async fn get_pet_by_id( &self, param_pet_id: i64, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet/{pet_id}", self.base_path @@ -2145,133 +2155,124 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { _ => {} } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - GetPetByIdResponse::InvalidIDSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - GetPetByIdResponse::PetNotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(GetPetByIdResponse::SuccessfulOperation + (body) + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + GetPetByIdResponse::InvalidIDSupplied + ) + } + 404 => { + let body = response.into_body(); + Ok( + GetPetByIdResponse::PetNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn update_pet( + async fn update_pet( &self, param_body: models::Pet, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PUT") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_body.to_xml(); @@ -2280,22 +2281,22 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -2305,64 +2306,56 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - UpdatePetResponse::InvalidIDSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - UpdatePetResponse::PetNotFound - ) - ) as Box + Send> - }, - 405 => { - let body = response.into_body(); - Box::new( - future::ok( - UpdatePetResponse::ValidationException - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 400 => { + let body = response.into_body(); + Ok( + UpdatePetResponse::InvalidIDSupplied + ) } - })) + 404 => { + let body = response.into_body(); + Ok( + UpdatePetResponse::PetNotFound + ) + } + 405 => { + let body = response.into_body(); + Ok( + UpdatePetResponse::ValidationException + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn update_pet_with_form( + async fn update_pet_with_form( &self, param_pet_id: i64, param_name: Option, param_status: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet/{pet_id}", self.base_path @@ -2370,24 +2363,26 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let params = &[ @@ -2399,23 +2394,23 @@ impl Api for Client where let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); *request.body_mut() = Body::from(body.into_bytes()); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -2425,48 +2420,44 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 405 => { - let body = response.into_body(); - Box::new( - future::ok( - UpdatePetWithFormResponse::InvalidInput - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 405 => { + let body = response.into_body(); + Ok( + UpdatePetWithFormResponse::InvalidInput + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn upload_file( + async fn upload_file( &self, param_pet_id: i64, param_additional_metadata: Option, param_file: Option, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/pet/{pet_id}/uploadImage", self.base_path @@ -2474,89 +2465,96 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let mut multipart = Multipart::new(); + let (body_string, multipart_header) = { + let mut multipart = Multipart::new(); - // For each parameter, encode as appropriate and add to the multipart body as a stream. + // For each parameter, encode as appropriate and add to the multipart body as a stream. - let additional_metadata_str = match serde_json::to_string(¶m_additional_metadata) { - Ok(str) => str, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse additional_metadata to string: {}", e)))), + let additional_metadata_str = match serde_json::to_string(¶m_additional_metadata) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to parse additional_metadata to string: {}", e))), + }; + + let additional_metadata_vec = additional_metadata_str.as_bytes().to_vec(); + let additional_metadata_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let additional_metadata_cursor = Cursor::new(additional_metadata_vec); + + multipart.add_stream("additional_metadata", additional_metadata_cursor, None as Option<&str>, Some(additional_metadata_mime)); + + + let file_str = match serde_json::to_string(¶m_file) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to parse file to string: {}", e))), + }; + + let file_vec = file_str.as_bytes().to_vec(); + let file_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let file_cursor = Cursor::new(file_vec); + + multipart.add_stream("file", file_cursor, None as Option<&str>, Some(file_mime)); + + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), + }; + + let mut body_string = String::new(); + + match fields.read_to_string(&mut body_string) { + Ok(_) => (), + Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), + } + + let boundary = fields.boundary(); + + let multipart_header = format!("multipart/form-data;boundary={}", boundary); + + (body_string, multipart_header) }; - let additional_metadata_vec = additional_metadata_str.as_bytes().to_vec(); - - let additional_metadata_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); - - let additional_metadata_cursor = Cursor::new(additional_metadata_vec); - - multipart.add_stream("additional_metadata", additional_metadata_cursor, None as Option<&str>, Some(additional_metadata_mime)); - - let file_str = match serde_json::to_string(¶m_file) { - Ok(str) => str, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse file to string: {}", e)))), - }; - - let file_vec = file_str.as_bytes().to_vec(); - - let file_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); - - let file_cursor = Cursor::new(file_vec); - - multipart.add_stream("file", file_cursor, None as Option<&str>, Some(file_mime)); - let mut fields = match multipart.prepare() { - Ok(fields) => fields, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build request: {}", err)))), - }; - - let mut body_string = String::new(); - match fields.read_to_string(&mut body_string) { - Ok(_) => (), - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build body: {}", err)))), - } - let boundary = fields.boundary(); - - let multipart_header = format!("multipart/form-data;boundary={}", boundary); - *request.body_mut() = Body::from(body_string); request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { &AuthData::Bearer(ref bearer_header) => { let auth = swagger::auth::Header(bearer_header.clone()); let header = match HeaderValue::from_str(&format!("{}", auth)) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, @@ -2566,58 +2564,48 @@ impl Api for Client where } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(UploadFileResponse::SuccessfulOperation + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn delete_order( + async fn delete_order( &self, param_order_id: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/store/order/{order_id}", self.base_path @@ -2625,170 +2613,158 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("DELETE") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - DeleteOrderResponse::InvalidIDSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - DeleteOrderResponse::OrderNotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 400 => { + let body = response.into_body(); + Ok( + DeleteOrderResponse::InvalidIDSupplied + ) } - })) + 404 => { + let body = response.into_body(); + Ok( + DeleteOrderResponse::OrderNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn get_inventory( + async fn get_inventory( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/store/inventory", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - if let Some(auth_data) = (context as &dyn Has>).get().as_ref() { + if let Some(auth_data) = Has::>::get(context).as_ref() { // Currently only authentication with Basic and Bearer are supported match auth_data { _ => {} } } - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::>(body)?; + Ok(GetInventoryResponse::SuccessfulOperation + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn get_order_by_id( + async fn get_order_by_id( &self, param_order_id: i64, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/store/order/{order_id}", self.base_path @@ -2796,126 +2772,117 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - GetOrderByIdResponse::InvalidIDSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - GetOrderByIdResponse::OrderNotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(GetOrderByIdResponse::SuccessfulOperation + (body) + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + GetOrderByIdResponse::InvalidIDSupplied + ) + } + 404 => { + let body = response.into_body(); + Ok( + GetOrderByIdResponse::OrderNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn place_order( + async fn place_order( &self, param_body: models::Order, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/store/order", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); @@ -2925,101 +2892,92 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - PlaceOrderResponse::InvalidOrder - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(PlaceOrderResponse::SuccessfulOperation + (body) + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + PlaceOrderResponse::InvalidOrder + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn create_user( + async fn create_user( &self, param_body: models::User, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; // Body parameter @@ -3029,78 +2987,76 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 0 => { - let body = response.into_body(); - Box::new( - future::ok( - CreateUserResponse::SuccessfulOperation - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 0 => { + let body = response.into_body(); + Ok( + CreateUserResponse::SuccessfulOperation + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn create_users_with_array_input( + async fn create_users_with_array_input( &self, param_body: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user/createWithArray", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); @@ -3109,78 +3065,76 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 0 => { - let body = response.into_body(); - Box::new( - future::ok( - CreateUsersWithArrayInputResponse::SuccessfulOperation - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 0 => { + let body = response.into_body(); + Ok( + CreateUsersWithArrayInputResponse::SuccessfulOperation + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn create_users_with_list_input( + async fn create_users_with_list_input( &self, param_body: &Vec, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user/createWithList", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); @@ -3189,54 +3143,50 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 0 => { - let body = response.into_body(); - Box::new( - future::ok( - CreateUsersWithListInputResponse::SuccessfulOperation - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 0 => { + let body = response.into_body(); + Ok( + CreateUsersWithListInputResponse::SuccessfulOperation + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn delete_user( + async fn delete_user( &self, param_username: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user/{username}", self.base_path @@ -3244,80 +3194,76 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("DELETE") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - DeleteUserResponse::InvalidUsernameSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - DeleteUserResponse::UserNotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 400 => { + let body = response.into_body(); + Ok( + DeleteUserResponse::InvalidUsernameSupplied + ) } - })) + 404 => { + let body = response.into_body(); + Ok( + DeleteUserResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn get_user_by_name( + async fn get_user_by_name( &self, param_username: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user/{username}", self.base_path @@ -3325,299 +3271,281 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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 + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - GetUserByNameResponse::InvalidUsernameSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - GetUserByNameResponse::UserNotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(GetUserByNameResponse::SuccessfulOperation + (body) + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + GetUserByNameResponse::InvalidUsernameSupplied + ) + } + 404 => { + let body = response.into_body(); + Ok( + GetUserByNameResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn login_user( + async fn login_user( &self, param_username: String, param_password: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user/login", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("username", ¶m_username.to_string()); - query_string.append_pair("password", ¶m_password.to_string()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("username", ¶m_username.to_string()); + query_string.append_pair("password", ¶m_password.to_string()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let response_x_rate_limit = match response.headers().get(HeaderName::from_static("x-rate-limit")) { - Some(response_x_rate_limit) => response_x_rate_limit.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header X-Rate-Limit for response 200 was not found.")))) as Box + Send>, - }; - let response_x_rate_limit = match TryInto::>::try_into(response_x_rate_limit) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header X-Rate-Limit for response 200 - {}", e)))) as Box + Send>; - }, - }; - let response_x_rate_limit = response_x_rate_limit.0; + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; - let response_x_expires_after = match response.headers().get(HeaderName::from_static("x-expires-after")) { - Some(response_x_expires_after) => response_x_expires_after.clone(), - None => return Box::new(future::err(ApiError(String::from("Required response header X-Expires-After for response 200 was not found.")))) as Box + Send>, - }; - let response_x_expires_after = match TryInto::>>::try_into(response_x_expires_after) { - Ok(value) => value, - Err(e) => { - return Box::new(future::err(ApiError(format!("Invalid response header X-Expires-After for response 200 - {}", e)))) as Box + Send>; - }, - }; - let response_x_expires_after = response_x_expires_after.0; + match response.status().as_u16() { + 200 => { + let response_x_rate_limit = match response.headers().get(HeaderName::from_static("x-rate-limit")) { + Some(response_x_rate_limit) => response_x_rate_limit.clone(), + None => { + return Err(ApiError(String::from("Required response header X-Rate-Limit for response 200 was not found."))); + } + }; + let response_x_rate_limit = match TryInto::>::try_into(response_x_rate_limit) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header X-Rate-Limit for response 200 - {}", e))); + }, + }; + let response_x_rate_limit = response_x_rate_limit.0; - let body = response.into_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 + Send> - }, - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - LoginUserResponse::InvalidUsername - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let response_x_expires_after = match response.headers().get(HeaderName::from_static("x-expires-after")) { + Some(response_x_expires_after) => response_x_expires_after.clone(), + None => { + return Err(ApiError(String::from("Required response header X-Expires-After for response 200 was not found."))); + } + }; + let response_x_expires_after = match TryInto::>>::try_into(response_x_expires_after) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header X-Expires-After for response 200 - {}", e))); + }, + }; + let response_x_expires_after = response_x_expires_after.0; + + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .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::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + Ok(LoginUserResponse::SuccessfulOperation + { + body: body, + x_rate_limit: response_x_rate_limit, + x_expires_after: response_x_expires_after, + } + ) } - })) + 400 => { + let body = response.into_body(); + Ok( + LoginUserResponse::InvalidUsername + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn logout_user( + async fn logout_user( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user/logout", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 0 => { - let body = response.into_body(); - Box::new( - future::ok( - LogoutUserResponse::SuccessfulOperation - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 0 => { + let body = response.into_body(); + Ok( + LogoutUserResponse::SuccessfulOperation + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn update_user( + async fn update_user( &self, param_username: String, param_body: models::User, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/v2/user/{username}", self.base_path @@ -3625,24 +3553,26 @@ impl Api for Client where ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PUT") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); @@ -3652,56 +3582,49 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 400 => { - let body = response.into_body(); - Box::new( - future::ok( - UpdateUserResponse::InvalidUserSupplied - ) - ) as Box + Send> - }, - 404 => { - let body = response.into_body(); - Box::new( - future::ok( - UpdateUserResponse::UserNotFound - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 400 => { + let body = response.into_body(); + Ok( + UpdateUserResponse::InvalidUserSupplied + ) } - })) + 404 => { + let body = response.into_body(); + Ok( + UpdateUserResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs index 0ea1fbb6ac8..d9b71134176 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs @@ -1,13 +1,12 @@ -use futures::Future; -use hyper; +use futures::future::BoxFuture; use hyper::header::HeaderName; -use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload}; +use hyper::{Error, Request, Response, StatusCode, service::Service}; use url::form_urlencoded; use std::default::Default; use std::io; use std::marker::PhantomData; +use std::task::{Poll, Context}; use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; -use swagger::context::ContextualPayload; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; use crate::Api; @@ -31,58 +30,52 @@ where } // Make a service that adds context. -impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for +impl Service for MakeAddContext where - A: Default + Push, + Target: Send, + A: Default + Push + Send, B: Push, Result = C>, C: Push, Result = D>, D: Send + 'static, - T: hyper::service::MakeService< - &'a SC, - Error = E, - MakeError = ME, - Service = S, - ReqBody = ContextualPayload, - ResBody = OB, - Future = F - >, - S: Service< - Error = E, - ReqBody = ContextualPayload, - ResBody = OB> + 'static, - ME: swagger::ErrorBound, - E: swagger::ErrorBound, - F: Future + Send + 'static, - S::Future: Send, - OB: Payload, + T: Service + Send, + T::Future: Send + 'static { - type ReqBody = hyper::Body; - type ResBody = OB; - type Error = E; - type MakeError = ME; - type Service = AddContext; - type Future = Box + Send + 'static>; + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; - fn make_service(&mut self, ctx: &'a SC) -> Self::Future { - Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s))) + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) } } -/// Middleware to extract authentication data from request -pub struct AddContext { +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, C: Push, Result = D>, - T: Service, { - pub fn new(inner: T) -> AddContext { + pub fn new(inner: T) -> Self { AddContext { inner, marker: PhantomData, @@ -90,24 +83,26 @@ where } } -impl Service for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, C: Push, Result=D>, D: Send + 'static, - T: Service>, - T::Future: Future, Error=T::Error> + Send + 'static + T: Service<(Request, D)> { - type ReqBody = hyper::Body; - type ResBody = T::ResBody; type Error = T::Error; - type Future = Box, Error=T::Error> + Send + 'static>; + type Future = T::Future; + type Response = T::Response; - fn call(&mut self, req: Request) -> Self::Future { - let context = A::default().push(XSpanIdString::get_or_generate(&req)); - let (head, body) = req.into_parts(); - let headers = head.headers.clone(); + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); { use swagger::auth::api_key_from_header; @@ -117,16 +112,11 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } { - let key = form_urlencoded::parse(head.uri.query().unwrap_or_default().as_bytes()) + let key = form_urlencoded::parse(request.uri().query().unwrap_or_default().as_bytes()) .filter(|e| e.0 == "api_key_query") .map(|e| e.1.clone().into_owned()) .nth(0); @@ -135,11 +125,7 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } { @@ -150,12 +136,7 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } { @@ -166,22 +147,13 @@ impl Service for AddContext let context = context.push(Some(auth_data)); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - - return Box::new(self.inner.call(hyper::Request::from_parts(head, body))); + return self.inner.call((request, context)) } } let context = context.push(None::); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - Box::new(self.inner.call(hyper::Request::from_parts(head, body))) + self.inner.call((request, context)) } } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs index 3fecf3101cb..03eae5fb765 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs @@ -1,12 +1,12 @@ #![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] +use async_trait::async_trait; use futures::Stream; -use std::io::Error; +use std::error::Error; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import swagger-rs directly")] -pub use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import futures directly")] -pub use futures::Future; +type ServiceError = Box; pub const BASE_PATH: &'static str = "/v2"; pub const API_VERSION: &'static str = "1.0.0"; @@ -306,60 +306,65 @@ pub enum UpdateUserResponse { } /// API -pub trait Api { +#[async_trait] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + /// To test special tags - fn test_special_tags( + async fn test_special_tags( &self, body: models::Client, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn call123example( + async fn call123example( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn fake_outer_boolean_serialize( + async fn fake_outer_boolean_serialize( &self, body: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn fake_outer_composite_serialize( + async fn fake_outer_composite_serialize( &self, body: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn fake_outer_number_serialize( + async fn fake_outer_number_serialize( &self, body: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn fake_outer_string_serialize( + async fn fake_outer_string_serialize( &self, body: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn fake_response_with_numerical_description( + async fn fake_response_with_numerical_description( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn hyphen_param( + async fn hyphen_param( &self, hyphen_param: String, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn test_body_with_query_params( + async fn test_body_with_query_params( &self, query: String, body: models::User, - context: &C) -> Box + Send>; + context: &C) -> Result; /// To test \"client\" model - fn test_client_model( + async fn test_client_model( &self, body: models::Client, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters( + async fn test_endpoint_parameters( &self, number: f64, double: f64, @@ -375,10 +380,10 @@ pub trait Api { date_time: Option>, password: Option, callback: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; /// To test enum parameters - fn test_enum_parameters( + async fn test_enum_parameters( &self, enum_header_string_array: Option<&Vec>, enum_header_string: Option, @@ -387,209 +392,215 @@ pub trait Api { enum_query_integer: Option, enum_query_double: Option, enum_form_string: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; /// test inline additionalProperties - fn test_inline_additional_properties( + async fn test_inline_additional_properties( &self, param: std::collections::HashMap, - context: &C) -> Box + Send>; + context: &C) -> Result; /// test json serialization of form data - fn test_json_form_data( + async fn test_json_form_data( &self, param: String, param2: String, - context: &C) -> Box + Send>; + context: &C) -> Result; /// To test class name in snake case - fn test_classname( + async fn test_classname( &self, body: models::Client, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Add a new pet to the store - fn add_pet( + async fn add_pet( &self, body: models::Pet, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Deletes a pet - fn delete_pet( + async fn delete_pet( &self, pet_id: i64, api_key: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Finds Pets by status - fn find_pets_by_status( + async fn find_pets_by_status( &self, status: &Vec, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Finds Pets by tags - fn find_pets_by_tags( + async fn find_pets_by_tags( &self, tags: &Vec, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Find pet by ID - fn get_pet_by_id( + async fn get_pet_by_id( &self, pet_id: i64, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Update an existing pet - fn update_pet( + async fn update_pet( &self, body: models::Pet, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Updates a pet in the store with form data - fn update_pet_with_form( + async fn update_pet_with_form( &self, pet_id: i64, name: Option, status: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; /// uploads an image - fn upload_file( + async fn upload_file( &self, pet_id: i64, additional_metadata: Option, file: Option, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Delete purchase order by ID - fn delete_order( + async fn delete_order( &self, order_id: String, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Returns pet inventories by status - fn get_inventory( + async fn get_inventory( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Find purchase order by ID - fn get_order_by_id( + async fn get_order_by_id( &self, order_id: i64, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Place an order for a pet - fn place_order( + async fn place_order( &self, body: models::Order, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Create user - fn create_user( + async fn create_user( &self, body: models::User, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Creates list of users with given input array - fn create_users_with_array_input( + async fn create_users_with_array_input( &self, body: &Vec, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Creates list of users with given input array - fn create_users_with_list_input( + async fn create_users_with_list_input( &self, body: &Vec, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Delete user - fn delete_user( + async fn delete_user( &self, username: String, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Get user by user name - fn get_user_by_name( + async fn get_user_by_name( &self, username: String, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Logs user into the system - fn login_user( + async fn login_user( &self, username: String, password: String, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Logs out current logged in user session - fn logout_user( + async fn logout_user( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Updated user - fn update_user( + async fn update_user( &self, username: String, body: models::User, - context: &C) -> Box + Send>; + context: &C) -> Result; } -/// API without a `Context` -pub trait ApiNoContext { +/// API where `Context` isn't passed on every API call +#[async_trait] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + /// To test special tags - fn test_special_tags( + async fn test_special_tags( &self, body: models::Client, - ) -> Box + Send>; + ) -> Result; - fn call123example( + async fn call123example( &self, - ) -> Box + Send>; + ) -> Result; - fn fake_outer_boolean_serialize( + async fn fake_outer_boolean_serialize( &self, body: Option, - ) -> Box + Send>; + ) -> Result; - fn fake_outer_composite_serialize( + async fn fake_outer_composite_serialize( &self, body: Option, - ) -> Box + Send>; + ) -> Result; - fn fake_outer_number_serialize( + async fn fake_outer_number_serialize( &self, body: Option, - ) -> Box + Send>; + ) -> Result; - fn fake_outer_string_serialize( + async fn fake_outer_string_serialize( &self, body: Option, - ) -> Box + Send>; + ) -> Result; - fn fake_response_with_numerical_description( + async fn fake_response_with_numerical_description( &self, - ) -> Box + Send>; + ) -> Result; - fn hyphen_param( + async fn hyphen_param( &self, hyphen_param: String, - ) -> Box + Send>; + ) -> Result; - fn test_body_with_query_params( + async fn test_body_with_query_params( &self, query: String, body: models::User, - ) -> Box + Send>; + ) -> Result; /// To test \"client\" model - fn test_client_model( + async fn test_client_model( &self, body: models::Client, - ) -> Box + Send>; + ) -> Result; /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters( + async fn test_endpoint_parameters( &self, number: f64, double: f64, @@ -605,10 +616,10 @@ pub trait ApiNoContext { date_time: Option>, password: Option, callback: Option, - ) -> Box + Send>; + ) -> Result; /// To test enum parameters - fn test_enum_parameters( + async fn test_enum_parameters( &self, enum_header_string_array: Option<&Vec>, enum_header_string: Option, @@ -617,250 +628,270 @@ pub trait ApiNoContext { enum_query_integer: Option, enum_query_double: Option, enum_form_string: Option, - ) -> Box + Send>; + ) -> Result; /// test inline additionalProperties - fn test_inline_additional_properties( + async fn test_inline_additional_properties( &self, param: std::collections::HashMap, - ) -> Box + Send>; + ) -> Result; /// test json serialization of form data - fn test_json_form_data( + async fn test_json_form_data( &self, param: String, param2: String, - ) -> Box + Send>; + ) -> Result; /// To test class name in snake case - fn test_classname( + async fn test_classname( &self, body: models::Client, - ) -> Box + Send>; + ) -> Result; /// Add a new pet to the store - fn add_pet( + async fn add_pet( &self, body: models::Pet, - ) -> Box + Send>; + ) -> Result; /// Deletes a pet - fn delete_pet( + async fn delete_pet( &self, pet_id: i64, api_key: Option, - ) -> Box + Send>; + ) -> Result; /// Finds Pets by status - fn find_pets_by_status( + async fn find_pets_by_status( &self, status: &Vec, - ) -> Box + Send>; + ) -> Result; /// Finds Pets by tags - fn find_pets_by_tags( + async fn find_pets_by_tags( &self, tags: &Vec, - ) -> Box + Send>; + ) -> Result; /// Find pet by ID - fn get_pet_by_id( + async fn get_pet_by_id( &self, pet_id: i64, - ) -> Box + Send>; + ) -> Result; /// Update an existing pet - fn update_pet( + async fn update_pet( &self, body: models::Pet, - ) -> Box + Send>; + ) -> Result; /// Updates a pet in the store with form data - fn update_pet_with_form( + async fn update_pet_with_form( &self, pet_id: i64, name: Option, status: Option, - ) -> Box + Send>; + ) -> Result; /// uploads an image - fn upload_file( + async fn upload_file( &self, pet_id: i64, additional_metadata: Option, file: Option, - ) -> Box + Send>; + ) -> Result; /// Delete purchase order by ID - fn delete_order( + async fn delete_order( &self, order_id: String, - ) -> Box + Send>; + ) -> Result; /// Returns pet inventories by status - fn get_inventory( + async fn get_inventory( &self, - ) -> Box + Send>; + ) -> Result; /// Find purchase order by ID - fn get_order_by_id( + async fn get_order_by_id( &self, order_id: i64, - ) -> Box + Send>; + ) -> Result; /// Place an order for a pet - fn place_order( + async fn place_order( &self, body: models::Order, - ) -> Box + Send>; + ) -> Result; /// Create user - fn create_user( + async fn create_user( &self, body: models::User, - ) -> Box + Send>; + ) -> Result; /// Creates list of users with given input array - fn create_users_with_array_input( + async fn create_users_with_array_input( &self, body: &Vec, - ) -> Box + Send>; + ) -> Result; /// Creates list of users with given input array - fn create_users_with_list_input( + async fn create_users_with_list_input( &self, body: &Vec, - ) -> Box + Send>; + ) -> Result; /// Delete user - fn delete_user( + async fn delete_user( &self, username: String, - ) -> Box + Send>; + ) -> Result; /// Get user by user name - fn get_user_by_name( + async fn get_user_by_name( &self, username: String, - ) -> Box + Send>; + ) -> Result; /// Logs user into the system - fn login_user( + async fn login_user( &self, username: String, password: String, - ) -> Box + Send>; + ) -> Result; /// Logs out current logged in user session - fn logout_user( + async fn logout_user( &self, - ) -> Box + Send>; + ) -> Result; /// Updated user - fn update_user( + async fn update_user( &self, username: String, body: models::User, - ) -> Box + Send>; + ) -> Result; } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a, C> where Self: Sized { +pub trait ContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + /// To test special tags - fn test_special_tags( + async fn test_special_tags( &self, body: models::Client, - ) -> Box + Send> + ) -> Result { - self.api().test_special_tags(body, &self.context()) + let context = self.context().clone(); + self.api().test_special_tags(body, &context).await } - fn call123example( + async fn call123example( &self, - ) -> Box + Send> + ) -> Result { - self.api().call123example(&self.context()) + let context = self.context().clone(); + self.api().call123example(&context).await } - fn fake_outer_boolean_serialize( + async fn fake_outer_boolean_serialize( &self, body: Option, - ) -> Box + Send> + ) -> Result { - self.api().fake_outer_boolean_serialize(body, &self.context()) + let context = self.context().clone(); + self.api().fake_outer_boolean_serialize(body, &context).await } - fn fake_outer_composite_serialize( + async fn fake_outer_composite_serialize( &self, body: Option, - ) -> Box + Send> + ) -> Result { - self.api().fake_outer_composite_serialize(body, &self.context()) + let context = self.context().clone(); + self.api().fake_outer_composite_serialize(body, &context).await } - fn fake_outer_number_serialize( + async fn fake_outer_number_serialize( &self, body: Option, - ) -> Box + Send> + ) -> Result { - self.api().fake_outer_number_serialize(body, &self.context()) + let context = self.context().clone(); + self.api().fake_outer_number_serialize(body, &context).await } - fn fake_outer_string_serialize( + async fn fake_outer_string_serialize( &self, body: Option, - ) -> Box + Send> + ) -> Result { - self.api().fake_outer_string_serialize(body, &self.context()) + let context = self.context().clone(); + self.api().fake_outer_string_serialize(body, &context).await } - fn fake_response_with_numerical_description( + async fn fake_response_with_numerical_description( &self, - ) -> Box + Send> + ) -> Result { - self.api().fake_response_with_numerical_description(&self.context()) + let context = self.context().clone(); + self.api().fake_response_with_numerical_description(&context).await } - fn hyphen_param( + async fn hyphen_param( &self, hyphen_param: String, - ) -> Box + Send> + ) -> Result { - self.api().hyphen_param(hyphen_param, &self.context()) + let context = self.context().clone(); + self.api().hyphen_param(hyphen_param, &context).await } - fn test_body_with_query_params( + async fn test_body_with_query_params( &self, query: String, body: models::User, - ) -> Box + Send> + ) -> Result { - self.api().test_body_with_query_params(query, body, &self.context()) + let context = self.context().clone(); + self.api().test_body_with_query_params(query, body, &context).await } /// To test \"client\" model - fn test_client_model( + async fn test_client_model( &self, body: models::Client, - ) -> Box + Send> + ) -> Result { - self.api().test_client_model(body, &self.context()) + let context = self.context().clone(); + self.api().test_client_model(body, &context).await } /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 - fn test_endpoint_parameters( + async fn test_endpoint_parameters( &self, number: f64, double: f64, @@ -876,13 +907,14 @@ impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { date_time: Option>, password: Option, callback: Option, - ) -> Box + Send> + ) -> Result { - self.api().test_endpoint_parameters(number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, &self.context()) + let context = self.context().clone(); + self.api().test_endpoint_parameters(number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, &context).await } /// To test enum parameters - fn test_enum_parameters( + async fn test_enum_parameters( &self, enum_header_string_array: Option<&Vec>, enum_header_string: Option, @@ -891,226 +923,251 @@ impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { enum_query_integer: Option, enum_query_double: Option, enum_form_string: Option, - ) -> Box + Send> + ) -> Result { - self.api().test_enum_parameters(enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, &self.context()) + let context = self.context().clone(); + self.api().test_enum_parameters(enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, &context).await } /// test inline additionalProperties - fn test_inline_additional_properties( + async fn test_inline_additional_properties( &self, param: std::collections::HashMap, - ) -> Box + Send> + ) -> Result { - self.api().test_inline_additional_properties(param, &self.context()) + let context = self.context().clone(); + self.api().test_inline_additional_properties(param, &context).await } /// test json serialization of form data - fn test_json_form_data( + async fn test_json_form_data( &self, param: String, param2: String, - ) -> Box + Send> + ) -> Result { - self.api().test_json_form_data(param, param2, &self.context()) + let context = self.context().clone(); + self.api().test_json_form_data(param, param2, &context).await } /// To test class name in snake case - fn test_classname( + async fn test_classname( &self, body: models::Client, - ) -> Box + Send> + ) -> Result { - self.api().test_classname(body, &self.context()) + let context = self.context().clone(); + self.api().test_classname(body, &context).await } /// Add a new pet to the store - fn add_pet( + async fn add_pet( &self, body: models::Pet, - ) -> Box + Send> + ) -> Result { - self.api().add_pet(body, &self.context()) + let context = self.context().clone(); + self.api().add_pet(body, &context).await } /// Deletes a pet - fn delete_pet( + async fn delete_pet( &self, pet_id: i64, api_key: Option, - ) -> Box + Send> + ) -> Result { - self.api().delete_pet(pet_id, api_key, &self.context()) + let context = self.context().clone(); + self.api().delete_pet(pet_id, api_key, &context).await } /// Finds Pets by status - fn find_pets_by_status( + async fn find_pets_by_status( &self, status: &Vec, - ) -> Box + Send> + ) -> Result { - self.api().find_pets_by_status(status, &self.context()) + let context = self.context().clone(); + self.api().find_pets_by_status(status, &context).await } /// Finds Pets by tags - fn find_pets_by_tags( + async fn find_pets_by_tags( &self, tags: &Vec, - ) -> Box + Send> + ) -> Result { - self.api().find_pets_by_tags(tags, &self.context()) + let context = self.context().clone(); + self.api().find_pets_by_tags(tags, &context).await } /// Find pet by ID - fn get_pet_by_id( + async fn get_pet_by_id( &self, pet_id: i64, - ) -> Box + Send> + ) -> Result { - self.api().get_pet_by_id(pet_id, &self.context()) + let context = self.context().clone(); + self.api().get_pet_by_id(pet_id, &context).await } /// Update an existing pet - fn update_pet( + async fn update_pet( &self, body: models::Pet, - ) -> Box + Send> + ) -> Result { - self.api().update_pet(body, &self.context()) + let context = self.context().clone(); + self.api().update_pet(body, &context).await } /// Updates a pet in the store with form data - fn update_pet_with_form( + async fn update_pet_with_form( &self, pet_id: i64, name: Option, status: Option, - ) -> Box + Send> + ) -> Result { - self.api().update_pet_with_form(pet_id, name, status, &self.context()) + let context = self.context().clone(); + self.api().update_pet_with_form(pet_id, name, status, &context).await } /// uploads an image - fn upload_file( + async fn upload_file( &self, pet_id: i64, additional_metadata: Option, file: Option, - ) -> Box + Send> + ) -> Result { - self.api().upload_file(pet_id, additional_metadata, file, &self.context()) + let context = self.context().clone(); + self.api().upload_file(pet_id, additional_metadata, file, &context).await } /// Delete purchase order by ID - fn delete_order( + async fn delete_order( &self, order_id: String, - ) -> Box + Send> + ) -> Result { - self.api().delete_order(order_id, &self.context()) + let context = self.context().clone(); + self.api().delete_order(order_id, &context).await } /// Returns pet inventories by status - fn get_inventory( + async fn get_inventory( &self, - ) -> Box + Send> + ) -> Result { - self.api().get_inventory(&self.context()) + let context = self.context().clone(); + self.api().get_inventory(&context).await } /// Find purchase order by ID - fn get_order_by_id( + async fn get_order_by_id( &self, order_id: i64, - ) -> Box + Send> + ) -> Result { - self.api().get_order_by_id(order_id, &self.context()) + let context = self.context().clone(); + self.api().get_order_by_id(order_id, &context).await } /// Place an order for a pet - fn place_order( + async fn place_order( &self, body: models::Order, - ) -> Box + Send> + ) -> Result { - self.api().place_order(body, &self.context()) + let context = self.context().clone(); + self.api().place_order(body, &context).await } /// Create user - fn create_user( + async fn create_user( &self, body: models::User, - ) -> Box + Send> + ) -> Result { - self.api().create_user(body, &self.context()) + let context = self.context().clone(); + self.api().create_user(body, &context).await } /// Creates list of users with given input array - fn create_users_with_array_input( + async fn create_users_with_array_input( &self, body: &Vec, - ) -> Box + Send> + ) -> Result { - self.api().create_users_with_array_input(body, &self.context()) + let context = self.context().clone(); + self.api().create_users_with_array_input(body, &context).await } /// Creates list of users with given input array - fn create_users_with_list_input( + async fn create_users_with_list_input( &self, body: &Vec, - ) -> Box + Send> + ) -> Result { - self.api().create_users_with_list_input(body, &self.context()) + let context = self.context().clone(); + self.api().create_users_with_list_input(body, &context).await } /// Delete user - fn delete_user( + async fn delete_user( &self, username: String, - ) -> Box + Send> + ) -> Result { - self.api().delete_user(username, &self.context()) + let context = self.context().clone(); + self.api().delete_user(username, &context).await } /// Get user by user name - fn get_user_by_name( + async fn get_user_by_name( &self, username: String, - ) -> Box + Send> + ) -> Result { - self.api().get_user_by_name(username, &self.context()) + let context = self.context().clone(); + self.api().get_user_by_name(username, &context).await } /// Logs user into the system - fn login_user( + async fn login_user( &self, username: String, password: String, - ) -> Box + Send> + ) -> Result { - self.api().login_user(username, password, &self.context()) + let context = self.context().clone(); + self.api().login_user(username, password, &context).await } /// Logs out current logged in user session - fn logout_user( + async fn logout_user( &self, - ) -> Box + Send> + ) -> Result { - self.api().logout_user(&self.context()) + let context = self.context().clone(); + self.api().logout_user(&context).await } /// Updated user - fn update_user( + async fn update_user( &self, username: String, body: models::User, - ) -> Box + Send> + ) -> Result { - self.api().update_user(username, body, &self.context()) + let context = self.context().clone(); + self.api().update_user(username, body, &context).await } } + #[cfg(feature = "client")] pub mod client; diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs index 723ac064003..1cbdc1fda25 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs @@ -1,24 +1,19 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; -use uuid; +use url::form_urlencoded; use multipart::server::Multipart; use multipart::server::save::SaveResult; -use serde_xml_rs; #[allow(unused_imports)] use crate::models; @@ -26,6 +21,8 @@ use crate::header; pub use crate::context; +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + use crate::{Api, TestSpecialTagsResponse, Call123exampleResponse, @@ -153,15 +150,17 @@ mod paths { } } -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -171,44 +170,45 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has + Has> + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -217,23 +217,38 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has + Has> + 'static + Send + C: Has + Has> + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; match &method { @@ -242,9 +257,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -254,29 +268,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.test_special_tags( + let result = api_impl.test_special_tags( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -310,29 +323,22 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // Call123example - GET /fake/operation-with-numeric-id &hyper::Method::GET if path.matched(paths::ID_FAKE_OPERATION_WITH_NUMERIC_ID) => { - Box::new({ - {{ - Box::new( - api_impl.call123example( + let result = api_impl.call123example( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -352,11 +358,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // FakeOuterBooleanSerialize - POST /fake/outer/boolean @@ -364,9 +366,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -382,13 +383,12 @@ where None }; - Box::new( - api_impl.fake_outer_boolean_serialize( + let result = api_impl.fake_outer_boolean_serialize( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -422,17 +422,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // FakeOuterCompositeSerialize - POST /fake/outer/composite @@ -440,9 +436,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -458,13 +453,12 @@ where None }; - Box::new( - api_impl.fake_outer_composite_serialize( + let result = api_impl.fake_outer_composite_serialize( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -498,17 +492,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // FakeOuterNumberSerialize - POST /fake/outer/number @@ -516,9 +506,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -534,13 +523,12 @@ where None }; - Box::new( - api_impl.fake_outer_number_serialize( + let result = api_impl.fake_outer_number_serialize( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -574,17 +562,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // FakeOuterStringSerialize - POST /fake/outer/string @@ -592,9 +576,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -610,13 +593,12 @@ where None }; - Box::new( - api_impl.fake_outer_string_serialize( + let result = api_impl.fake_outer_string_serialize( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -650,29 +632,22 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // FakeResponseWithNumericalDescription - GET /fake/response-with-numerical-description &hyper::Method::GET if path.matched(paths::ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION) => { - Box::new({ - {{ - Box::new( - api_impl.fake_response_with_numerical_description( + let result = api_impl.fake_response_with_numerical_description( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -692,11 +667,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // HyphenParam - GET /fake/hyphenParam/{hyphen-param} @@ -713,26 +684,23 @@ where let param_hyphen_param = match percent_encoding::percent_decode(path_params["hyphen-param"].as_bytes()).decode_utf8() { Ok(param_hyphen_param) => match param_hyphen_param.parse::() { Ok(param_hyphen_param) => param_hyphen_param, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter hyphen-param: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["hyphen-param"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.hyphen_param( + let result = api_impl.hyphen_param( param_hyphen_param, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -752,11 +720,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // TestBodyWithQueryParams - PUT /fake/body-with-query-params @@ -768,23 +732,22 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse query parameter query - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid query parameter query"))), + .expect("Unable to create Bad Request response for invalid query parameter query")), }, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required query parameter query")) - .expect("Unable to create Bad Request response for missing qeury parameter query"))), + .expect("Unable to create Bad Request response for missing qeury 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -794,30 +757,29 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.test_body_with_query_params( + let result = api_impl.test_body_with_query_params( param_query, param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -844,17 +806,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // TestClientModel - PATCH /fake @@ -862,9 +820,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -874,29 +831,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.test_client_model( + let result = api_impl.test_client_model( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -930,17 +886,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // TestEndpointParameters - POST /fake @@ -948,15 +900,13 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; } - Box::new({ - {{ // Form parameters let param_integer = Some(56); let param_int32 = Some(56); @@ -973,8 +923,7 @@ where let param_password = Some("password_example".to_string()); let param_callback = Some("callback_example".to_string()); - Box::new( - api_impl.test_endpoint_parameters( + let result = api_impl.test_endpoint_parameters( param_number, param_double, param_pattern_without_delimiter, @@ -990,9 +939,9 @@ where param_password, param_callback, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1016,11 +965,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // TestEnumParameters - GET /fake @@ -1033,10 +978,10 @@ where Ok(result) => Some(result.0), Err(err) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Invalid header enum_header_string_array - {}", err))) - .expect("Unable to create Bad Request response for invalid header enum_header_string_array"))); + .expect("Unable to create Bad Request response for invalid header enum_header_string_array")); }, }, @@ -1051,10 +996,10 @@ where Ok(result) => Some(result.0), Err(err) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Invalid header enum_header_string - {}", err))) - .expect("Unable to create Bad Request response for invalid header enum_header_string"))); + .expect("Unable to create Bad Request response for invalid header enum_header_string")); }, }, @@ -1083,13 +1028,10 @@ where .nth(0); let param_enum_query_double = param_enum_query_double.and_then(|param_enum_query_double| param_enum_query_double.parse::<>().ok()); - Box::new({ - {{ // Form parameters let param_enum_form_string = Some("enum_form_string_example".to_string()); - Box::new( - api_impl.test_enum_parameters( + let result = api_impl.test_enum_parameters( param_enum_header_string_array.as_ref(), param_enum_header_string, param_enum_query_string_array.as_ref(), @@ -1098,9 +1040,9 @@ where param_enum_query_double, param_enum_form_string, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1124,11 +1066,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // TestInlineAdditionalProperties - POST /fake/inline-additionalProperties @@ -1136,9 +1074,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_param: Option> = if !body.is_empty() { @@ -1148,29 +1085,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_param) => param_param, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter param - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter param due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter param due to schema")), } } else { None }; let param_param = match param_param { Some(param_param) => param_param, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter param")) - .expect("Unable to create Bad Request response for missing body parameter param"))), + .expect("Unable to create Bad Request response for missing body parameter param")), }; - Box::new( - api_impl.test_inline_additional_properties( + let result = api_impl.test_inline_additional_properties( param_param, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1197,35 +1133,28 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter param: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter param"))), + .expect("Unable to create Bad Request response due to unable to read body parameter param")), } - }) - ) as Self::Future }, // TestJsonFormData - GET /fake/jsonFormData &hyper::Method::GET if path.matched(paths::ID_FAKE_JSONFORMDATA) => { - 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( + let result = api_impl.test_json_form_data( param_param, param_param2, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1245,11 +1174,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // TestClassname - PATCH /fake_classname_test @@ -1257,19 +1182,18 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; } // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -1279,29 +1203,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.test_classname( + let result = api_impl.test_classname( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1335,17 +1258,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // AddPet - POST /pet @@ -1353,10 +1272,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -1368,14 +1287,14 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } @@ -1383,9 +1302,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -1395,29 +1313,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.add_pet( + let result = api_impl.add_pet( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1444,17 +1361,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // DeletePet - DELETE /pet/{petId} @@ -1462,10 +1375,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -1477,14 +1390,14 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } @@ -1501,15 +1414,15 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; // Header parameters @@ -1520,10 +1433,10 @@ where Ok(result) => Some(result.0), Err(err) => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Invalid header api_key - {}", err))) - .expect("Unable to create Bad Request response for invalid header api_key"))); + .expect("Unable to create Bad Request response for invalid header api_key")); }, }, @@ -1532,16 +1445,13 @@ where } }; - Box::new({ - {{ - Box::new( - api_impl.delete_pet( + let result = api_impl.delete_pet( param_pet_id, param_api_key, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1561,11 +1471,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // FindPetsByStatus - GET /pet/findByStatus @@ -1573,10 +1479,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -1588,14 +1494,14 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } @@ -1606,15 +1512,12 @@ where .filter_map(|param_status| param_status.parse().ok()) .collect::>(); - Box::new({ - {{ - Box::new( - api_impl.find_pets_by_status( + let result = api_impl.find_pets_by_status( param_status.as_ref(), &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1645,11 +1548,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // FindPetsByTags - GET /pet/findByTags @@ -1657,10 +1556,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -1672,14 +1571,14 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } @@ -1690,15 +1589,12 @@ where .filter_map(|param_tags| param_tags.parse().ok()) .collect::>(); - Box::new({ - {{ - Box::new( - api_impl.find_pets_by_tags( + let result = api_impl.find_pets_by_tags( param_tags.as_ref(), &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1729,11 +1625,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // GetPetById - GET /pet/{petId} @@ -1741,10 +1633,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; } @@ -1760,26 +1652,23 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.get_pet_by_id( + let result = api_impl.get_pet_by_id( param_pet_id, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1814,11 +1703,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // UpdatePet - PUT /pet @@ -1826,10 +1711,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -1841,14 +1726,14 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } @@ -1856,9 +1741,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -1868,29 +1752,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.update_pet( + let result = api_impl.update_pet( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -1925,17 +1808,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // UpdatePetWithForm - POST /pet/{petId} @@ -1943,10 +1822,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -1958,14 +1837,14 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } @@ -1982,32 +1861,29 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - 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( + let result = api_impl.update_pet_with_form( param_pet_id, param_name, param_status, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2027,11 +1903,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // UploadFile - POST /pet/{petId}/uploadImage @@ -2039,10 +1911,10 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; // Authorization @@ -2054,24 +1926,24 @@ where if !required_scopes.is_subset(scopes) { let missing_scopes = required_scopes.difference(scopes); - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), |s, scope| format!("{} {}", s, scope)) )) .expect("Unable to create Authentication Insufficient response") - )); + ); } } } let boundary = match swagger::multipart::boundary(&headers) { Some(boundary) => boundary.to_string(), - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Couldn't find valid multipart body".to_string())) - .expect("Unable to create Bad Request response for incorrect boundary"))), + .expect("Unable to create Bad Request response for incorrect boundary")), }; // Path parameters @@ -2086,23 +1958,22 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; // Form 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| -> Self::Future { - match result { + let result = body.to_raw(); + match result.await { Ok(body) => { use std::io::Read; @@ -2112,10 +1983,10 @@ where entries }, _ => { - return Box::new(future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Unable to process all message parts"))) - .expect("Unable to create Bad Request response due to failure to process all message"))) + .expect("Unable to create Bad Request response due to failure to process all message")) }, }; let field_additional_metadata = entries.fields.remove("additional_metadata"); @@ -2128,11 +1999,11 @@ where let additional_metadata_model: String = match serde_json::from_str(&data) { Ok(model) => model, Err(e) => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("additional_metadata data does not match API definition : {}", e))) - .expect("Unable to create Bad Request due to missing required form parameter additional_metadata"))) + .expect("Unable to create Bad Request due to missing required form parameter additional_metadata")) } }; additional_metadata_model @@ -2152,11 +2023,11 @@ where let file_model: swagger::ByteArray = match serde_json::from_str(&data) { Ok(model) => model, Err(e) => { - return Box::new(future::ok( + return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("file data does not match API definition : {}", e))) - .expect("Unable to create Bad Request due to missing required form parameter file"))) + .expect("Unable to create Bad Request due to missing required form parameter file")) } }; file_model @@ -2166,15 +2037,14 @@ where None } }; - Box::new( - api_impl.upload_file( + let result = api_impl.upload_file( param_pet_id, param_additional_metadata, param_file, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2201,18 +2071,13 @@ where }, } - future::ok(response) - } - )) - as Self::Future + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read multipart body"))) - .expect("Unable to create Bad Request response due to unable read multipart body"))), + .expect("Unable to create Bad Request response due to unable read multipart body")), } - }) - ) }, // DeleteOrder - DELETE /store/order/{order_id} @@ -2229,26 +2094,23 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter order_id: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.delete_order( + let result = api_impl.delete_order( param_order_id, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2272,11 +2134,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // GetInventory - GET /store/inventory @@ -2284,21 +2142,18 @@ where { let authorization = match (&context as &dyn Has>).get() { &Some(ref authorization) => authorization, - &None => return Box::new(future::ok(Response::builder() + &None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) .body(Body::from("Unauthenticated")) - .expect("Unable to create Authentication Forbidden response"))), + .expect("Unable to create Authentication Forbidden response")), }; } - Box::new({ - {{ - Box::new( - api_impl.get_inventory( + let result = api_impl.get_inventory( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2325,11 +2180,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // GetOrderById - GET /store/order/{order_id} @@ -2346,26 +2197,23 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter order_id: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.get_order_by_id( + let result = api_impl.get_order_by_id( param_order_id, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2400,11 +2248,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // PlaceOrder - POST /store/order @@ -2412,9 +2256,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -2424,29 +2267,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.place_order( + let result = api_impl.place_order( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2484,17 +2326,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // CreateUser - POST /user @@ -2502,9 +2340,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -2514,29 +2351,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.create_user( + let result = api_impl.create_user( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2563,17 +2399,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // CreateUsersWithArrayInput - POST /user/createWithArray @@ -2581,9 +2413,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option> = if !body.is_empty() { @@ -2593,29 +2424,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.create_users_with_array_input( + let result = api_impl.create_users_with_array_input( param_body.as_ref(), &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2642,17 +2472,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // CreateUsersWithListInput - POST /user/createWithList @@ -2660,9 +2486,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option> = if !body.is_empty() { @@ -2672,29 +2497,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.create_users_with_list_input( + let result = api_impl.create_users_with_list_input( param_body.as_ref(), &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2721,17 +2545,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // DeleteUser - DELETE /user/{username} @@ -2748,26 +2568,23 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter username: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.delete_user( + let result = api_impl.delete_user( param_username, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2791,11 +2608,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // GetUserByName - GET /user/{username} @@ -2812,26 +2625,23 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter username: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; - Box::new({ - {{ - Box::new( - api_impl.get_user_by_name( + let result = api_impl.get_user_by_name( param_username, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2866,11 +2676,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // LoginUser - GET /user/login @@ -2882,42 +2688,39 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse query parameter username - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid query parameter username"))), + .expect("Unable to create Bad Request response for invalid query parameter username")), }, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required query parameter username")) - .expect("Unable to create Bad Request response for missing qeury parameter username"))), + .expect("Unable to create Bad Request response for missing qeury 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse query parameter password - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid query parameter password"))), + .expect("Unable to create Bad Request response for invalid query parameter password")), }, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required query parameter password")) - .expect("Unable to create Bad Request response for missing qeury parameter password"))), + .expect("Unable to create Bad Request response for missing qeury parameter password")), }; - Box::new({ - {{ - Box::new( - api_impl.login_user( + let result = api_impl.login_user( param_username, param_password, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -2934,7 +2737,7 @@ where let x_rate_limit = match header::IntoHeaderValue(x_rate_limit).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling x_rate_limit header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -2944,7 +2747,7 @@ where let x_expires_after = match header::IntoHeaderValue(x_expires_after).try_into() { Ok(val) => val, Err(e) => { - return future::ok(Response::builder() + return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(Body::from(format!("An internal server error occurred handling x_expires_after header - {}", e))) .expect("Unable to create Internal Server Error for invalid response header")) @@ -2980,23 +2783,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // LogoutUser - GET /user/logout &hyper::Method::GET if path.matched(paths::ID_USER_LOGOUT) => { - Box::new({ - {{ - Box::new( - api_impl.logout_user( + let result = api_impl.logout_user( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -3016,11 +2812,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // UpdateUser - PUT /user/{username} @@ -3037,23 +2829,22 @@ where 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::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse path parameter username: {}", e))) - .expect("Unable to create Bad Request response for invalid path parameter"))), + .expect("Unable to create Bad Request response for invalid path parameter")), }, - Err(_) => return Box::new(future::ok(Response::builder() + Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) - .expect("Unable to create Bad Request response for invalid percent decode"))) + .expect("Unable to create Bad Request response for invalid percent decode")) }; // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_body: Option = if !body.is_empty() { @@ -3063,30 +2854,29 @@ where unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.update_user( + let result = api_impl.update_user( param_username, param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -3117,17 +2907,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, _ if path.matched(paths::ID_ANOTHER_FAKE_DUMMY) => method_not_allowed(), @@ -3157,23 +2943,11 @@ where _ if path.matched(paths::ID_USER_LOGIN) => method_not_allowed(), _ if path.matched(paths::ID_USER_LOGOUT) => method_not_allowed(), _ if path.matched(paths::ID_USER_USERNAME) => method_not_allowed(), - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } /// Request parser for `Api`. diff --git a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml index 8479e643bd6..adb71498607 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml +++ b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "hyper", "hyper-openssl", "native-tls", "openssl", "url" + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" @@ -18,35 +18,37 @@ conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk- [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.4", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.7.1", optional = true } +hyper-openssl = { version = "0.8", optional = true } openssl = {version = "0.10", optional = true } [dependencies] # Common +async-trait = "0.1.24" chrono = { version = "0.4", features = ["serde"] } -futures = "0.1" -swagger = "4.0" +futures = "0.3" +swagger = "5.0.0-alpha-1" log = "0.4.0" mime = "0.3" -serde = { version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Crates included if required by the API definition # Common between server and client features -hyper = {version = "0.12", optional = true} -serde_ignored = {version = "0.0.4", optional = true} -url = {version = "1.5", optional = true} +hyper = {version = "0.13", optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} # Client-specific # Server, and client callback-specific lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} # Conversion frunk = { version = "0.3.0", optional = true } @@ -57,13 +59,13 @@ frunk-enum-core = { version = "0.2.0", optional = true } [dev-dependencies] clap = "2.25" -error-chain = "0.12" -env_logger = "0.6" -tokio = "0.1.17" -uuid = {version = "0.7", features = ["serde", "v4"]} +env_logger = "0.7" +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"] } +native-tls = "0.2" +tokio-tls = "0.3" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] -tokio-openssl = "0.3" +tokio-openssl = "0.4" openssl = "0.10" [[example]] diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs index 1584d433fe7..e615b83c4f0 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs @@ -2,10 +2,9 @@ #[allow(unused_imports)] -use futures::{Future, future, Stream, stream}; +use futures::{future, Stream, stream}; #[allow(unused_imports)] use rust_server_test::{Api, ApiNoContext, Client, ContextWrapperExt, models, - ApiError, AllOfGetResponse, DummyGetResponse, DummyPutResponse, @@ -14,7 +13,7 @@ use rust_server_test::{Api, ApiNoContext, Client, ContextWrapperExt, models, HtmlPostResponse, PostYamlResponse, RawJsonGetResponse, - SoloObjectPostResponse + SoloObjectPostResponse, }; use clap::{App, Arg}; @@ -23,7 +22,9 @@ use log::info; // swagger::Has may be unused if there are no examples #[allow(unused_imports)] -use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData}; +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); // rt may be unused if there are no examples #[allow(unused_mut)] @@ -65,21 +66,21 @@ fn main() { matches.value_of("host").unwrap(), matches.value_of("port").unwrap()); - let client = if matches.is_present("https") { - // Using Simple HTTPS - Client::try_new_https(&base_url) - .expect("Failed to create HTTPS client") - } else { - // Using HTTP - Client::try_new_http( - &base_url) - .expect("Failed to create HTTP client") - }; - - let context: swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString) = + let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, None as Option, XSpanIdString::default()); - let client = client.with_context(context); + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; let mut rt = tokio::runtime::Runtime::new().unwrap(); diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs index cdf588968aa..1a3f8022c38 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs @@ -9,7 +9,8 @@ mod server; /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. -fn main() { +#[tokio::main] +async fn main() { env_logger::init(); let matches = App::new("server") @@ -20,5 +21,5 @@ fn main() { let addr = "127.0.0.1:8080"; - hyper::rt::run(server::create(addr, matches.is_present("https"))); + server::create(addr, matches.is_present("https")).await; } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs index 5fa44541184..6ab48764bdd 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs @@ -2,30 +2,22 @@ #![allow(unused_imports)] -mod errors { - error_chain::error_chain!{} -} - -pub use self::errors::*; - -use chrono; -use futures::{future, Future, Stream}; +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; use hyper::server::conn::Http; -use hyper::service::MakeService as _; +use hyper::service::Service; use log::info; use openssl::ssl::SslAcceptorBuilder; +use std::future::Future; use std::marker::PhantomData; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; -use swagger; +use std::task::{Context, Poll}; use swagger::{Has, XSpanIdString}; use swagger::auth::MakeAllowAllAuthenticator; use swagger::EmptyContext; use tokio::net::TcpListener; - -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use tokio_openssl::SslAcceptorExt; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; @@ -33,18 +25,18 @@ use rust_server_test::models; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -pub fn create(addr: &str, https: bool) -> Box + Send> { +pub async fn create(addr: &str, https: bool) { let addr = addr.parse().expect("Failed to parse bind address"); let server = Server::new(); - let service_fn = MakeService::new(server); + let service = MakeService::new(server); - let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo"); + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); - let service_fn = + let mut service = rust_server_test::server::context::MakeAddContext::<_, EmptyContext>::new( - service_fn + service ); if https { @@ -62,32 +54,31 @@ pub fn create(addr: &str, https: bool) -> Box ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set cerificate chain"); ssl.check_private_key().expect("Failed to check private key"); - let tls_acceptor = ssl.build(); - let service_fn = Arc::new(Mutex::new(service_fn)); - let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| { - let addr = tcp.peer_addr().expect("Unable to get remote address"); + let tls_acceptor = Arc::new(ssl.build()); + let mut tcp_listener = TcpListener::bind(&addr).await.unwrap(); + let mut incoming = tcp_listener.incoming(); - let service_fn = service_fn.clone(); + while let (Some(tcp), rest) = incoming.into_future().await { + if let Ok(tcp) = tcp { + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + let tls_acceptor = Arc::clone(&tls_acceptor); - hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| { - let ms = { - let mut service_fn = service_fn.lock().unwrap(); - service_fn.make_service(&addr) - }; + tokio::spawn(async move { + let tls = tokio_openssl::accept(&*tls_acceptor, tcp).await.map_err(|_| ())?; - ms.and_then(move |service| { - Http::new().serve_connection(tls, service) - }).map_err(|_| ()) - })); + let service = service.await.map_err(|_| ())?; - Ok(()) - }).map_err(|_| ()); + Http::new().serve_connection(tls, service).await.map_err(|_| ()) + }); + } - Box::new(tls_listener) + incoming = rest; + } } } else { // Using HTTP - Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e))) + hyper::server::Server::bind(&addr).serve(service).await.unwrap() } } @@ -105,7 +96,6 @@ impl Server { use rust_server_test::{ Api, - ApiError, AllOfGetResponse, DummyGetResponse, DummyPutResponse, @@ -117,96 +107,100 @@ use rust_server_test::{ SoloObjectPostResponse, }; use rust_server_test::server::MakeService; +use std::error::Error; +use swagger::ApiError; -impl Api for Server where C: Has{ - fn all_of_get( +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn all_of_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("all_of_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// A dummy endpoint to make the spec valid. - fn dummy_get( + async fn dummy_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("dummy_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn dummy_put( + async fn dummy_put( &self, nested_response: models::InlineObject, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("dummy_put({:?}) - X-Span-ID: {:?}", nested_response, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Get a file - fn file_response_get( + async fn file_response_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("file_response_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn get_structured_yaml( + async fn get_structured_yaml( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("get_structured_yaml() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Test HTML handling - fn html_post( + async fn html_post( &self, body: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("html_post(\"{}\") - X-Span-ID: {:?}", body, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } - fn post_yaml( + async fn post_yaml( &self, value: String, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("post_yaml(\"{}\") - X-Span-ID: {:?}", value, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Get an arbitrary JSON blob. - fn raw_json_get( + async fn raw_json_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("raw_json_get() - X-Span-ID: {:?}", context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } /// Send an arbitrary JSON blob - fn solo_object_post( + async fn solo_object_post( &self, value: serde_json::Value, - context: &C) -> Box + Send> + context: &C) -> Result { let context = context.clone(); info!("solo_object_post({:?}) - X-Span-ID: {:?}", value, context.get().0.clone()); - Box::new(future::err("Generic failure".into())) + Err("Generic failuare".into()) } } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs index 7ce4e8ad0ac..aaece7a9b13 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs @@ -1,37 +1,38 @@ -use futures; -use futures::{Future, Stream, future, stream}; -use hyper; -use hyper::client::HttpConnector; +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Uri, Response}; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -use hyper_openssl::HttpsConnector; -use serde_json; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; use std::convert::TryInto; -use std::io::{Read, Error, ErrorKind}; -use std::error; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; use std::fmt; use std::path::Path; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::str; use std::str::FromStr; use std::string::ToString; -use swagger; -use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData}; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use url::form_urlencoded; -use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; + use crate::models; use crate::header; -url::define_encode_set! { - /// This encode set is used for object IDs - /// - /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, - /// the vertical bar (|) is encoded. - pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'} -} +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); use crate::{Api, AllOfGetResponse, @@ -46,11 +47,11 @@ use crate::{Api, }; /// 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 { +fn into_base_path(input: impl TryInto, 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 uri = input.try_into()?; - let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?; + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; // Check the scheme if necessary if let Some(correct_scheme) = correct_scheme { @@ -60,38 +61,54 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result +pub struct Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { /// Inner service - client_service: Arc + Send + Sync>>, + client_service: S, /// Base path of the API base_path: String, } -impl fmt::Debug for Client +impl fmt::Debug for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Client {{ base_path: {} }}", self.base_path) } } -impl Clone for Client +impl Clone for Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { fn clone(&self) -> Self { - Client { + Self { client_service: self.client_service.clone(), base_path: self.base_path.clone(), } } } -impl Client +impl Client> where + C: hyper::client::connect::Connect + Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. /// @@ -104,30 +121,93 @@ impl Client /// /// # Arguments /// - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client - pub fn try_new_with_connector( + pub fn try_new_with_connector( base_path: &str, protocol: Option<&'static str>, connector: C, - ) -> Result where - C: hyper::client::connect::Connect + 'static, - C::Transport: 'static, - C::Future: 'static, + ) -> Result { - let client_service = Box::new(hyper::client::Client::builder().build(connector)); + let client_service = hyper::client::Client::builder().build(connector); - Ok(Client { - client_service: Arc::new(client_service), + Ok(Self { + client_service, base_path: into_base_path(base_path, protocol)?, }) } +} +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(|e| ClientInitError::SslError(e))?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + }) + } +} + +impl Client> +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" pub fn try_new_http( base_path: &str, ) -> Result { @@ -135,11 +215,20 @@ impl Client Self::try_new_with_connector(base_path, Some("http"), http_connector) } +} +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client> +{ /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -152,7 +241,7 @@ impl Client /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -173,7 +262,7 @@ impl Client /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "https://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 @@ -199,17 +288,24 @@ impl Client } } -impl Client +impl Client where + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` /// /// This allows adding custom wrappers around the underlying transport, for example for logging. pub fn try_new_with_client_service( - client_service: Arc + Send + Sync>>, + client_service: S, base_path: &str, - ) -> Result { - Ok(Client { - client_service: client_service, + ) -> Result + { + Ok(Self { + client_service, base_path: into_base_path(base_path, None)?, }) } @@ -249,199 +345,205 @@ impl fmt::Display for ClientInitError { } } -impl error::Error for ClientInitError { +impl Error for ClientInitError { fn description(&self) -> &str { "Failed to produce a hyper client." } } -impl Api for Client where - C: Has , - F: Future, Error=hyper::Error> + Send + 'static +#[async_trait] +impl Api for Client where + C: Has + Clone + Send + Sync + 'static, + S: Service< + Request, + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, { - fn all_of_get( + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn all_of_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/allOf", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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| { - AllOfGetResponse::OK - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(AllOfGetResponse::OK + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn dummy_get( + async fn dummy_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/dummy", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - DummyGetResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + DummyGetResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn dummy_put( + async fn dummy_put( &self, param_nested_response: models::InlineObject, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/dummy", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("PUT") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_nested_response).expect("impossible to fail to serialize"); @@ -450,243 +552,226 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - future::ok( - DummyPutResponse::Success - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Ok( + DummyPutResponse::Success + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn file_response_get( + async fn file_response_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/file_response", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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| { - FileResponseGetResponse::Success - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(FileResponseGetResponse::Success + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn get_structured_yaml( + async fn get_structured_yaml( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/get-structured-yaml", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - Ok(body.to_string()) - ) - ) - .map(move |body| { - GetStructuredYamlResponse::OK - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = body.to_string(); + Ok(GetStructuredYamlResponse::OK + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn html_post( + async fn html_post( &self, param_body: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/html", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_body; @@ -695,89 +780,82 @@ impl Api for Client where let header = "text/html"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_body(); - Box::new( - body - .concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| - str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) - .and_then(|body| - Ok(body.to_string()) - ) - ) - .map(move |body| { - HtmlPostResponse::Success - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = body.to_string(); + Ok(HtmlPostResponse::Success + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn post_yaml( + async fn post_yaml( &self, param_value: String, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/post-yaml", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = param_value; @@ -786,161 +864,151 @@ impl Api for Client where let header = "application/yaml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_body(); - Box::new( - future::ok( - PostYamlResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + Ok( + PostYamlResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn raw_json_get( + async fn raw_json_get( &self, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/raw_json", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("GET") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 200 => { - let body = response.into_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| { - RawJsonGetResponse::Success - (body) - }) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .to_raw() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::(body)?; + Ok(RawJsonGetResponse::Success + (body) + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } - fn solo_object_post( + async fn solo_object_post( &self, param_value: serde_json::Value, - context: &C) -> Box + Send> + context: &C) -> Result { + let mut client_service = self.client_service.clone(); let mut uri = format!( "{}/solo-object", self.base_path ); // Query parameters - let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); - let query_string_str = query_string.finish(); - if !query_string_str.is_empty() { + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { uri += "?"; - uri += &query_string_str; + uri += &query_string; } let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), }; - let mut request = match hyper::Request::builder() + let mut request = match Request::builder() .method("POST") .uri(uri) .body(Body::empty()) { Ok(req) => req, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) }; let body = serde_json::to_string(¶m_value).expect("impossible to fail to serialize"); @@ -950,48 +1018,43 @@ impl Api for Client where let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e)))) + Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) }); - let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + let header = HeaderValue::from_str(Has::::get(context).0.clone().to_string().as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) }); - Box::new(self.client_service.request(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| { - match response.status().as_u16() { - 204 => { - let body = response.into_body(); - Box::new( - future::ok( - SoloObjectPostResponse::OK - ) - ) as Box + Send> - }, - code => { - let headers = response.headers().clone(); - Box::new(response.into_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 + Send> - } + let mut response = client_service.call(request) + .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + Ok( + SoloObjectPostResponse::OK + ) } - })) + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .to_raw().await; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } } } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs index d14e73f822d..fadd880b965 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs @@ -1,13 +1,12 @@ -use futures::Future; -use hyper; +use futures::future::BoxFuture; use hyper::header::HeaderName; -use hyper::{Error, Request, Response, StatusCode, service::Service, body::Payload}; +use hyper::{Error, Request, Response, StatusCode, service::Service}; use url::form_urlencoded; use std::default::Default; use std::io; use std::marker::PhantomData; +use std::task::{Poll, Context}; use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; -use swagger::context::ContextualPayload; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; use crate::Api; @@ -31,58 +30,52 @@ where } // Make a service that adds context. -impl<'a, T, SC, A, B, C, D, E, ME, S, OB, F> hyper::service::MakeService<&'a SC> for +impl Service for MakeAddContext where - A: Default + Push, + Target: Send, + A: Default + Push + Send, B: Push, Result = C>, C: Push, Result = D>, D: Send + 'static, - T: hyper::service::MakeService< - &'a SC, - Error = E, - MakeError = ME, - Service = S, - ReqBody = ContextualPayload, - ResBody = OB, - Future = F - >, - S: Service< - Error = E, - ReqBody = ContextualPayload, - ResBody = OB> + 'static, - ME: swagger::ErrorBound, - E: swagger::ErrorBound, - F: Future + Send + 'static, - S::Future: Send, - OB: Payload, + T: Service + Send, + T::Future: Send + 'static { - type ReqBody = hyper::Body; - type ResBody = OB; - type Error = E; - type MakeError = ME; - type Service = AddContext; - type Future = Box + Send + 'static>; + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; - fn make_service(&mut self, ctx: &'a SC) -> Self::Future { - Box::new(self.inner.make_service(ctx).map(|s| AddContext::new(s))) + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) } } -/// Middleware to extract authentication data from request -pub struct AddContext { +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, C: Push, Result = D>, - T: Service, { - pub fn new(inner: T) -> AddContext { + pub fn new(inner: T) -> Self { AddContext { inner, marker: PhantomData, @@ -90,33 +83,31 @@ where } } -impl Service for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, C: Push, Result=D>, D: Send + 'static, - T: Service>, - T::Future: Future, Error=T::Error> + Send + 'static + T: Service<(Request, D)> { - type ReqBody = hyper::Body; - type ResBody = T::ResBody; type Error = T::Error; - type Future = Box, Error=T::Error> + Send + 'static>; + type Future = T::Future; + type Response = T::Response; - fn call(&mut self, req: Request) -> Self::Future { - let context = A::default().push(XSpanIdString::get_or_generate(&req)); - let (head, body) = req.into_parts(); - let headers = head.headers.clone(); + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); let context = context.push(None::); let context = context.push(None::); - let body = ContextualPayload { - inner: body, - context: context, - }; - Box::new(self.inner.call(hyper::Request::from_parts(head, body))) + self.inner.call((request, context)) } } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs index b8553112ae5..d7928600363 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs @@ -1,12 +1,12 @@ #![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] +use async_trait::async_trait; use futures::Stream; -use std::io::Error; +use std::error::Error; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import swagger-rs directly")] -pub use swagger::{ApiError, ContextWrapper}; -#[deprecated(note = "Import futures directly")] -pub use futures::Future; +type ServiceError = Box; pub const BASE_PATH: &'static str = ""; pub const API_VERSION: &'static str = "2.3.4"; @@ -71,190 +71,221 @@ pub enum SoloObjectPostResponse { } /// API -pub trait Api { - fn all_of_get( +#[async_trait] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn all_of_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; /// A dummy endpoint to make the spec valid. - fn dummy_get( + async fn dummy_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn dummy_put( + async fn dummy_put( &self, nested_response: models::InlineObject, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Get a file - fn file_response_get( + async fn file_response_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn get_structured_yaml( + async fn get_structured_yaml( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Test HTML handling - fn html_post( + async fn html_post( &self, body: String, - context: &C) -> Box + Send>; + context: &C) -> Result; - fn post_yaml( + async fn post_yaml( &self, value: String, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Get an arbitrary JSON blob. - fn raw_json_get( + async fn raw_json_get( &self, - context: &C) -> Box + Send>; + context: &C) -> Result; /// Send an arbitrary JSON blob - fn solo_object_post( + async fn solo_object_post( &self, value: serde_json::Value, - context: &C) -> Box + Send>; + context: &C) -> Result; } -/// API without a `Context` -pub trait ApiNoContext { - fn all_of_get( +/// API where `Context` isn't passed on every API call +#[async_trait] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn all_of_get( &self, - ) -> Box + Send>; + ) -> Result; /// A dummy endpoint to make the spec valid. - fn dummy_get( + async fn dummy_get( &self, - ) -> Box + Send>; + ) -> Result; - fn dummy_put( + async fn dummy_put( &self, nested_response: models::InlineObject, - ) -> Box + Send>; + ) -> Result; /// Get a file - fn file_response_get( + async fn file_response_get( &self, - ) -> Box + Send>; + ) -> Result; - fn get_structured_yaml( + async fn get_structured_yaml( &self, - ) -> Box + Send>; + ) -> Result; /// Test HTML handling - fn html_post( + async fn html_post( &self, body: String, - ) -> Box + Send>; + ) -> Result; - fn post_yaml( + async fn post_yaml( &self, value: String, - ) -> Box + Send>; + ) -> Result; /// Get an arbitrary JSON blob. - fn raw_json_get( + async fn raw_json_get( &self, - ) -> Box + Send>; + ) -> Result; /// Send an arbitrary JSON blob - fn solo_object_post( + async fn solo_object_post( &self, value: serde_json::Value, - ) -> Box + Send>; + ) -> Result; } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a, C> where Self: Sized { +pub trait ContextWrapperExt where Self: Sized +{ /// Binds this API to a context. - fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>; + fn with_context(self: Self, context: C) -> ContextWrapper; } -impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { - fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> { +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { ContextWrapper::::new(self, context) } } -impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { - fn all_of_get( +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn all_of_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().all_of_get(&self.context()) + let context = self.context().clone(); + self.api().all_of_get(&context).await } /// A dummy endpoint to make the spec valid. - fn dummy_get( + async fn dummy_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().dummy_get(&self.context()) + let context = self.context().clone(); + self.api().dummy_get(&context).await } - fn dummy_put( + async fn dummy_put( &self, nested_response: models::InlineObject, - ) -> Box + Send> + ) -> Result { - self.api().dummy_put(nested_response, &self.context()) + let context = self.context().clone(); + self.api().dummy_put(nested_response, &context).await } /// Get a file - fn file_response_get( + async fn file_response_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().file_response_get(&self.context()) + let context = self.context().clone(); + self.api().file_response_get(&context).await } - fn get_structured_yaml( + async fn get_structured_yaml( &self, - ) -> Box + Send> + ) -> Result { - self.api().get_structured_yaml(&self.context()) + let context = self.context().clone(); + self.api().get_structured_yaml(&context).await } /// Test HTML handling - fn html_post( + async fn html_post( &self, body: String, - ) -> Box + Send> + ) -> Result { - self.api().html_post(body, &self.context()) + let context = self.context().clone(); + self.api().html_post(body, &context).await } - fn post_yaml( + async fn post_yaml( &self, value: String, - ) -> Box + Send> + ) -> Result { - self.api().post_yaml(value, &self.context()) + let context = self.context().clone(); + self.api().post_yaml(value, &context).await } /// Get an arbitrary JSON blob. - fn raw_json_get( + async fn raw_json_get( &self, - ) -> Box + Send> + ) -> Result { - self.api().raw_json_get(&self.context()) + let context = self.context().clone(); + self.api().raw_json_get(&context).await } /// Send an arbitrary JSON blob - fn solo_object_post( + async fn solo_object_post( &self, value: serde_json::Value, - ) -> Box + Send> + ) -> Result { - self.api().solo_object_post(value, &self.context()) + let context = self.context().clone(); + self.api().solo_object_post(value, &context).await } } + #[cfg(feature = "client")] pub mod client; diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs index 69fd7709b91..7f9e845c9a3 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs @@ -1,20 +1,17 @@ -use std::marker::PhantomData; -use futures::{Future, future, Stream, stream}; -use hyper; -use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap}; +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; -use serde_json; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::io; -use url::form_urlencoded; -#[allow(unused_imports)] -use swagger; -use swagger::{ApiError, XSpanIdString, Has, RequestParser}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; -use swagger::context::ContextualPayload; +use url::form_urlencoded; #[allow(unused_imports)] use crate::models; @@ -22,6 +19,8 @@ use crate::header; pub use crate::context; +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + use crate::{Api, AllOfGetResponse, DummyGetResponse, @@ -60,15 +59,17 @@ mod paths { pub(crate) static ID_SOLO_OBJECT: usize = 7; } -pub struct MakeService { +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { pub fn new(api_impl: T) -> Self { MakeService { @@ -78,44 +79,45 @@ where } } -impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService -where - T: Api + Clone + Send + 'static, - RC: Has + 'static + Send +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; - type Service = Service; - type Future = future::FutureResult; - type MakeError = Error; + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; - fn make_service(&mut self, _ctx: &'a SC) -> Self::Future { - future::FutureResult::from(Ok(Service::new( + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + futures::future::ok(Service::new( self.api_impl.clone(), - ))) + )) } } -type ServiceFuture = Box, Error = Error> + Send>; - -fn method_not_allowed() -> ServiceFuture { - Box::new(future::ok( +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) .body(Body::empty()) .expect("Unable to create Method Not Allowed response") - )) + ) } -pub struct Service { +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ api_impl: T, - marker: PhantomData, + marker: PhantomData, } -impl Service -where - T: Api + Clone + Send + 'static, - RC: Has + 'static { +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ pub fn new(api_impl: T) -> Self { Service { api_impl: api_impl, @@ -124,36 +126,48 @@ where } } -impl hyper::service::Service for Service -where +impl Clone for Service where T: Api + Clone + Send + 'static, - C: Has + 'static + Send + C: Has + Send + Sync + 'static { - type ReqBody = ContextualPayload; - type ResBody = Body; - type Error = Error; + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker.clone(), + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; type Future = ServiceFuture; - fn call(&mut self, req: Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (parts, body) = req.into_parts(); + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { async fn run(mut api_impl: T, req: (Request, C)) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); let (method, uri, headers) = (parts.method, parts.uri, parts.headers); let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - let mut context = body.context; - let body = body.inner; match &method { // AllOfGet - GET /allOf &hyper::Method::GET if path.matched(paths::ID_ALLOF) => { - Box::new({ - {{ - Box::new( - api_impl.all_of_get( + let result = api_impl.all_of_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -180,23 +194,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // DummyGet - GET /dummy &hyper::Method::GET if path.matched(paths::ID_DUMMY) => { - Box::new({ - {{ - Box::new( - api_impl.dummy_get( + let result = api_impl.dummy_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -216,11 +223,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // DummyPut - PUT /dummy @@ -228,9 +231,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_nested_response: Option = if !body.is_empty() { @@ -240,29 +242,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_nested_response) => param_nested_response, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter nested_response - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter nested_response due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter nested_response due to schema")), } } else { None }; let param_nested_response = match param_nested_response { Some(param_nested_response) => param_nested_response, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter nested_response")) - .expect("Unable to create Bad Request response for missing body parameter nested_response"))), + .expect("Unable to create Bad Request response for missing body parameter nested_response")), }; - Box::new( - api_impl.dummy_put( + let result = api_impl.dummy_put( param_nested_response, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -289,29 +290,22 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter nested_response: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter nested_response"))), + .expect("Unable to create Bad Request response due to unable to read body parameter nested_response")), } - }) - ) as Self::Future }, // FileResponseGet - GET /file_response &hyper::Method::GET if path.matched(paths::ID_FILE_RESPONSE) => { - Box::new({ - {{ - Box::new( - api_impl.file_response_get( + let result = api_impl.file_response_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -338,23 +332,16 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // GetStructuredYaml - GET /get-structured-yaml &hyper::Method::GET if path.matched(paths::ID_GET_STRUCTURED_YAML) => { - Box::new({ - {{ - Box::new( - api_impl.get_structured_yaml( + let result = api_impl.get_structured_yaml( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -381,11 +368,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // HtmlPost - POST /html @@ -393,36 +376,34 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let param_body: Option = if !body.is_empty() { match String::from_utf8(body.to_vec()) { Ok(param_body) => Some(param_body), - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter body due to UTF-8"))), + .expect("Unable to create Bad Request response for invalid body parameter body due to UTF-8")), } } else { None }; let param_body = match param_body { Some(param_body) => param_body, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter body")) - .expect("Unable to create Bad Request response for missing body parameter body"))), + .expect("Unable to create Bad Request response for missing body parameter body")), }; - Box::new( - api_impl.html_post( + let result = api_impl.html_post( param_body, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -449,17 +430,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter body: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter body"))), + .expect("Unable to create Bad Request response due to unable to read body parameter body")), } - }) - ) as Self::Future }, // PostYaml - POST /post-yaml @@ -467,36 +444,34 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let param_value: Option = if !body.is_empty() { match String::from_utf8(body.to_vec()) { Ok(param_value) => Some(param_value), - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter value - not valid UTF-8: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter value due to UTF-8"))), + .expect("Unable to create Bad Request response for invalid body parameter value due to UTF-8")), } } else { None }; let param_value = match param_value { Some(param_value) => param_value, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter value")) - .expect("Unable to create Bad Request response for missing body parameter value"))), + .expect("Unable to create Bad Request response for missing body parameter value")), }; - Box::new( - api_impl.post_yaml( + let result = api_impl.post_yaml( param_value, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -516,29 +491,22 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter value: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter value"))), + .expect("Unable to create Bad Request response due to unable to read body parameter value")), } - }) - ) as Self::Future }, // RawJsonGet - GET /raw_json &hyper::Method::GET if path.matched(paths::ID_RAW_JSON) => { - Box::new({ - {{ - Box::new( - api_impl.raw_json_get( + let result = api_impl.raw_json_get( &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -565,11 +533,7 @@ where }, } - future::ok(response) - } - )) - }} - }) as Self::Future + Ok(response) }, // SoloObjectPost - POST /solo-object @@ -577,9 +541,8 @@ where // 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| -> Self::Future { - match result { + let result = body.to_raw().await; + match result { Ok(body) => { let mut unused_elements = Vec::new(); let param_value: Option = if !body.is_empty() { @@ -589,29 +552,28 @@ where unused_elements.push(path.to_string()); }) { Ok(param_value) => param_value, - Err(e) => return Box::new(future::ok(Response::builder() + Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't parse body parameter value - doesn't match schema: {}", e))) - .expect("Unable to create Bad Request response for invalid body parameter value due to schema"))), + .expect("Unable to create Bad Request response for invalid body parameter value due to schema")), } } else { None }; let param_value = match param_value { Some(param_value) => param_value, - None => return Box::new(future::ok(Response::builder() + None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from("Missing required body parameter value")) - .expect("Unable to create Bad Request response for missing body parameter value"))), + .expect("Unable to create Bad Request response for missing body parameter value")), }; - Box::new( - api_impl.solo_object_post( + let result = api_impl.solo_object_post( param_value, &context - ).then(move |result| { - let mut response = Response::new(Body::empty()); - response.headers_mut().insert( + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().to_string().as_str()) .expect("Unable to create X-Span-ID header value")); @@ -638,17 +600,13 @@ where }, } - future::ok(response) - } - )) + Ok(response) }, - Err(e) => Box::new(future::ok(Response::builder() + Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) .body(Body::from(format!("Couldn't read body parameter value: {}", e))) - .expect("Unable to create Bad Request response due to unable to read body parameter value"))), + .expect("Unable to create Bad Request response due to unable to read body parameter value")), } - }) - ) as Self::Future }, _ if path.matched(paths::ID_ALLOF) => method_not_allowed(), @@ -659,23 +617,11 @@ where _ if path.matched(paths::ID_POST_YAML) => method_not_allowed(), _ if path.matched(paths::ID_RAW_JSON) => method_not_allowed(), _ if path.matched(paths::ID_SOLO_OBJECT) => method_not_allowed(), - _ => Box::new(future::ok( - Response::builder().status(StatusCode::NOT_FOUND) + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) .body(Body::empty()) - .expect("Unable to create Not Found response") - )) as Self::Future + .expect("Unable to create Not Found response")) } - } -} - -impl Clone for Service where T: Clone -{ - fn clone(&self) -> Self { - Service { - api_impl: self.api_impl.clone(), - marker: self.marker.clone(), - } - } + } Box::pin(run(self.api_impl.clone(), req)) } } /// Request parser for `Api`.