fix trait bounds on web test and awc

This commit is contained in:
Rob Ede 2021-05-17 13:57:22 +01:00
parent 0448bbf8ab
commit 1ad7c44c6e
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
5 changed files with 105 additions and 48 deletions

View File

@ -5,3 +5,4 @@ ci-min = "hack check --workspace --no-default-features"
ci-min-test = "hack check --workspace --no-default-features --tests --examples" ci-min-test = "hack check --workspace --no-default-features --tests --examples"
ci-default = "hack check --workspace" ci-default = "hack check --workspace"
ci-full = "check --workspace --bins --examples --tests" ci-full = "check --workspace --bins --examples --tests"
ci-test = "test --workspace --all-features --no-fail-fast"

View File

@ -8,7 +8,7 @@ use std::{
use bytes::{Bytes, BytesMut}; use bytes::{Bytes, BytesMut};
use crate::{ use crate::{
body::{Body, MessageBody}, body::{AnyBody, MessageBody},
error::Error, error::Error,
extensions::Extensions, extensions::Extensions,
http::{HeaderMap, StatusCode}, http::{HeaderMap, StatusCode},
@ -22,13 +22,13 @@ pub struct Response<B> {
pub(crate) body: B, pub(crate) body: B,
} }
impl Response<Body> { impl Response<AnyBody> {
/// Constructs a new response with default body. /// Constructs a new response with default body.
#[inline] #[inline]
pub fn new(status: StatusCode) -> Response<Body> { pub fn new(status: StatusCode) -> Self {
Response { Response {
head: BoxedResponseHead::new(status), head: BoxedResponseHead::new(status),
body: Body::Empty, body: AnyBody::Empty,
} }
} }
@ -43,25 +43,25 @@ impl Response<Body> {
/// Constructs a new response with status 200 OK. /// Constructs a new response with status 200 OK.
#[inline] #[inline]
pub fn ok() -> Response<Body> { pub fn ok() -> Self {
Response::new(StatusCode::OK) Response::new(StatusCode::OK)
} }
/// Constructs a new response with status 400 Bad Request. /// Constructs a new response with status 400 Bad Request.
#[inline] #[inline]
pub fn bad_request() -> Response<Body> { pub fn bad_request() -> Self {
Response::new(StatusCode::BAD_REQUEST) Response::new(StatusCode::BAD_REQUEST)
} }
/// Constructs a new response with status 404 Not Found. /// Constructs a new response with status 404 Not Found.
#[inline] #[inline]
pub fn not_found() -> Response<Body> { pub fn not_found() -> Self {
Response::new(StatusCode::NOT_FOUND) Response::new(StatusCode::NOT_FOUND)
} }
/// Constructs a new response with status 500 Internal Server Error. /// Constructs a new response with status 500 Internal Server Error.
#[inline] #[inline]
pub fn internal_server_error() -> Response<Body> { pub fn internal_server_error() -> Self {
Response::new(StatusCode::INTERNAL_SERVER_ERROR) Response::new(StatusCode::INTERNAL_SERVER_ERROR)
} }
@ -69,7 +69,7 @@ impl Response<Body> {
/// Constructs a new response from an error. /// Constructs a new response from an error.
#[inline] #[inline]
pub fn from_error(error: Error) -> Response<Body> { pub fn from_error(error: Error) -> Response<AnyBody> {
let resp = error.as_response_error().error_response(); let resp = error.as_response_error().error_response();
if resp.head.status == StatusCode::INTERNAL_SERVER_ERROR { if resp.head.status == StatusCode::INTERNAL_SERVER_ERROR {
debug!("Internal Server Error: {:?}", error); debug!("Internal Server Error: {:?}", error);
@ -234,7 +234,9 @@ impl<B: Default> Default for Response<B> {
} }
} }
impl<I: Into<Response<Body>>, E: Into<Error>> From<Result<I, E>> for Response<Body> { impl<I: Into<Response<AnyBody>>, E: Into<Error>> From<Result<I, E>>
for Response<AnyBody>
{
fn from(res: Result<I, E>) -> Self { fn from(res: Result<I, E>) -> Self {
match res { match res {
Ok(val) => val.into(), Ok(val) => val.into(),
@ -243,13 +245,13 @@ impl<I: Into<Response<Body>>, E: Into<Error>> From<Result<I, E>> for Response<Bo
} }
} }
impl From<ResponseBuilder> for Response<Body> { impl From<ResponseBuilder> for Response<AnyBody> {
fn from(mut builder: ResponseBuilder) -> Self { fn from(mut builder: ResponseBuilder) -> Self {
builder.finish() builder.finish()
} }
} }
impl From<()> for Response<Body> { impl From<()> for Response<AnyBody> {
fn from(_: ()) -> Self { fn from(_: ()) -> Self {
Error::from(crate::error::UnitError) Error::from(crate::error::UnitError)
.as_response_error() .as_response_error()
@ -257,13 +259,13 @@ impl From<()> for Response<Body> {
} }
} }
impl From<std::convert::Infallible> for Response<Body> { impl From<std::convert::Infallible> for Response<AnyBody> {
fn from(val: std::convert::Infallible) -> Self { fn from(val: std::convert::Infallible) -> Self {
match val {} match val {}
} }
} }
impl From<&'static str> for Response<Body> { impl From<&'static str> for Response<AnyBody> {
fn from(val: &'static str) -> Self { fn from(val: &'static str) -> Self {
Response::build(StatusCode::OK) Response::build(StatusCode::OK)
.content_type(mime::TEXT_PLAIN_UTF_8) .content_type(mime::TEXT_PLAIN_UTF_8)
@ -271,7 +273,7 @@ impl From<&'static str> for Response<Body> {
} }
} }
impl From<&'static [u8]> for Response<Body> { impl From<&'static [u8]> for Response<AnyBody> {
fn from(val: &'static [u8]) -> Self { fn from(val: &'static [u8]) -> Self {
Response::build(StatusCode::OK) Response::build(StatusCode::OK)
.content_type(mime::APPLICATION_OCTET_STREAM) .content_type(mime::APPLICATION_OCTET_STREAM)
@ -279,7 +281,7 @@ impl From<&'static [u8]> for Response<Body> {
} }
} }
impl From<String> for Response<Body> { impl From<String> for Response<AnyBody> {
fn from(val: String) -> Self { fn from(val: String) -> Self {
Response::build(StatusCode::OK) Response::build(StatusCode::OK)
.content_type(mime::TEXT_PLAIN_UTF_8) .content_type(mime::TEXT_PLAIN_UTF_8)
@ -287,7 +289,7 @@ impl From<String> for Response<Body> {
} }
} }
impl<'a> From<&'a String> for Response<Body> { impl<'a> From<&'a String> for Response<AnyBody> {
fn from(val: &'a String) -> Self { fn from(val: &'a String) -> Self {
Response::build(StatusCode::OK) Response::build(StatusCode::OK)
.content_type(mime::TEXT_PLAIN_UTF_8) .content_type(mime::TEXT_PLAIN_UTF_8)
@ -295,7 +297,7 @@ impl<'a> From<&'a String> for Response<Body> {
} }
} }
impl From<Bytes> for Response<Body> { impl From<Bytes> for Response<AnyBody> {
fn from(val: Bytes) -> Self { fn from(val: Bytes) -> Self {
Response::build(StatusCode::OK) Response::build(StatusCode::OK)
.content_type(mime::APPLICATION_OCTET_STREAM) .content_type(mime::APPLICATION_OCTET_STREAM)
@ -303,7 +305,7 @@ impl From<Bytes> for Response<Body> {
} }
} }
impl From<BytesMut> for Response<Body> { impl From<BytesMut> for Response<AnyBody> {
fn from(val: BytesMut) -> Self { fn from(val: BytesMut) -> Self {
Response::build(StatusCode::OK) Response::build(StatusCode::OK)
.content_type(mime::APPLICATION_OCTET_STREAM) .content_type(mime::APPLICATION_OCTET_STREAM)
@ -314,7 +316,6 @@ impl From<BytesMut> for Response<Body> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::body::Body;
use crate::http::header::{HeaderValue, CONTENT_TYPE, COOKIE}; use crate::http::header::{HeaderValue, CONTENT_TYPE, COOKIE};
#[test] #[test]
@ -329,7 +330,7 @@ mod tests {
#[test] #[test]
fn test_into_response() { fn test_into_response() {
let resp: Response<Body> = "test".into(); let resp: Response<AnyBody> = "test".into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!( assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(), resp.headers().get(CONTENT_TYPE).unwrap(),
@ -338,7 +339,7 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().get_ref(), b"test"); assert_eq!(resp.body().get_ref(), b"test");
let resp: Response<Body> = b"test".as_ref().into(); let resp: Response<AnyBody> = b"test".as_ref().into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!( assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(), resp.headers().get(CONTENT_TYPE).unwrap(),
@ -347,7 +348,7 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().get_ref(), b"test"); assert_eq!(resp.body().get_ref(), b"test");
let resp: Response<Body> = "test".to_owned().into(); let resp: Response<AnyBody> = "test".to_owned().into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!( assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(), resp.headers().get(CONTENT_TYPE).unwrap(),
@ -356,7 +357,7 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().get_ref(), b"test"); assert_eq!(resp.body().get_ref(), b"test");
let resp: Response<Body> = (&"test".to_owned()).into(); let resp: Response<AnyBody> = (&"test".to_owned()).into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!( assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(), resp.headers().get(CONTENT_TYPE).unwrap(),
@ -366,7 +367,7 @@ mod tests {
assert_eq!(resp.body().get_ref(), b"test"); assert_eq!(resp.body().get_ref(), b"test");
let b = Bytes::from_static(b"test"); let b = Bytes::from_static(b"test");
let resp: Response<Body> = b.into(); let resp: Response<AnyBody> = b.into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!( assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(), resp.headers().get(CONTENT_TYPE).unwrap(),
@ -376,7 +377,7 @@ mod tests {
assert_eq!(resp.body().get_ref(), b"test"); assert_eq!(resp.body().get_ref(), b"test");
let b = Bytes::from_static(b"test"); let b = Bytes::from_static(b"test");
let resp: Response<Body> = b.into(); let resp: Response<AnyBody> = b.into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!( assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(), resp.headers().get(CONTENT_TYPE).unwrap(),
@ -386,7 +387,7 @@ mod tests {
assert_eq!(resp.body().get_ref(), b"test"); assert_eq!(resp.body().get_ref(), b"test");
let b = BytesMut::from("test"); let b = BytesMut::from("test");
let resp: Response<Body> = b.into(); let resp: Response<AnyBody> = b.into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!( assert_eq!(
resp.headers().get(CONTENT_TYPE).unwrap(), resp.headers().get(CONTENT_TYPE).unwrap(),

View File

@ -72,7 +72,7 @@ mod inner {
use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed}; use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed};
use crate::ResponseError; use crate::{body::AnyBody, Response, ResponseError};
/// Framed transport errors /// Framed transport errors
pub enum DispatcherError<E, U, I> pub enum DispatcherError<E, U, I>
@ -145,6 +145,18 @@ mod inner {
{ {
} }
impl<E, U, I> From<DispatcherError<E, U, I>> for Response<AnyBody>
where
E: fmt::Debug + fmt::Display,
U: Encoder<I> + Decoder,
<U as Encoder<I>>::Error: fmt::Debug,
<U as Decoder>::Error: fmt::Debug,
{
fn from(err: DispatcherError<E, U, I>) -> Self {
Response::internal_server_error().set_body(AnyBody::from(err.to_string()))
}
}
/// Message type wrapper for signalling end of message stream. /// Message type wrapper for signalling end of message stream.
pub enum Message<T> { pub enum Message<T> {
/// Message item. /// Message item.

View File

@ -36,10 +36,11 @@ use std::{fmt, net, sync::mpsc, thread, time};
use actix_codec::{AsyncRead, AsyncWrite, Framed}; use actix_codec::{AsyncRead, AsyncWrite, Framed};
pub use actix_http::test::TestBuffer; pub use actix_http::test::TestBuffer;
use actix_http::{ use actix_http::{
body::AnyBody,
http::{HeaderMap, Method}, http::{HeaderMap, Method},
ws, HttpService, Request, Response, ws, HttpService, Request, Response,
}; };
use actix_service::{map_config, IntoServiceFactory, ServiceFactory}; use actix_service::{map_config, IntoServiceFactory, ServiceFactory, ServiceFactoryExt as _};
use actix_web::{ use actix_web::{
dev::{AppConfig, MessageBody, Server, Service}, dev::{AppConfig, MessageBody, Server, Service},
rt, web, Error, rt, web, Error,
@ -86,7 +87,7 @@ where
S::Response: Into<Response<B>> + 'static, S::Response: Into<Response<B>> + 'static,
<S::Service as Service<Request>>::Future: 'static, <S::Service as Service<Request>>::Future: 'static,
B: MessageBody + 'static, B: MessageBody + 'static,
B::Error: Into<Error>, B::Error: Into<Response<AnyBody>>,
{ {
start_with(TestServerConfig::default(), factory) start_with(TestServerConfig::default(), factory)
} }
@ -126,7 +127,7 @@ where
S::Response: Into<Response<B>> + 'static, S::Response: Into<Response<B>> + 'static,
<S::Service as Service<Request>>::Future: 'static, <S::Service as Service<Request>>::Future: 'static,
B: MessageBody + 'static, B: MessageBody + 'static,
B::Error: Into<Error>, B::Error: Into<Response<AnyBody>>,
{ {
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
@ -153,25 +154,34 @@ where
HttpVer::Http1 => builder.listen("test", tcp, move || { HttpVer::Http1 => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h1(map_config(factory(), move |_| app_cfg.clone())) .h1(map_config(fac, move |_| app_cfg.clone()))
.tcp() .tcp()
}), }),
HttpVer::Http2 => builder.listen("test", tcp, move || { HttpVer::Http2 => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h2(map_config(factory(), move |_| app_cfg.clone())) .h2(map_config(fac, move |_| app_cfg.clone()))
.tcp() .tcp()
}), }),
HttpVer::Both => builder.listen("test", tcp, move || { HttpVer::Both => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.finish(map_config(factory(), move |_| app_cfg.clone())) .finish(map_config(fac, move |_| app_cfg.clone()))
.tcp() .tcp()
}), }),
}, },
@ -180,25 +190,34 @@ where
HttpVer::Http1 => builder.listen("test", tcp, move || { HttpVer::Http1 => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h1(map_config(factory(), move |_| app_cfg.clone())) .h1(map_config(fac, move |_| app_cfg.clone()))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
}), }),
HttpVer::Http2 => builder.listen("test", tcp, move || { HttpVer::Http2 => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h2(map_config(factory(), move |_| app_cfg.clone())) .h2(map_config(fac, move |_| app_cfg.clone()))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
}), }),
HttpVer::Both => builder.listen("test", tcp, move || { HttpVer::Both => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.finish(map_config(factory(), move |_| app_cfg.clone())) .finish(map_config(fac, move |_| app_cfg.clone()))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
}), }),
}, },
@ -207,25 +226,34 @@ where
HttpVer::Http1 => builder.listen("test", tcp, move || { HttpVer::Http1 => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h1(map_config(factory(), move |_| app_cfg.clone())) .h1(map_config(fac, move |_| app_cfg.clone()))
.rustls(config.clone()) .rustls(config.clone())
}), }),
HttpVer::Http2 => builder.listen("test", tcp, move || { HttpVer::Http2 => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.h2(map_config(factory(), move |_| app_cfg.clone())) .h2(map_config(fac, move |_| app_cfg.clone()))
.rustls(config.clone()) .rustls(config.clone())
}), }),
HttpVer::Both => builder.listen("test", tcp, move || { HttpVer::Both => builder.listen("test", tcp, move || {
let app_cfg = let app_cfg =
AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
let fac = factory().into_factory().map_err(|err| err.into());
HttpService::build() HttpService::build()
.client_timeout(timeout) .client_timeout(timeout)
.finish(map_config(factory(), move |_| app_cfg.clone())) .finish(map_config(fac, move |_| app_cfg.clone()))
.rustls(config.clone()) .rustls(config.clone())
}), }),
}, },

View File

@ -7,10 +7,13 @@ use std::{
}; };
use actix_http::{ use actix_http::{
body::MessageBody, Error, Extensions, HttpService, KeepAlive, Request, Response, body::{AnyBody, MessageBody},
Error, Extensions, HttpService, KeepAlive, Request, Response,
}; };
use actix_server::{Server, ServerBuilder}; use actix_server::{Server, ServerBuilder};
use actix_service::{map_config, IntoServiceFactory, Service, ServiceFactory}; use actix_service::{
map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
};
#[cfg(feature = "openssl")] #[cfg(feature = "openssl")]
use actix_tls::accept::openssl::{AlpnError, SslAcceptor, SslAcceptorBuilder}; use actix_tls::accept::openssl::{AlpnError, SslAcceptor, SslAcceptorBuilder};
@ -81,7 +84,7 @@ where
S::Service: 'static, S::Service: 'static,
// S::Service: 'static, // S::Service: 'static,
B: MessageBody + 'static, B: MessageBody + 'static,
B::Error: Into<Error>, B::Error: Into<Response<AnyBody>>,
{ {
/// Create new HTTP server with application factory /// Create new HTTP server with application factory
pub fn new(factory: F) -> Self { pub fn new(factory: F) -> Self {
@ -301,7 +304,9 @@ where
svc svc
}; };
svc.finish(map_config(factory(), move |_| { let fac = factory().into_factory().map_err(|err| err.into());
svc.finish(map_config(fac, move |_| {
AppConfig::new(false, host.clone(), addr) AppConfig::new(false, host.clone(), addr)
})) }))
.tcp() .tcp()
@ -356,7 +361,9 @@ where
svc svc
}; };
svc.finish(map_config(factory(), move |_| { let fac = factory().into_factory().map_err(|err| err.into());
svc.finish(map_config(fac, move |_| {
AppConfig::new(true, host.clone(), addr) AppConfig::new(true, host.clone(), addr)
})) }))
.openssl(acceptor.clone()) .openssl(acceptor.clone())
@ -410,7 +417,9 @@ where
svc svc
}; };
svc.finish(map_config(factory(), move |_| { let fac = factory().into_factory().map_err(|err| err.into());
svc.finish(map_config(fac, move |_| {
AppConfig::new(true, host.clone(), addr) AppConfig::new(true, host.clone(), addr)
})) }))
.rustls(config.clone()) .rustls(config.clone())
@ -533,7 +542,9 @@ where
svc svc
}; };
svc.finish(map_config(factory(), move |_| config.clone())) let fac = factory().into_factory().map_err(|err| err.into());
svc.finish(map_config(fac, move |_| config.clone()))
}) })
})?; })?;
Ok(self) Ok(self)
@ -568,14 +579,18 @@ where
c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)), c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
socket_addr, socket_addr,
); );
let fac = factory().into_factory().map_err(|err| err.into());
fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then( fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then(
HttpService::build() HttpService::build()
.keep_alive(c.keep_alive) .keep_alive(c.keep_alive)
.client_timeout(c.client_timeout) .client_timeout(c.client_timeout)
.finish(map_config(factory(), move |_| config.clone())), .finish(map_config(fac, move |_| config.clone())),
) )
}, },
)?; )?;
Ok(self) Ok(self)
} }
} }