[Rust Server] Pass context to client middleware (#6574)

* [Rust Server] Pass context to client middleware

When creating a client with middleware, pass the context.

This allows users to pass contextual data about the requests through to the
client middleware.

* Update samples
This commit is contained in:
Richard Whitehouse 2020-06-15 23:03:25 +01:00 committed by GitHub
parent aa201b3d9f
commit c65363eb71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 448 additions and 270 deletions

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
{{#apiUsesMultipartFormData}} {{#apiUsesMultipartFormData}}

View File

@ -27,49 +27,57 @@ fn into_base_path(input: impl TryInto<Uri, Error=hyper::http::uri::InvalidUri>,
} }
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Base path of the API /// Base path of the API
base_path: String, base_path: String,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client {{ base_path: {} }}", self.base_path) write!(f, "Client {{ base_path: {} }}", self.base_path)
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
base_path: self.base_path.clone(), base_path: self.base_path.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static,
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -88,14 +96,16 @@ impl<C> Client<hyper::client::Client<C, Body>> where
pub fn try_new_with_connector( pub fn try_new_with_connector(
base_path: &str, base_path: &str,
protocol: Option<&'static str>, protocol: Option<&'static str>,
connector: C, connector: Connector,
) -> Result<Self, ClientInitError> ) -> Result<Self, ClientInitError>
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, protocol)?, base_path: into_base_path(base_path, protocol)?,
marker: PhantomData,
}) })
} }
} }
@ -126,7 +136,9 @@ impl Service<Request<Body>> for HyperClient {
} }
} }
impl Client<HyperClient> { impl<C> Client<DropContextService<HyperClient, C>, C> where
C: Clone + Send + Sync + 'static,
{
/// Create an HTTP client. /// Create an HTTP client.
/// ///
/// # Arguments /// # Arguments
@ -156,14 +168,18 @@ impl Client<HyperClient> {
} }
}; };
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
/// ///
@ -184,7 +200,8 @@ type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server /// Create a client with a TLS connection to the server
/// ///
@ -249,12 +266,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` /
/// `tower::Service` /// `tower::Service`
@ -268,6 +286,7 @@ impl<S> Client<S> where
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
@ -313,13 +332,13 @@ impl Error for ClientInitError {
} }
#[async_trait] #[async_trait]
impl<C, S> Api<C> for Client<S> where impl<S, C> Api<C> for Client<S, C> where
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}} + Clone + Send + Sync + 'static,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}} + Clone + Send + Sync + 'static,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {

View File

@ -134,6 +134,7 @@
}; };
*request.body_mut() = Body::from(body_string); *request.body_mut() = Body::from(body_string);
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) {
Ok(h) => h, Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e)))
@ -365,7 +366,7 @@
{{/isMapContainer}} {{/isMapContainer}}
{{/headerParams}} {{/headerParams}}
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {

View File

@ -17,45 +17,53 @@ use crate::{{{operationId}}}Response;
{{/apiInfo}} {{/apiInfo}}
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client") write!(f, "Client")
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -69,17 +77,20 @@ impl<C> Client<hyper::client::Client<C, Body>> where
/// # Arguments /// # Arguments
/// ///
/// * `connector` - Implementation of `hyper::client::Connect` to use for the client /// * `connector` - Implementation of `hyper::client::Connect` to use for the client
pub fn new_with_connector(connector: C) -> Self pub fn new_with_connector(connector: Connector) -> Self
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Self { Self {
client_service, client_service,
marker: PhantomData,
} }
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
pub fn new_http() -> Self { pub fn new_http() -> Self {
@ -94,7 +105,8 @@ type HttpConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server. /// Create a client with a TLS connection to the server.
#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))]
@ -155,12 +167,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
/// ///
@ -170,19 +183,20 @@ impl<S> Client<S> where
) -> Self { ) -> Self {
Client { Client {
client_service, client_service,
marker: PhantomData,
} }
} }
} }
#[async_trait] #[async_trait]
impl<C, S> CallbackApi<C> for Client<S> where impl<S, C> CallbackApi<C> for Client<S, C> where
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}} + Send + Sync,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}} + Clone + Send + Sync,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {

View File

@ -1,5 +1,6 @@
.cargo/config .cargo/config
.gitignore .gitignore
.openapi-generator-ignore
Cargo.toml Cargo.toml
README.md README.md
api/openapi.yaml api/openapi.yaml

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
use mime::Mime; use mime::Mime;
@ -65,49 +66,57 @@ fn into_base_path(input: impl TryInto<Uri, Error=hyper::http::uri::InvalidUri>,
} }
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Base path of the API /// Base path of the API
base_path: String, base_path: String,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client {{ base_path: {} }}", self.base_path) write!(f, "Client {{ base_path: {} }}", self.base_path)
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
base_path: self.base_path.clone(), base_path: self.base_path.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static,
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -126,14 +135,16 @@ impl<C> Client<hyper::client::Client<C, Body>> where
pub fn try_new_with_connector( pub fn try_new_with_connector(
base_path: &str, base_path: &str,
protocol: Option<&'static str>, protocol: Option<&'static str>,
connector: C, connector: Connector,
) -> Result<Self, ClientInitError> ) -> Result<Self, ClientInitError>
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, protocol)?, base_path: into_base_path(base_path, protocol)?,
marker: PhantomData,
}) })
} }
} }
@ -164,7 +175,9 @@ impl Service<Request<Body>> for HyperClient {
} }
} }
impl Client<HyperClient> { impl<C> Client<DropContextService<HyperClient, C>, C> where
C: Clone + Send + Sync + 'static,
{
/// Create an HTTP client. /// Create an HTTP client.
/// ///
/// # Arguments /// # Arguments
@ -194,14 +207,18 @@ impl Client<HyperClient> {
} }
}; };
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
/// ///
@ -222,7 +239,8 @@ type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server /// Create a client with a TLS connection to the server
/// ///
@ -287,12 +305,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` /
/// `tower::Service` /// `tower::Service`
@ -306,6 +325,7 @@ impl<S> Client<S> where
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
@ -351,13 +371,13 @@ impl Error for ClientInitError {
} }
#[async_trait] #[async_trait]
impl<C, S> Api<C> for Client<S> where impl<S, C> Api<C> for Client<S, C> where
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {
@ -480,7 +500,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -621,6 +641,7 @@ impl<C, S> Api<C> for Client<S> where
}; };
*request.body_mut() = Body::from(body_string); *request.body_mut() = Body::from(body_string);
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) {
Ok(h) => h, Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e)))
@ -632,7 +653,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -759,7 +780,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {

View File

@ -1,5 +1,6 @@
.cargo/config .cargo/config
.gitignore .gitignore
.openapi-generator-ignore
Cargo.toml Cargo.toml
README.md README.md
api/openapi.yaml api/openapi.yaml

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
@ -58,49 +59,57 @@ fn into_base_path(input: impl TryInto<Uri, Error=hyper::http::uri::InvalidUri>,
} }
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Base path of the API /// Base path of the API
base_path: String, base_path: String,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client {{ base_path: {} }}", self.base_path) write!(f, "Client {{ base_path: {} }}", self.base_path)
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
base_path: self.base_path.clone(), base_path: self.base_path.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static,
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -119,14 +128,16 @@ impl<C> Client<hyper::client::Client<C, Body>> where
pub fn try_new_with_connector( pub fn try_new_with_connector(
base_path: &str, base_path: &str,
protocol: Option<&'static str>, protocol: Option<&'static str>,
connector: C, connector: Connector,
) -> Result<Self, ClientInitError> ) -> Result<Self, ClientInitError>
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, protocol)?, base_path: into_base_path(base_path, protocol)?,
marker: PhantomData,
}) })
} }
} }
@ -157,7 +168,9 @@ impl Service<Request<Body>> for HyperClient {
} }
} }
impl Client<HyperClient> { impl<C> Client<DropContextService<HyperClient, C>, C> where
C: Clone + Send + Sync + 'static,
{
/// Create an HTTP client. /// Create an HTTP client.
/// ///
/// # Arguments /// # Arguments
@ -187,14 +200,18 @@ impl Client<HyperClient> {
} }
}; };
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
/// ///
@ -215,7 +232,8 @@ type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server /// Create a client with a TLS connection to the server
/// ///
@ -280,12 +298,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` /
/// `tower::Service` /// `tower::Service`
@ -299,6 +318,7 @@ impl<S> Client<S> where
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
@ -344,13 +364,13 @@ impl Error for ClientInitError {
} }
#[async_trait] #[async_trait]
impl<C, S> Api<C> for Client<S> where impl<S, C> Api<C> for Client<S, C> where
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {
@ -411,7 +431,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {

View File

@ -1,5 +1,6 @@
.cargo/config .cargo/config
.gitignore .gitignore
.openapi-generator-ignore
Cargo.toml Cargo.toml
README.md README.md
api/openapi.yaml api/openapi.yaml

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
@ -82,49 +83,57 @@ fn into_base_path(input: impl TryInto<Uri, Error=hyper::http::uri::InvalidUri>,
} }
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Base path of the API /// Base path of the API
base_path: String, base_path: String,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client {{ base_path: {} }}", self.base_path) write!(f, "Client {{ base_path: {} }}", self.base_path)
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
base_path: self.base_path.clone(), base_path: self.base_path.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static,
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -143,14 +152,16 @@ impl<C> Client<hyper::client::Client<C, Body>> where
pub fn try_new_with_connector( pub fn try_new_with_connector(
base_path: &str, base_path: &str,
protocol: Option<&'static str>, protocol: Option<&'static str>,
connector: C, connector: Connector,
) -> Result<Self, ClientInitError> ) -> Result<Self, ClientInitError>
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, protocol)?, base_path: into_base_path(base_path, protocol)?,
marker: PhantomData,
}) })
} }
} }
@ -181,7 +192,9 @@ impl Service<Request<Body>> for HyperClient {
} }
} }
impl Client<HyperClient> { impl<C> Client<DropContextService<HyperClient, C>, C> where
C: Clone + Send + Sync + 'static,
{
/// Create an HTTP client. /// Create an HTTP client.
/// ///
/// # Arguments /// # Arguments
@ -211,14 +224,18 @@ impl Client<HyperClient> {
} }
}; };
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
/// ///
@ -239,7 +256,8 @@ type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server /// Create a client with a TLS connection to the server
/// ///
@ -304,12 +322,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` /
/// `tower::Service` /// `tower::Service`
@ -323,6 +342,7 @@ impl<S> Client<S> where
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
@ -368,13 +388,13 @@ impl Error for ClientInitError {
} }
#[async_trait] #[async_trait]
impl<C, S> Api<C> for Client<S> where impl<S, C> Api<C> for Client<S, C> where
C: Has<XSpanIdString> + Has<Option<AuthData>> + Clone + Send + Sync + 'static,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> + Has<Option<AuthData>> + Clone + Send + Sync + 'static,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {
@ -425,7 +445,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -498,7 +518,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -569,7 +589,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -650,7 +670,7 @@ impl<C, S> Api<C> for Client<S> where
}, },
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -719,7 +739,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -794,7 +814,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -959,7 +979,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1028,7 +1048,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1109,7 +1129,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1201,7 +1221,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1272,7 +1292,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1350,7 +1370,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1419,7 +1439,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1579,7 +1599,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1694,7 +1714,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1763,7 +1783,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1851,7 +1871,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1939,7 +1959,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2036,7 +2056,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2124,7 +2144,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2214,7 +2234,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2299,7 +2319,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2370,7 +2390,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
@ -39,45 +40,53 @@ use crate::CallbackCallbackWithHeaderPostResponse;
use crate::CallbackCallbackPostResponse; use crate::CallbackCallbackPostResponse;
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client") write!(f, "Client")
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -91,17 +100,20 @@ impl<C> Client<hyper::client::Client<C, Body>> where
/// # Arguments /// # Arguments
/// ///
/// * `connector` - Implementation of `hyper::client::Connect` to use for the client /// * `connector` - Implementation of `hyper::client::Connect` to use for the client
pub fn new_with_connector(connector: C) -> Self pub fn new_with_connector(connector: Connector) -> Self
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Self { Self {
client_service, client_service,
marker: PhantomData,
} }
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
pub fn new_http() -> Self { pub fn new_http() -> Self {
@ -116,7 +128,8 @@ type HttpConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server. /// Create a client with a TLS connection to the server.
#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))]
@ -177,12 +190,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
/// ///
@ -192,19 +206,20 @@ impl<S> Client<S> where
) -> Self { ) -> Self {
Client { Client {
client_service, client_service,
marker: PhantomData,
} }
} }
} }
#[async_trait] #[async_trait]
impl<C, S> CallbackApi<C> for Client<S> where impl<S, C> CallbackApi<C> for Client<S, C> where
C: Has<XSpanIdString> + Has<Option<AuthData>> + Send + Sync,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>, Response=Response<Body>,
Error=hyper::Error> + Clone + Send + Sync, Error=hyper::Error> + Clone + Send + Sync,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> + Has<Option<AuthData>> + Clone + Send + Sync,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {
@ -271,7 +286,7 @@ impl<C, S> CallbackApi<C> for Client<S> where
None => {} None => {}
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -341,7 +356,7 @@ impl<C, S> CallbackApi<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {

View File

@ -1,5 +1,6 @@
.cargo/config .cargo/config
.gitignore .gitignore
.openapi-generator-ignore
Cargo.toml Cargo.toml
README.md README.md
api/openapi.yaml api/openapi.yaml

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
@ -94,49 +95,57 @@ fn into_base_path(input: impl TryInto<Uri, Error=hyper::http::uri::InvalidUri>,
} }
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Base path of the API /// Base path of the API
base_path: String, base_path: String,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client {{ base_path: {} }}", self.base_path) write!(f, "Client {{ base_path: {} }}", self.base_path)
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
base_path: self.base_path.clone(), base_path: self.base_path.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static,
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -155,14 +164,16 @@ impl<C> Client<hyper::client::Client<C, Body>> where
pub fn try_new_with_connector( pub fn try_new_with_connector(
base_path: &str, base_path: &str,
protocol: Option<&'static str>, protocol: Option<&'static str>,
connector: C, connector: Connector,
) -> Result<Self, ClientInitError> ) -> Result<Self, ClientInitError>
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, protocol)?, base_path: into_base_path(base_path, protocol)?,
marker: PhantomData,
}) })
} }
} }
@ -193,7 +204,9 @@ impl Service<Request<Body>> for HyperClient {
} }
} }
impl Client<HyperClient> { impl<C> Client<DropContextService<HyperClient, C>, C> where
C: Clone + Send + Sync + 'static,
{
/// Create an HTTP client. /// Create an HTTP client.
/// ///
/// # Arguments /// # Arguments
@ -223,14 +236,18 @@ impl Client<HyperClient> {
} }
}; };
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
/// ///
@ -251,7 +268,8 @@ type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server /// Create a client with a TLS connection to the server
/// ///
@ -316,12 +334,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` /
/// `tower::Service` /// `tower::Service`
@ -335,6 +354,7 @@ impl<S> Client<S> where
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
@ -380,13 +400,13 @@ impl Error for ClientInitError {
} }
#[async_trait] #[async_trait]
impl<C, S> Api<C> for Client<S> where impl<S, C> Api<C> for Client<S, C> where
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {
@ -435,7 +455,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -504,7 +524,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -573,7 +593,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -642,7 +662,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -711,7 +731,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -780,7 +800,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -849,7 +869,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -918,7 +938,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -987,7 +1007,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1056,7 +1076,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1125,7 +1145,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1194,7 +1214,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1263,7 +1283,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1332,7 +1352,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1401,7 +1421,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1470,7 +1490,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1539,7 +1559,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1608,7 +1628,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1677,7 +1697,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1746,7 +1766,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1815,7 +1835,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1884,7 +1904,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1953,7 +1973,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2022,7 +2042,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2091,7 +2111,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2160,7 +2180,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2229,7 +2249,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2298,7 +2318,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2367,7 +2387,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2436,7 +2456,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2505,7 +2525,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2574,7 +2594,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2643,7 +2663,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2712,7 +2732,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2781,7 +2801,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2850,7 +2870,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2919,7 +2939,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {

View File

@ -1,5 +1,6 @@
.cargo/config .cargo/config
.gitignore .gitignore
.openapi-generator-ignore
Cargo.toml Cargo.toml
README.md README.md
api/openapi.yaml api/openapi.yaml

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
use mime::Mime; use mime::Mime;
@ -95,49 +96,57 @@ fn into_base_path(input: impl TryInto<Uri, Error=hyper::http::uri::InvalidUri>,
} }
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Base path of the API /// Base path of the API
base_path: String, base_path: String,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client {{ base_path: {} }}", self.base_path) write!(f, "Client {{ base_path: {} }}", self.base_path)
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
base_path: self.base_path.clone(), base_path: self.base_path.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static,
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -156,14 +165,16 @@ impl<C> Client<hyper::client::Client<C, Body>> where
pub fn try_new_with_connector( pub fn try_new_with_connector(
base_path: &str, base_path: &str,
protocol: Option<&'static str>, protocol: Option<&'static str>,
connector: C, connector: Connector,
) -> Result<Self, ClientInitError> ) -> Result<Self, ClientInitError>
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, protocol)?, base_path: into_base_path(base_path, protocol)?,
marker: PhantomData,
}) })
} }
} }
@ -194,7 +205,9 @@ impl Service<Request<Body>> for HyperClient {
} }
} }
impl Client<HyperClient> { impl<C> Client<DropContextService<HyperClient, C>, C> where
C: Clone + Send + Sync + 'static,
{
/// Create an HTTP client. /// Create an HTTP client.
/// ///
/// # Arguments /// # Arguments
@ -224,14 +237,18 @@ impl Client<HyperClient> {
} }
}; };
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
/// ///
@ -252,7 +269,8 @@ type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server /// Create a client with a TLS connection to the server
/// ///
@ -317,12 +335,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` /
/// `tower::Service` /// `tower::Service`
@ -336,6 +355,7 @@ impl<S> Client<S> where
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
@ -381,13 +401,13 @@ impl Error for ClientInitError {
} }
#[async_trait] #[async_trait]
impl<C, S> Api<C> for Client<S> where impl<S, C> Api<C> for Client<S, C> where
C: Has<XSpanIdString> + Has<Option<AuthData>> + Clone + Send + Sync + 'static,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> + Has<Option<AuthData>> + Clone + Send + Sync + 'static,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {
@ -448,7 +468,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -523,7 +543,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -605,7 +625,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -693,7 +713,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -781,7 +801,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -869,7 +889,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -944,7 +964,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1015,7 +1035,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1095,7 +1115,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1173,7 +1193,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1303,7 +1323,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1439,7 +1459,7 @@ impl<C, S> Api<C> for Client<S> where
None => {} None => {}
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1523,7 +1543,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1606,7 +1626,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1699,7 +1719,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1801,7 +1821,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1906,7 +1926,7 @@ impl<C, S> Api<C> for Client<S> where
None => {} None => {}
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1994,7 +2014,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2097,7 +2117,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2190,7 +2210,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2306,7 +2326,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2420,7 +2440,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2536,6 +2556,7 @@ impl<C, S> Api<C> for Client<S> where
}; };
*request.body_mut() = Body::from(body_string); *request.body_mut() = Body::from(body_string);
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) {
Ok(h) => h, Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e)))
@ -2564,7 +2585,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2641,7 +2662,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2723,7 +2744,7 @@ impl<C, S> Api<C> for Client<S> where
} }
} }
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2800,7 +2821,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2901,7 +2922,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -2995,7 +3016,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -3073,7 +3094,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -3151,7 +3172,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -3222,7 +3243,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -3299,7 +3320,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -3393,7 +3414,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -3509,7 +3530,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -3591,7 +3612,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {

View File

@ -1,5 +1,6 @@
.cargo/config .cargo/config
.gitignore .gitignore
.openapi-generator-ignore
Cargo.toml Cargo.toml
README.md README.md
api/openapi.yaml api/openapi.yaml

View File

@ -9,13 +9,14 @@ use std::io::{ErrorKind, Read};
use std::error::Error; use std::error::Error;
use std::future::Future; use std::future::Future;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::str; use std::str;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use swagger::{ApiError, AuthData, BodyExt, Connector, Has, XSpanIdString}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
use url::form_urlencoded; use url::form_urlencoded;
@ -66,49 +67,57 @@ fn into_base_path(input: impl TryInto<Uri, Error=hyper::http::uri::InvalidUri>,
} }
/// A client that implements the API by making HTTP calls out to a server. /// A client that implements the API by making HTTP calls out to a server.
pub struct Client<S> where pub struct Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Inner service /// Inner service
client_service: S, client_service: S,
/// Base path of the API /// Base path of the API
base_path: String, base_path: String,
/// Marker
marker: PhantomData<fn(C)>,
} }
impl<S> fmt::Debug for Client<S> where impl<S, C> fmt::Debug for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Client {{ base_path: {} }}", self.base_path) write!(f, "Client {{ base_path: {} }}", self.base_path)
} }
} }
impl<S> Clone for Client<S> where impl<S, C> Clone for Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
client_service: self.client_service.clone(), client_service: self.client_service.clone(),
base_path: self.base_path.clone(), base_path: self.base_path.clone(),
marker: PhantomData,
} }
} }
} }
impl<C> Client<hyper::client::Client<C, Body>> where impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C> where
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
C: Clone + Send + Sync + 'static,
{ {
/// Create a client with a custom implementation of hyper::client::Connect. /// Create a client with a custom implementation of hyper::client::Connect.
/// ///
@ -127,14 +136,16 @@ impl<C> Client<hyper::client::Client<C, Body>> where
pub fn try_new_with_connector( pub fn try_new_with_connector(
base_path: &str, base_path: &str,
protocol: Option<&'static str>, protocol: Option<&'static str>,
connector: C, connector: Connector,
) -> Result<Self, ClientInitError> ) -> Result<Self, ClientInitError>
{ {
let client_service = hyper::client::Client::builder().build(connector); let client_service = hyper::client::Client::builder().build(connector);
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, protocol)?, base_path: into_base_path(base_path, protocol)?,
marker: PhantomData,
}) })
} }
} }
@ -165,7 +176,9 @@ impl Service<Request<Body>> for HyperClient {
} }
} }
impl Client<HyperClient> { impl<C> Client<DropContextService<HyperClient, C>, C> where
C: Clone + Send + Sync + 'static,
{
/// Create an HTTP client. /// Create an HTTP client.
/// ///
/// # Arguments /// # Arguments
@ -195,14 +208,18 @@ impl Client<HyperClient> {
} }
}; };
let client_service = DropContextService::new(client_service);
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
impl Client<hyper::client::Client<hyper::client::HttpConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create an HTTP client. /// Create an HTTP client.
/// ///
@ -223,7 +240,8 @@ type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>; type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
impl Client<hyper::client::Client<HttpsConnector, Body>> impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C> where
C: Clone + Send + Sync + 'static
{ {
/// Create a client with a TLS connection to the server /// Create a client with a TLS connection to the server
/// ///
@ -288,12 +306,13 @@ impl Client<hyper::client::Client<HttpsConnector, Body>>
} }
} }
impl<S> Client<S> where impl<S, C> Client<S, C> where
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Clone + Send + Sync + 'static
{ {
/// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` /
/// `tower::Service` /// `tower::Service`
@ -307,6 +326,7 @@ impl<S> Client<S> where
Ok(Self { Ok(Self {
client_service, client_service,
base_path: into_base_path(base_path, None)?, base_path: into_base_path(base_path, None)?,
marker: PhantomData,
}) })
} }
} }
@ -352,13 +372,13 @@ impl Error for ClientInitError {
} }
#[async_trait] #[async_trait]
impl<C, S> Api<C> for Client<S> where impl<S, C> Api<C> for Client<S, C> where
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
S: Service< S: Service<
Request<Body>, (Request<Body>, C),
Response=Response<Body>> + Clone + Sync + Send + 'static, Response=Response<Body>> + Clone + Sync + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
S::Error: Into<crate::ServiceError> + fmt::Display, S::Error: Into<crate::ServiceError> + fmt::Display,
C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
{ {
fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> { fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
match self.client_service.clone().poll_ready(cx) { match self.client_service.clone().poll_ready(cx) {
@ -407,7 +427,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -482,7 +502,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -560,7 +580,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -629,7 +649,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -704,7 +724,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -788,7 +808,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -872,7 +892,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -941,7 +961,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {
@ -1027,7 +1047,7 @@ impl<C, S> Api<C> for Client<S> where
Err(e) => return 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)))
}); });
let mut response = client_service.call(request) let mut response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?; .map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() { match response.status().as_u16() {