mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-24 01:11:07 +01:00
service trait takes request type parameter (#232)
This commit is contained in:
parent
518bf3f6a6
commit
3ab8c3eb69
@ -40,8 +40,7 @@ impl<T> Clone for TcpConnectorFactory<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> ServiceFactory for TcpConnectorFactory<T> {
|
impl<T: Address> ServiceFactory<Connect<T>> for TcpConnectorFactory<T> {
|
||||||
type Request = Connect<T>;
|
|
||||||
type Response = Connection<T, TcpStream>;
|
type Response = Connection<T, TcpStream>;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
@ -70,8 +69,7 @@ impl<T> Clone for TcpConnector<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> Service for TcpConnector<T> {
|
impl<T: Address> Service<Connect<T>> for TcpConnector<T> {
|
||||||
type Request = Connect<T>;
|
|
||||||
type Response = Connection<T, TcpStream>;
|
type Response = Connection<T, TcpStream>;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
|
@ -76,8 +76,8 @@ pub async fn start_default_resolver() -> Result<AsyncResolver, ConnectError> {
|
|||||||
/// Create TCP connector service.
|
/// Create TCP connector service.
|
||||||
pub fn new_connector<T: Address + 'static>(
|
pub fn new_connector<T: Address + 'static>(
|
||||||
resolver: AsyncResolver,
|
resolver: AsyncResolver,
|
||||||
) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
|
) -> impl Service<Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError> + Clone
|
||||||
+ Clone {
|
{
|
||||||
pipeline(Resolver::new(resolver)).and_then(TcpConnector::new())
|
pipeline(Resolver::new(resolver)).and_then(TcpConnector::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +85,8 @@ pub fn new_connector<T: Address + 'static>(
|
|||||||
pub fn new_connector_factory<T: Address + 'static>(
|
pub fn new_connector_factory<T: Address + 'static>(
|
||||||
resolver: AsyncResolver,
|
resolver: AsyncResolver,
|
||||||
) -> impl ServiceFactory<
|
) -> impl ServiceFactory<
|
||||||
|
Connect<T>,
|
||||||
Config = (),
|
Config = (),
|
||||||
Request = Connect<T>,
|
|
||||||
Response = Connection<T, TcpStream>,
|
Response = Connection<T, TcpStream>,
|
||||||
Error = ConnectError,
|
Error = ConnectError,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
@ -96,15 +96,15 @@ pub fn new_connector_factory<T: Address + 'static>(
|
|||||||
|
|
||||||
/// Create connector service with default parameters.
|
/// Create connector service with default parameters.
|
||||||
pub fn default_connector<T: Address + 'static>(
|
pub fn default_connector<T: Address + 'static>(
|
||||||
) -> impl Service<Request = Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
|
) -> impl Service<Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError> + Clone
|
||||||
+ Clone {
|
{
|
||||||
pipeline(Resolver::default()).and_then(TcpConnector::new())
|
pipeline(Resolver::default()).and_then(TcpConnector::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create connector service factory with default parameters.
|
/// Create connector service factory with default parameters.
|
||||||
pub fn default_connector_factory<T: Address + 'static>() -> impl ServiceFactory<
|
pub fn default_connector_factory<T: Address + 'static>() -> impl ServiceFactory<
|
||||||
|
Connect<T>,
|
||||||
Config = (),
|
Config = (),
|
||||||
Request = Connect<T>,
|
|
||||||
Response = Connection<T, TcpStream>,
|
Response = Connection<T, TcpStream>,
|
||||||
Error = ConnectError,
|
Error = ConnectError,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
|
@ -54,8 +54,7 @@ impl<T> Clone for ResolverFactory<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> ServiceFactory for ResolverFactory<T> {
|
impl<T: Address> ServiceFactory<Connect<T>> for ResolverFactory<T> {
|
||||||
type Request = Connect<T>;
|
|
||||||
type Response = Connect<T>;
|
type Response = Connect<T>;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
@ -102,8 +101,7 @@ impl<T> Clone for Resolver<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> Service for Resolver<T> {
|
impl<T: Address> Service<Connect<T>> for Resolver<T> {
|
||||||
type Request = Connect<T>;
|
|
||||||
type Response = Connect<T>;
|
type Response = Connect<T>;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
|
@ -70,8 +70,7 @@ impl<T> Clone for ConnectServiceFactory<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> ServiceFactory for ConnectServiceFactory<T> {
|
impl<T: Address> ServiceFactory<Connect<T>> for ConnectServiceFactory<T> {
|
||||||
type Request = Connect<T>;
|
|
||||||
type Response = Connection<T, TcpStream>;
|
type Response = Connection<T, TcpStream>;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
@ -90,8 +89,7 @@ pub struct ConnectService<T> {
|
|||||||
resolver: Resolver<T>,
|
resolver: Resolver<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> Service for ConnectService<T> {
|
impl<T: Address> Service<Connect<T>> for ConnectService<T> {
|
||||||
type Request = Connect<T>;
|
|
||||||
type Response = Connection<T, TcpStream>;
|
type Response = Connection<T, TcpStream>;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
type Future = ConnectServiceResponse<T>;
|
type Future = ConnectServiceResponse<T>;
|
||||||
@ -109,8 +107,8 @@ impl<T: Address> Service for ConnectService<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ConnectState<T: Address> {
|
enum ConnectState<T: Address> {
|
||||||
Resolve(<Resolver<T> as Service>::Future),
|
Resolve(<Resolver<T> as Service<Connect<T>>>::Future),
|
||||||
Connect(<TcpConnector<T> as Service>::Future),
|
Connect(<TcpConnector<T> as Service<Connect<T>>>::Future),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> ConnectState<T> {
|
impl<T: Address> ConnectState<T> {
|
||||||
@ -160,8 +158,7 @@ pub struct TcpConnectService<T> {
|
|||||||
resolver: Resolver<T>,
|
resolver: Resolver<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address + 'static> Service for TcpConnectService<T> {
|
impl<T: Address + 'static> Service<Connect<T>> for TcpConnectService<T> {
|
||||||
type Request = Connect<T>;
|
|
||||||
type Response = TcpStream;
|
type Response = TcpStream;
|
||||||
type Error = ConnectError;
|
type Error = ConnectError;
|
||||||
type Future = TcpConnectServiceResponse<T>;
|
type Future = TcpConnectServiceResponse<T>;
|
||||||
@ -179,8 +176,8 @@ impl<T: Address + 'static> Service for TcpConnectService<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum TcpConnectState<T: Address> {
|
enum TcpConnectState<T: Address> {
|
||||||
Resolve(<Resolver<T> as Service>::Future),
|
Resolve(<Resolver<T> as Service<Connect<T>>>::Future),
|
||||||
Connect(<TcpConnector<T> as Service>::Future),
|
Connect(<TcpConnector<T> as Service<Connect<T>>>::Future),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address> TcpConnectState<T> {
|
impl<T: Address> TcpConnectState<T> {
|
||||||
|
@ -2,7 +2,10 @@ use std::collections::HashMap;
|
|||||||
use std::{fmt, io, net};
|
use std::{fmt, io, net};
|
||||||
|
|
||||||
use actix_rt::net::TcpStream;
|
use actix_rt::net::TcpStream;
|
||||||
use actix_service as actix;
|
use actix_service::{
|
||||||
|
fn_service, IntoServiceFactory as IntoBaseServiceFactory,
|
||||||
|
ServiceFactory as BaseServiceFactory,
|
||||||
|
};
|
||||||
use actix_utils::counter::CounterGuard;
|
use actix_utils::counter::CounterGuard;
|
||||||
use futures_util::future::{ok, Future, FutureExt, LocalBoxFuture};
|
use futures_util::future::{ok, Future, FutureExt, LocalBoxFuture};
|
||||||
use log::error;
|
use log::error;
|
||||||
@ -141,12 +144,10 @@ impl InternalServiceFactory for ConfiguredService {
|
|||||||
let name = names.remove(&token).unwrap().0;
|
let name = names.remove(&token).unwrap().0;
|
||||||
res.push((
|
res.push((
|
||||||
token,
|
token,
|
||||||
Box::new(StreamService::new(actix::fn_service(
|
Box::new(StreamService::new(fn_service(move |_: TcpStream| {
|
||||||
move |_: TcpStream| {
|
|
||||||
error!("Service {:?} is not configured", name);
|
error!("Service {:?} is not configured", name);
|
||||||
ok::<_, ()>(())
|
ok::<_, ()>(())
|
||||||
},
|
}))),
|
||||||
))),
|
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -208,8 +209,8 @@ impl ServiceRuntime {
|
|||||||
/// *ServiceConfig::bind()* or *ServiceConfig::listen()* methods.
|
/// *ServiceConfig::bind()* or *ServiceConfig::listen()* methods.
|
||||||
pub fn service<T, F>(&mut self, name: &str, service: F)
|
pub fn service<T, F>(&mut self, name: &str, service: F)
|
||||||
where
|
where
|
||||||
F: actix::IntoServiceFactory<T>,
|
F: IntoBaseServiceFactory<T, TcpStream>,
|
||||||
T: actix::ServiceFactory<Config = (), Request = TcpStream> + 'static,
|
T: BaseServiceFactory<TcpStream, Config = ()> + 'static,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
T::Service: 'static,
|
T::Service: 'static,
|
||||||
T::InitError: fmt::Debug,
|
T::InitError: fmt::Debug,
|
||||||
@ -237,8 +238,8 @@ impl ServiceRuntime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BoxedNewService = Box<
|
type BoxedNewService = Box<
|
||||||
dyn actix::ServiceFactory<
|
dyn BaseServiceFactory<
|
||||||
Request = (Option<CounterGuard>, StdStream),
|
(Option<CounterGuard>, StdStream),
|
||||||
Response = (),
|
Response = (),
|
||||||
Error = (),
|
Error = (),
|
||||||
InitError = (),
|
InitError = (),
|
||||||
@ -252,15 +253,14 @@ struct ServiceFactory<T> {
|
|||||||
inner: T,
|
inner: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> actix::ServiceFactory for ServiceFactory<T>
|
impl<T> BaseServiceFactory<(Option<CounterGuard>, StdStream)> for ServiceFactory<T>
|
||||||
where
|
where
|
||||||
T: actix::ServiceFactory<Config = (), Request = TcpStream>,
|
T: BaseServiceFactory<TcpStream, Config = ()>,
|
||||||
T::Future: 'static,
|
T::Future: 'static,
|
||||||
T::Service: 'static,
|
T::Service: 'static,
|
||||||
T::Error: 'static,
|
T::Error: 'static,
|
||||||
T::InitError: fmt::Debug + 'static,
|
T::InitError: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
type Request = (Option<CounterGuard>, StdStream);
|
|
||||||
type Response = ();
|
type Response = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
@ -3,7 +3,7 @@ use std::net::SocketAddr;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use actix_rt::spawn;
|
use actix_rt::spawn;
|
||||||
use actix_service::{self as actix, Service, ServiceFactory as ActixServiceFactory};
|
use actix_service::{Service, ServiceFactory as BaseServiceFactory};
|
||||||
use actix_utils::counter::CounterGuard;
|
use actix_utils::counter::CounterGuard;
|
||||||
use futures_util::future::{err, ok, LocalBoxFuture, Ready};
|
use futures_util::future::{err, ok, LocalBoxFuture, Ready};
|
||||||
use futures_util::{FutureExt, TryFutureExt};
|
use futures_util::{FutureExt, TryFutureExt};
|
||||||
@ -13,7 +13,7 @@ use super::Token;
|
|||||||
use crate::socket::{FromStream, StdStream};
|
use crate::socket::{FromStream, StdStream};
|
||||||
|
|
||||||
pub trait ServiceFactory<Stream: FromStream>: Send + Clone + 'static {
|
pub trait ServiceFactory<Stream: FromStream>: Send + Clone + 'static {
|
||||||
type Factory: actix::ServiceFactory<Config = (), Request = Stream>;
|
type Factory: BaseServiceFactory<Stream, Config = ()>;
|
||||||
|
|
||||||
fn create(&self) -> Self::Factory;
|
fn create(&self) -> Self::Factory;
|
||||||
}
|
}
|
||||||
@ -28,31 +28,34 @@ pub(crate) trait InternalServiceFactory: Send {
|
|||||||
|
|
||||||
pub(crate) type BoxedServerService = Box<
|
pub(crate) type BoxedServerService = Box<
|
||||||
dyn Service<
|
dyn Service<
|
||||||
Request = (Option<CounterGuard>, StdStream),
|
(Option<CounterGuard>, StdStream),
|
||||||
Response = (),
|
Response = (),
|
||||||
Error = (),
|
Error = (),
|
||||||
Future = Ready<Result<(), ()>>,
|
Future = Ready<Result<(), ()>>,
|
||||||
>,
|
>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub(crate) struct StreamService<T> {
|
pub(crate) struct StreamService<S, I> {
|
||||||
service: T,
|
service: S,
|
||||||
|
_phantom: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> StreamService<T> {
|
impl<S, I> StreamService<S, I> {
|
||||||
pub(crate) fn new(service: T) -> Self {
|
pub(crate) fn new(service: S) -> Self {
|
||||||
StreamService { service }
|
StreamService {
|
||||||
|
service,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, I> Service for StreamService<T>
|
impl<S, I> Service<(Option<CounterGuard>, StdStream)> for StreamService<S, I>
|
||||||
where
|
where
|
||||||
T: Service<Request = I>,
|
S: Service<I>,
|
||||||
T::Future: 'static,
|
S::Future: 'static,
|
||||||
T::Error: 'static,
|
S::Error: 'static,
|
||||||
I: FromStream,
|
I: FromStream,
|
||||||
{
|
{
|
||||||
type Request = (Option<CounterGuard>, StdStream);
|
|
||||||
type Response = ();
|
type Response = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<(), ()>>;
|
type Future = Ready<Result<(), ()>>;
|
||||||
@ -144,7 +147,7 @@ where
|
|||||||
impl<F, T, I> ServiceFactory<I> for F
|
impl<F, T, I> ServiceFactory<I> for F
|
||||||
where
|
where
|
||||||
F: Fn() -> T + Send + Clone + 'static,
|
F: Fn() -> T + Send + Clone + 'static,
|
||||||
T: actix::ServiceFactory<Config = (), Request = I>,
|
T: BaseServiceFactory<I, Config = ()>,
|
||||||
I: FromStream,
|
I: FromStream,
|
||||||
{
|
{
|
||||||
type Factory = T;
|
type Factory = T;
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
* `Service`, other traits, and many type signatures now take the the request type as a type
|
||||||
|
parameter instead of an associated type. [#232]
|
||||||
* Upgrade `pin-project` to `1.0`.
|
* Upgrade `pin-project` to `1.0`.
|
||||||
|
|
||||||
|
|
||||||
|
[#232]: https://github.com/actix/actix-net/pull/232
|
||||||
|
|
||||||
|
|
||||||
## 1.0.6 - 2020-08-09
|
## 1.0.6 - 2020-08-09
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -5,11 +5,14 @@ use actix_service::Service;
|
|||||||
use criterion::{criterion_main, Criterion};
|
use criterion::{criterion_main, Criterion};
|
||||||
use futures_util::future::join_all;
|
use futures_util::future::join_all;
|
||||||
use futures_util::future::TryFutureExt;
|
use futures_util::future::TryFutureExt;
|
||||||
use std::cell::{RefCell, UnsafeCell};
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
use std::{
|
||||||
|
cell::{RefCell, UnsafeCell},
|
||||||
|
marker::PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test services A,B for AndThen service implementations
|
* Test services A,B for AndThen service implementations
|
||||||
@ -28,71 +31,72 @@ async fn svc2(req: usize) -> Result<usize, ()> {
|
|||||||
* Cut down version of actix_service::AndThenService based on actix-service::Cell
|
* Cut down version of actix_service::AndThenService based on actix-service::Cell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct AndThenUC<A, B>(Rc<UnsafeCell<(A, B)>>);
|
struct AndThenUC<A, Req, B>(Rc<UnsafeCell<(A, B)>>, PhantomData<Req>);
|
||||||
|
|
||||||
impl<A, B> AndThenUC<A, B> {
|
impl<A, Req, B> AndThenUC<A, Req, B> {
|
||||||
fn new(a: A, b: B) -> Self
|
fn new(a: A, b: B) -> Self
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
Self(Rc::new(UnsafeCell::new((a, b))))
|
Self(Rc::new(UnsafeCell::new((a, b))), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for AndThenUC<A, B> {
|
impl<A, Req, B> Clone for AndThenUC<A, Req, B> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.clone())
|
Self(self.0.clone(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Service for AndThenUC<A, B>
|
impl<A, Req, B> Service<Req> for AndThenUC<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
type Future = AndThenServiceResponse<A, B>;
|
type Future = AndThenServiceResponse<A, Req, B>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
let fut = unsafe { &mut *(*self.0).get() }.0.call(req);
|
let fut = unsafe { &mut *(*self.0).get() }.0.call(req);
|
||||||
AndThenServiceResponse {
|
AndThenServiceResponse {
|
||||||
state: State::A(fut, Some(self.0.clone())),
|
state: State::A(fut, Some(self.0.clone())),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct AndThenServiceResponse<A, B>
|
pub(crate) struct AndThenServiceResponse<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
state: State<A, B>,
|
state: State<A, Req, B>,
|
||||||
|
_phantom: PhantomData<Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = StateProj)]
|
#[pin_project::pin_project(project = StateProj)]
|
||||||
enum State<A, B>
|
enum State<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
A(#[pin] A::Future, Option<Rc<UnsafeCell<(A, B)>>>),
|
A(#[pin] A::Future, Option<Rc<UnsafeCell<(A, B)>>>),
|
||||||
B(#[pin] B::Future),
|
B(#[pin] B::Future),
|
||||||
Empty,
|
Empty(PhantomData<Req>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Future for AndThenServiceResponse<A, B>
|
impl<A, Req, B> Future for AndThenServiceResponse<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
type Output = Result<B::Response, A::Error>;
|
type Output = Result<B::Response, A::Error>;
|
||||||
|
|
||||||
@ -103,7 +107,7 @@ where
|
|||||||
StateProj::A(fut, b) => match fut.poll(cx)? {
|
StateProj::A(fut, b) => match fut.poll(cx)? {
|
||||||
Poll::Ready(res) => {
|
Poll::Ready(res) => {
|
||||||
let b = b.take().unwrap();
|
let b = b.take().unwrap();
|
||||||
this.state.set(State::Empty); // drop fut A
|
this.state.set(State::Empty(PhantomData)); // drop fut A
|
||||||
let fut = unsafe { &mut (*b.get()).1 }.call(res);
|
let fut = unsafe { &mut (*b.get()).1 }.call(res);
|
||||||
this.state.set(State::B(fut));
|
this.state.set(State::B(fut));
|
||||||
self.poll(cx)
|
self.poll(cx)
|
||||||
@ -111,10 +115,10 @@ where
|
|||||||
Poll::Pending => Poll::Pending,
|
Poll::Pending => Poll::Pending,
|
||||||
},
|
},
|
||||||
StateProj::B(fut) => fut.poll(cx).map(|r| {
|
StateProj::B(fut) => fut.poll(cx).map(|r| {
|
||||||
this.state.set(State::Empty);
|
this.state.set(State::Empty(PhantomData));
|
||||||
r
|
r
|
||||||
}),
|
}),
|
||||||
StateProj::Empty => {
|
StateProj::Empty(_) => {
|
||||||
panic!("future must not be polled after it returned `Poll::Ready`")
|
panic!("future must not be polled after it returned `Poll::Ready`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,39 +129,38 @@ where
|
|||||||
* AndThenRC - AndThen service based on RefCell
|
* AndThenRC - AndThen service based on RefCell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct AndThenRC<A, B>(Rc<RefCell<(A, B)>>);
|
struct AndThenRC<A, Req, B>(Rc<RefCell<(A, B)>>, PhantomData<Req>);
|
||||||
|
|
||||||
impl<A, B> AndThenRC<A, B> {
|
impl<A, Req, B> AndThenRC<A, Req, B> {
|
||||||
fn new(a: A, b: B) -> Self
|
fn new(a: A, b: B) -> Self
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
Self(Rc::new(RefCell::new((a, b))))
|
Self(Rc::new(RefCell::new((a, b))), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for AndThenRC<A, B> {
|
impl<A, Req, B> Clone for AndThenRC<A, Req, B> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.clone())
|
Self(self.0.clone(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Service for AndThenRC<A, B>
|
impl<A, Req, B> Service<Req> for AndThenRC<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
type Future = AndThenServiceResponseRC<A, B>;
|
type Future = AndThenServiceResponseRC<A, Req, B>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
let fut = self.0.borrow_mut().0.call(req);
|
let fut = self.0.borrow_mut().0.call(req);
|
||||||
AndThenServiceResponseRC {
|
AndThenServiceResponseRC {
|
||||||
state: StateRC::A(fut, Some(self.0.clone())),
|
state: StateRC::A(fut, Some(self.0.clone())),
|
||||||
@ -166,30 +169,30 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct AndThenServiceResponseRC<A, B>
|
pub(crate) struct AndThenServiceResponseRC<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
state: StateRC<A, B>,
|
state: StateRC<A, Req, B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = StateRCProj)]
|
#[pin_project::pin_project(project = StateRCProj)]
|
||||||
enum StateRC<A, B>
|
enum StateRC<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
A(#[pin] A::Future, Option<Rc<RefCell<(A, B)>>>),
|
A(#[pin] A::Future, Option<Rc<RefCell<(A, B)>>>),
|
||||||
B(#[pin] B::Future),
|
B(#[pin] B::Future),
|
||||||
Empty,
|
Empty(PhantomData<Req>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Future for AndThenServiceResponseRC<A, B>
|
impl<A, Req, B> Future for AndThenServiceResponseRC<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
type Output = Result<B::Response, A::Error>;
|
type Output = Result<B::Response, A::Error>;
|
||||||
|
|
||||||
@ -200,7 +203,7 @@ where
|
|||||||
StateRCProj::A(fut, b) => match fut.poll(cx)? {
|
StateRCProj::A(fut, b) => match fut.poll(cx)? {
|
||||||
Poll::Ready(res) => {
|
Poll::Ready(res) => {
|
||||||
let b = b.take().unwrap();
|
let b = b.take().unwrap();
|
||||||
this.state.set(StateRC::Empty); // drop fut A
|
this.state.set(StateRC::Empty(PhantomData)); // drop fut A
|
||||||
let fut = b.borrow_mut().1.call(res);
|
let fut = b.borrow_mut().1.call(res);
|
||||||
this.state.set(StateRC::B(fut));
|
this.state.set(StateRC::B(fut));
|
||||||
self.poll(cx)
|
self.poll(cx)
|
||||||
@ -208,10 +211,10 @@ where
|
|||||||
Poll::Pending => Poll::Pending,
|
Poll::Pending => Poll::Pending,
|
||||||
},
|
},
|
||||||
StateRCProj::B(fut) => fut.poll(cx).map(|r| {
|
StateRCProj::B(fut) => fut.poll(cx).map(|r| {
|
||||||
this.state.set(StateRC::Empty);
|
this.state.set(StateRC::Empty(PhantomData));
|
||||||
r
|
r
|
||||||
}),
|
}),
|
||||||
StateRCProj::Empty => {
|
StateRCProj::Empty(_) => {
|
||||||
panic!("future must not be polled after it returned `Poll::Ready`")
|
panic!("future must not be polled after it returned `Poll::Ready`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,32 +226,31 @@ where
|
|||||||
* and standard futures::future::and_then combinator in a Box
|
* and standard futures::future::and_then combinator in a Box
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct AndThenRCFuture<A, B>(Rc<RefCell<(A, B)>>);
|
struct AndThenRCFuture<A, Req, B>(Rc<RefCell<(A, B)>>, PhantomData<Req>);
|
||||||
|
|
||||||
impl<A, B> AndThenRCFuture<A, B> {
|
impl<A, Req, B> AndThenRCFuture<A, Req, B> {
|
||||||
fn new(a: A, b: B) -> Self
|
fn new(a: A, b: B) -> Self
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
Self(Rc::new(RefCell::new((a, b))))
|
Self(Rc::new(RefCell::new((a, b))), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for AndThenRCFuture<A, B> {
|
impl<A, Req, B> Clone for AndThenRCFuture<A, Req, B> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.clone())
|
Self(self.0.clone(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Service for AndThenRCFuture<A, B>
|
impl<A, Req, B> Service<Req> for AndThenRCFuture<A, Req, B>
|
||||||
where
|
where
|
||||||
A: Service + 'static,
|
A: Service<Req> + 'static,
|
||||||
A::Future: 'static,
|
A::Future: 'static,
|
||||||
B: Service<Request = A::Response, Error = A::Error> + 'static,
|
B: Service<A::Response, Error = A::Error> + 'static,
|
||||||
B::Future: 'static,
|
B::Future: 'static,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
type Future = BoxFuture<Self::Response, Self::Error>;
|
type Future = BoxFuture<Self::Response, Self::Error>;
|
||||||
@ -257,7 +259,7 @@ where
|
|||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
let fut = self.0.borrow_mut().0.call(req);
|
let fut = self.0.borrow_mut().0.call(req);
|
||||||
let core = self.0.clone();
|
let core = self.0.clone();
|
||||||
let fut2 = move |res| (*core).borrow_mut().1.call(res);
|
let fut2 = move |res| (*core).borrow_mut().1.call(res);
|
||||||
@ -281,7 +283,7 @@ where
|
|||||||
/// async_service_direct time: [1.0908 us 1.1656 us 1.2613 us]
|
/// async_service_direct time: [1.0908 us 1.1656 us 1.2613 us]
|
||||||
pub fn bench_async_service<S>(c: &mut Criterion, srv: S, name: &str)
|
pub fn bench_async_service<S>(c: &mut Criterion, srv: S, name: &str)
|
||||||
where
|
where
|
||||||
S: Service<Request = (), Response = usize, Error = ()> + Clone + 'static,
|
S: Service<(), Response = usize, Error = ()> + Clone + 'static,
|
||||||
{
|
{
|
||||||
let mut rt = actix_rt::System::new("test");
|
let mut rt = actix_rt::System::new("test");
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@ impl Clone for SrvUC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Service for SrvUC {
|
impl Service<()> for SrvUC {
|
||||||
type Request = ();
|
|
||||||
type Response = usize;
|
type Response = usize;
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<Self::Response, ()>>;
|
type Future = Ready<Result<Self::Response, ()>>;
|
||||||
@ -50,8 +49,7 @@ impl Clone for SrvRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Service for SrvRC {
|
impl Service<()> for SrvRC {
|
||||||
type Request = ();
|
|
||||||
type Response = usize;
|
type Response = usize;
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<Self::Response, ()>>;
|
type Future = Ready<Result<Self::Response, ()>>;
|
||||||
@ -83,7 +81,7 @@ impl Service for SrvRC {
|
|||||||
/// async_service_direct time: [1.0908 us 1.1656 us 1.2613 us]
|
/// async_service_direct time: [1.0908 us 1.1656 us 1.2613 us]
|
||||||
pub fn bench_async_service<S>(c: &mut Criterion, srv: S, name: &str)
|
pub fn bench_async_service<S>(c: &mut Criterion, srv: S, name: &str)
|
||||||
where
|
where
|
||||||
S: Service<Request = (), Response = usize, Error = ()> + Clone + 'static,
|
S: Service<(), Response = usize, Error = ()> + Clone + 'static,
|
||||||
{
|
{
|
||||||
let mut rt = actix_rt::System::new("test");
|
let mut rt = actix_rt::System::new("test");
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
use std::{cell::RefCell, marker::PhantomData};
|
||||||
|
|
||||||
use super::{Service, ServiceFactory};
|
use super::{Service, ServiceFactory};
|
||||||
|
|
||||||
@ -10,34 +10,33 @@ use super::{Service, ServiceFactory};
|
|||||||
/// of another service which completes successfully.
|
/// of another service which completes successfully.
|
||||||
///
|
///
|
||||||
/// This is created by the `Pipeline::and_then` method.
|
/// This is created by the `Pipeline::and_then` method.
|
||||||
pub(crate) struct AndThenService<A, B>(Rc<RefCell<(A, B)>>);
|
pub(crate) struct AndThenService<A, B, Req>(Rc<RefCell<(A, B)>>, PhantomData<Req>);
|
||||||
|
|
||||||
impl<A, B> AndThenService<A, B> {
|
impl<A, B, Req> AndThenService<A, B, Req> {
|
||||||
/// Create new `AndThen` combinator
|
/// Create new `AndThen` combinator
|
||||||
pub(crate) fn new(a: A, b: B) -> Self
|
pub(crate) fn new(a: A, b: B) -> Self
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
Self(Rc::new(RefCell::new((a, b))))
|
Self(Rc::new(RefCell::new((a, b))), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for AndThenService<A, B> {
|
impl<A, B, Req> Clone for AndThenService<A, B, Req> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
AndThenService(self.0.clone())
|
AndThenService(self.0.clone(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Service for AndThenService<A, B>
|
impl<A, B, Req> Service<Req> for AndThenService<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
type Future = AndThenServiceResponse<A, B>;
|
type Future = AndThenServiceResponse<A, B, Req>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
let mut srv = self.0.borrow_mut();
|
let mut srv = self.0.borrow_mut();
|
||||||
@ -49,7 +48,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
AndThenServiceResponse {
|
AndThenServiceResponse {
|
||||||
state: State::A(self.0.borrow_mut().0.call(req), Some(self.0.clone())),
|
state: State::A(self.0.borrow_mut().0.call(req), Some(self.0.clone())),
|
||||||
}
|
}
|
||||||
@ -57,30 +56,30 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct AndThenServiceResponse<A, B>
|
pub(crate) struct AndThenServiceResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
state: State<A, B>,
|
state: State<A, B, Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = StateProj)]
|
#[pin_project::pin_project(project = StateProj)]
|
||||||
enum State<A, B>
|
enum State<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
A(#[pin] A::Future, Option<Rc<RefCell<(A, B)>>>),
|
A(#[pin] A::Future, Option<Rc<RefCell<(A, B)>>>),
|
||||||
B(#[pin] B::Future),
|
B(#[pin] B::Future),
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Future for AndThenServiceResponse<A, B>
|
impl<A, B, Req> Future for AndThenServiceResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = A::Response, Error = A::Error>,
|
B: Service<A::Response, Error = A::Error>,
|
||||||
{
|
{
|
||||||
type Output = Result<B::Response, A::Error>;
|
type Output = Result<B::Response, A::Error>;
|
||||||
|
|
||||||
@ -110,27 +109,28 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// `.and_then()` service factory combinator
|
/// `.and_then()` service factory combinator
|
||||||
pub(crate) struct AndThenServiceFactory<A, B>
|
pub(crate) struct AndThenServiceFactory<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
A::Config: Clone,
|
A::Config: Clone,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
A::Response,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = A::Response,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
inner: Rc<(A, B)>,
|
inner: Rc<(A, B)>,
|
||||||
|
_phantom: PhantomData<Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> AndThenServiceFactory<A, B>
|
impl<A, B, Req> AndThenServiceFactory<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
A::Config: Clone,
|
A::Config: Clone,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
A::Response,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = A::Response,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
@ -139,29 +139,29 @@ where
|
|||||||
pub(crate) fn new(a: A, b: B) -> Self {
|
pub(crate) fn new(a: A, b: B) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: Rc::new((a, b)),
|
inner: Rc::new((a, b)),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> ServiceFactory for AndThenServiceFactory<A, B>
|
impl<A, B, Req> ServiceFactory<Req> for AndThenServiceFactory<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
A::Config: Clone,
|
A::Config: Clone,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
A::Response,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = A::Response,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
|
|
||||||
type Config = A::Config;
|
type Config = A::Config;
|
||||||
type Service = AndThenService<A::Service, B::Service>;
|
type Service = AndThenService<A::Service, B::Service, Req>;
|
||||||
type InitError = A::InitError;
|
type InitError = A::InitError;
|
||||||
type Future = AndThenServiceFactoryResponse<A, B>;
|
type Future = AndThenServiceFactoryResponse<A, B, Req>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
||||||
let inner = &*self.inner;
|
let inner = &*self.inner;
|
||||||
@ -172,13 +172,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for AndThenServiceFactory<A, B>
|
impl<A, B, Req> Clone for AndThenServiceFactory<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
A::Config: Clone,
|
A::Config: Clone,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
A::Response,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = A::Response,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
@ -186,15 +186,16 @@ where
|
|||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: self.inner.clone(),
|
inner: self.inner.clone(),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct AndThenServiceFactoryResponse<A, B>
|
pub(crate) struct AndThenServiceFactoryResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<Request = A::Response>,
|
B: ServiceFactory<A::Response>,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
fut_a: A::Future,
|
fut_a: A::Future,
|
||||||
@ -205,10 +206,10 @@ where
|
|||||||
b: Option<B::Service>,
|
b: Option<B::Service>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> AndThenServiceFactoryResponse<A, B>
|
impl<A, B, Req> AndThenServiceFactoryResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<Request = A::Response>,
|
B: ServiceFactory<A::Response>,
|
||||||
{
|
{
|
||||||
fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
|
fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
|
||||||
AndThenServiceFactoryResponse {
|
AndThenServiceFactoryResponse {
|
||||||
@ -220,12 +221,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Future for AndThenServiceFactoryResponse<A, B>
|
impl<A, B, Req> Future for AndThenServiceFactoryResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<Request = A::Response, Error = A::Error, InitError = A::InitError>,
|
B: ServiceFactory<A::Response, Error = A::Error, InitError = A::InitError>,
|
||||||
{
|
{
|
||||||
type Output = Result<AndThenService<A::Service, B::Service>, A::InitError>;
|
type Output = Result<AndThenService<A::Service, B::Service, Req>, A::InitError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
@ -263,8 +264,7 @@ mod tests {
|
|||||||
|
|
||||||
struct Srv1(Rc<Cell<usize>>);
|
struct Srv1(Rc<Cell<usize>>);
|
||||||
|
|
||||||
impl Service for Srv1 {
|
impl Service<&'static str> for Srv1 {
|
||||||
type Request = &'static str;
|
|
||||||
type Response = &'static str;
|
type Response = &'static str;
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<Self::Response, ()>>;
|
type Future = Ready<Result<Self::Response, ()>>;
|
||||||
@ -282,8 +282,7 @@ mod tests {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Srv2(Rc<Cell<usize>>);
|
struct Srv2(Rc<Cell<usize>>);
|
||||||
|
|
||||||
impl Service for Srv2 {
|
impl Service<&'static str> for Srv2 {
|
||||||
type Request = &'static str;
|
|
||||||
type Response = (&'static str, &'static str);
|
type Response = (&'static str, &'static str);
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<Self::Response, ()>>;
|
type Future = Ready<Result<Self::Response, ()>>;
|
||||||
|
@ -8,66 +8,67 @@ use std::task::{Context, Poll};
|
|||||||
use crate::{Service, ServiceFactory};
|
use crate::{Service, ServiceFactory};
|
||||||
|
|
||||||
/// `Apply` service combinator
|
/// `Apply` service combinator
|
||||||
pub(crate) struct AndThenApplyFn<A, B, F, Fut, Res, Err>
|
pub(crate) struct AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: Service,
|
S1: Service<Req>,
|
||||||
B: Service,
|
S2: Service<In>,
|
||||||
F: FnMut(A::Response, &mut B) -> Fut,
|
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<S1::Error> + From<S2::Error>,
|
||||||
{
|
{
|
||||||
srv: Rc<RefCell<(A, B, F)>>,
|
svc: Rc<RefCell<(S1, S2, F)>>,
|
||||||
r: PhantomData<(Fut, Res, Err)>,
|
_phantom: PhantomData<(Fut, Req, In, Res, Err)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> AndThenApplyFn<A, B, F, Fut, Res, Err>
|
impl<S1, S2, F, Fut, Req, In, Res, Err> AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: Service,
|
S1: Service<Req>,
|
||||||
B: Service,
|
S2: Service<In>,
|
||||||
F: FnMut(A::Response, &mut B) -> Fut,
|
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<S1::Error> + From<S2::Error>,
|
||||||
{
|
{
|
||||||
/// Create new `Apply` combinator
|
/// Create new `Apply` combinator
|
||||||
pub(crate) fn new(a: A, b: B, f: F) -> Self {
|
pub(crate) fn new(a: S1, b: S2, wrap_fn: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
srv: Rc::new(RefCell::new((a, b, f))),
|
svc: Rc::new(RefCell::new((a, b, wrap_fn))),
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> Clone for AndThenApplyFn<A, B, F, Fut, Res, Err>
|
impl<S1, S2, F, Fut, Req, In, Res, Err> Clone
|
||||||
|
for AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: Service,
|
S1: Service<Req>,
|
||||||
B: Service,
|
S2: Service<In>,
|
||||||
F: FnMut(A::Response, &mut B) -> Fut,
|
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<S1::Error> + From<S2::Error>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
AndThenApplyFn {
|
AndThenApplyFn {
|
||||||
srv: self.srv.clone(),
|
svc: self.svc.clone(),
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> Service for AndThenApplyFn<A, B, F, Fut, Res, Err>
|
impl<S1, S2, F, Fut, Req, In, Res, Err> Service<Req>
|
||||||
|
for AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: Service,
|
S1: Service<Req>,
|
||||||
B: Service,
|
S2: Service<In>,
|
||||||
F: FnMut(A::Response, &mut B) -> Fut,
|
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<S1::Error> + From<S2::Error>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type Future = AndThenApplyFnFuture<A, B, F, Fut, Res, Err>;
|
type Future = AndThenApplyFnFuture<S1, S2, F, Fut, Req, In, Res, Err>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
let mut inner = self.srv.borrow_mut();
|
let mut inner = self.svc.borrow_mut();
|
||||||
let not_ready = inner.0.poll_ready(cx)?.is_pending();
|
let not_ready = inner.0.poll_ready(cx)?.is_pending();
|
||||||
if inner.1.poll_ready(cx)?.is_pending() || not_ready {
|
if inner.1.poll_ready(cx)?.is_pending() || not_ready {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
@ -76,50 +77,49 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
let fut = self.srv.borrow_mut().0.call(req);
|
let fut = self.svc.borrow_mut().0.call(req);
|
||||||
AndThenApplyFnFuture {
|
AndThenApplyFnFuture {
|
||||||
state: State::A(fut, Some(self.srv.clone())),
|
state: State::A(fut, Some(self.svc.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct AndThenApplyFnFuture<A, B, F, Fut, Res, Err>
|
pub(crate) struct AndThenApplyFnFuture<S1, S2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: Service,
|
S1: Service<Req>,
|
||||||
B: Service,
|
S2: Service<In>,
|
||||||
F: FnMut(A::Response, &mut B) -> Fut,
|
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error>,
|
Err: From<S1::Error> + From<S2::Error>,
|
||||||
Err: From<B::Error>,
|
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
state: State<A, B, F, Fut, Res, Err>,
|
state: State<S1, S2, F, Fut, Req, In, Res, Err>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = StateProj)]
|
#[pin_project::pin_project(project = StateProj)]
|
||||||
enum State<A, B, F, Fut, Res, Err>
|
enum State<S1, S2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: Service,
|
S1: Service<Req>,
|
||||||
B: Service,
|
S2: Service<In>,
|
||||||
F: FnMut(A::Response, &mut B) -> Fut,
|
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error>,
|
Err: From<S1::Error> + From<S2::Error>,
|
||||||
Err: From<B::Error>,
|
|
||||||
{
|
{
|
||||||
A(#[pin] A::Future, Option<Rc<RefCell<(A, B, F)>>>),
|
A(#[pin] S1::Future, Option<Rc<RefCell<(S1, S2, F)>>>),
|
||||||
B(#[pin] Fut),
|
B(#[pin] Fut),
|
||||||
Empty,
|
Empty(PhantomData<In>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> Future for AndThenApplyFnFuture<A, B, F, Fut, Res, Err>
|
impl<S1, S2, F, Fut, Req, In, Res, Err> Future
|
||||||
|
for AndThenApplyFnFuture<S1, S2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: Service,
|
S1: Service<Req>,
|
||||||
B: Service,
|
S2: Service<In>,
|
||||||
F: FnMut(A::Response, &mut B) -> Fut,
|
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<S1::Error> + From<S2::Error>,
|
||||||
{
|
{
|
||||||
type Output = Result<Res, Err>;
|
type Output = Result<Res, Err>;
|
||||||
|
|
||||||
@ -129,8 +129,8 @@ where
|
|||||||
match this.state.as_mut().project() {
|
match this.state.as_mut().project() {
|
||||||
StateProj::A(fut, b) => match fut.poll(cx)? {
|
StateProj::A(fut, b) => match fut.poll(cx)? {
|
||||||
Poll::Ready(res) => {
|
Poll::Ready(res) => {
|
||||||
let b = b.take().unwrap();
|
let b = Option::take(b).unwrap();
|
||||||
this.state.set(State::Empty);
|
this.state.set(State::Empty(PhantomData));
|
||||||
let (_, b, f) = &mut *b.borrow_mut();
|
let (_, b, f) = &mut *b.borrow_mut();
|
||||||
let fut = f(res, b);
|
let fut = f(res, b);
|
||||||
this.state.set(State::B(fut));
|
this.state.set(State::B(fut));
|
||||||
@ -139,10 +139,10 @@ where
|
|||||||
Poll::Pending => Poll::Pending,
|
Poll::Pending => Poll::Pending,
|
||||||
},
|
},
|
||||||
StateProj::B(fut) => fut.poll(cx).map(|r| {
|
StateProj::B(fut) => fut.poll(cx).map(|r| {
|
||||||
this.state.set(State::Empty);
|
this.state.set(State::Empty(PhantomData));
|
||||||
r
|
r
|
||||||
}),
|
}),
|
||||||
StateProj::Empty => {
|
StateProj::Empty(_) => {
|
||||||
panic!("future must not be polled after it returned `Poll::Ready`")
|
panic!("future must not be polled after it returned `Poll::Ready`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,119 +150,127 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// `AndThenApplyFn` service factory
|
/// `AndThenApplyFn` service factory
|
||||||
pub(crate) struct AndThenApplyFnFactory<A, B, F, Fut, Res, Err> {
|
pub(crate) struct AndThenApplyFnFactory<SF1, SF2, F, Fut, Req, In, Res, Err> {
|
||||||
srv: Rc<(A, B, F)>,
|
srv: Rc<(SF1, SF2, F)>,
|
||||||
r: PhantomData<(Fut, Res, Err)>,
|
_phantom: PhantomData<(Fut, Req, In, Res, Err)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> AndThenApplyFnFactory<A, B, F, Fut, Res, Err>
|
impl<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||||
|
AndThenApplyFnFactory<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
SF1: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<Config = A::Config, InitError = A::InitError>,
|
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<SF1::Error> + From<SF2::Error>,
|
||||||
{
|
{
|
||||||
/// Create new `ApplyNewService` new service instance
|
/// Create new `ApplyNewService` new service instance
|
||||||
pub(crate) fn new(a: A, b: B, f: F) -> Self {
|
pub(crate) fn new(a: SF1, b: SF2, wrap_fn: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
srv: Rc::new((a, b, f)),
|
srv: Rc::new((a, b, wrap_fn)),
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> Clone for AndThenApplyFnFactory<A, B, F, Fut, Res, Err> {
|
impl<SF1, SF2, F, Fut, Req, In, Res, Err> Clone
|
||||||
|
for AndThenApplyFnFactory<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||||
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
srv: self.srv.clone(),
|
srv: self.srv.clone(),
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> ServiceFactory for AndThenApplyFnFactory<A, B, F, Fut, Res, Err>
|
impl<SF1, SF2, F, Fut, Req, In, Res, Err> ServiceFactory<Req>
|
||||||
|
for AndThenApplyFnFactory<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
SF1: ServiceFactory<Req>,
|
||||||
A::Config: Clone,
|
SF1::Config: Clone,
|
||||||
B: ServiceFactory<Config = A::Config, InitError = A::InitError>,
|
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<SF1::Error> + From<SF2::Error>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type Service = AndThenApplyFn<A::Service, B::Service, F, Fut, Res, Err>;
|
type Service = AndThenApplyFn<SF1::Service, SF2::Service, F, Fut, Req, In, Res, Err>;
|
||||||
type Config = A::Config;
|
type Config = SF1::Config;
|
||||||
type InitError = A::InitError;
|
type InitError = SF1::InitError;
|
||||||
type Future = AndThenApplyFnFactoryResponse<A, B, F, Fut, Res, Err>;
|
type Future = AndThenApplyFnFactoryResponse<SF1, SF2, F, Fut, Req, In, Res, Err>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
fn new_service(&self, cfg: SF1::Config) -> Self::Future {
|
||||||
let srv = &*self.srv;
|
let srv = &*self.srv;
|
||||||
AndThenApplyFnFactoryResponse {
|
AndThenApplyFnFactoryResponse {
|
||||||
a: None,
|
s1: None,
|
||||||
b: None,
|
s2: None,
|
||||||
f: srv.2.clone(),
|
wrap_fn: srv.2.clone(),
|
||||||
fut_a: srv.0.new_service(cfg.clone()),
|
fut_s1: srv.0.new_service(cfg.clone()),
|
||||||
fut_b: srv.1.new_service(cfg),
|
fut_s2: srv.1.new_service(cfg),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct AndThenApplyFnFactoryResponse<A, B, F, Fut, Res, Err>
|
pub(crate) struct AndThenApplyFnFactoryResponse<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
SF1: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<Config = A::Config, InitError = A::InitError>,
|
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error>,
|
Err: From<SF1::Error>,
|
||||||
Err: From<B::Error>,
|
Err: From<SF2::Error>,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
fut_b: B::Future,
|
fut_s1: SF1::Future,
|
||||||
#[pin]
|
#[pin]
|
||||||
fut_a: A::Future,
|
fut_s2: SF2::Future,
|
||||||
f: F,
|
wrap_fn: F,
|
||||||
a: Option<A::Service>,
|
s1: Option<SF1::Service>,
|
||||||
b: Option<B::Service>,
|
s2: Option<SF2::Service>,
|
||||||
|
_phantom: PhantomData<In>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, F, Fut, Res, Err> Future for AndThenApplyFnFactoryResponse<A, B, F, Fut, Res, Err>
|
impl<SF1, SF2, F, Fut, Req, In, Res, Err> Future
|
||||||
|
for AndThenApplyFnFactoryResponse<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
SF1: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<Config = A::Config, InitError = A::InitError>,
|
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<A::Error> + From<B::Error>,
|
Err: From<SF1::Error> + From<SF2::Error>,
|
||||||
{
|
{
|
||||||
type Output =
|
type Output = Result<
|
||||||
Result<AndThenApplyFn<A::Service, B::Service, F, Fut, Res, Err>, A::InitError>;
|
AndThenApplyFn<SF1::Service, SF2::Service, F, Fut, Req, In, Res, Err>,
|
||||||
|
SF1::InitError,
|
||||||
|
>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
|
|
||||||
if this.a.is_none() {
|
if this.s1.is_none() {
|
||||||
if let Poll::Ready(service) = this.fut_a.poll(cx)? {
|
if let Poll::Ready(service) = this.fut_s1.poll(cx)? {
|
||||||
*this.a = Some(service);
|
*this.s1 = Some(service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.b.is_none() {
|
if this.s2.is_none() {
|
||||||
if let Poll::Ready(service) = this.fut_b.poll(cx)? {
|
if let Poll::Ready(service) = this.fut_s2.poll(cx)? {
|
||||||
*this.b = Some(service);
|
*this.s2 = Some(service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.a.is_some() && this.b.is_some() {
|
if this.s1.is_some() && this.s2.is_some() {
|
||||||
Poll::Ready(Ok(AndThenApplyFn {
|
Poll::Ready(Ok(AndThenApplyFn {
|
||||||
srv: Rc::new(RefCell::new((
|
svc: Rc::new(RefCell::new((
|
||||||
this.a.take().unwrap(),
|
Option::take(this.s1).unwrap(),
|
||||||
this.b.take().unwrap(),
|
Option::take(this.s2).unwrap(),
|
||||||
this.f.clone(),
|
this.wrap_fn.clone(),
|
||||||
))),
|
))),
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
@ -280,29 +288,29 @@ mod tests {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Srv;
|
struct Srv;
|
||||||
impl Service for Srv {
|
|
||||||
type Request = ();
|
impl Service<u8> for Srv {
|
||||||
type Response = ();
|
type Response = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<(), ()>>;
|
type Future = Ready<Result<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unit_arg)]
|
fn call(&mut self, req: u8) -> Self::Future {
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
let _ = req;
|
||||||
ok(req)
|
ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_service() {
|
async fn test_service() {
|
||||||
let mut srv = pipeline(ok).and_then_apply_fn(Srv, |req: &'static str, s| {
|
let mut srv = pipeline(ok).and_then_apply_fn(Srv, |req: &'static str, s| {
|
||||||
s.call(()).map_ok(move |res| (req, res))
|
s.call(1).map_ok(move |res| (req, res))
|
||||||
});
|
});
|
||||||
let res = lazy(|cx| srv.poll_ready(cx)).await;
|
let res = lazy(|cx| srv.poll_ready(cx)).await;
|
||||||
assert_eq!(res, Poll::Ready(Ok(())));
|
assert!(res.is_ready());
|
||||||
|
|
||||||
let res = srv.call("srv").await;
|
let res = srv.call("srv").await;
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
@ -313,11 +321,11 @@ mod tests {
|
|||||||
async fn test_service_factory() {
|
async fn test_service_factory() {
|
||||||
let new_srv = pipeline_factory(|| ok::<_, ()>(fn_service(ok))).and_then_apply_fn(
|
let new_srv = pipeline_factory(|| ok::<_, ()>(fn_service(ok))).and_then_apply_fn(
|
||||||
|| ok(Srv),
|
|| ok(Srv),
|
||||||
|req: &'static str, s| s.call(()).map_ok(move |res| (req, res)),
|
|req: &'static str, s| s.call(1).map_ok(move |res| (req, res)),
|
||||||
);
|
);
|
||||||
let mut srv = new_srv.new_service(()).await.unwrap();
|
let mut srv = new_srv.new_service(()).await.unwrap();
|
||||||
let res = lazy(|cx| srv.poll_ready(cx)).await;
|
let res = lazy(|cx| srv.poll_ready(cx)).await;
|
||||||
assert_eq!(res, Poll::Ready(Ok(())));
|
assert!(res.is_ready());
|
||||||
|
|
||||||
let res = srv.call("srv").await;
|
let res = srv.call("srv").await;
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
@ -1,203 +1,209 @@
|
|||||||
use std::future::Future;
|
use std::{
|
||||||
use std::marker::PhantomData;
|
future::Future,
|
||||||
use std::pin::Pin;
|
marker::PhantomData,
|
||||||
use std::task::{Context, Poll};
|
pin::Pin,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
|
use futures_util::ready;
|
||||||
|
|
||||||
use super::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
use super::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||||
|
|
||||||
/// Apply transform function to a service.
|
/// Apply transform function to a service.
|
||||||
pub fn apply_fn<T, F, R, In, Out, Err, U>(service: U, f: F) -> Apply<T, F, R, In, Out, Err>
|
///
|
||||||
|
/// The In and Out type params refer to the request and response types for the wrapped service.
|
||||||
|
pub fn apply_fn<I, S, F, Fut, Req, In, Res, Err>(
|
||||||
|
service: I,
|
||||||
|
wrap_fn: F,
|
||||||
|
) -> Apply<S, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: Service<Error = Err>,
|
I: IntoService<S, In>,
|
||||||
F: FnMut(In, &mut T) -> R,
|
S: Service<In, Error = Err>,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
F: FnMut(Req, &mut S) -> Fut,
|
||||||
U: IntoService<T>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
Apply::new(service.into_service(), f)
|
Apply::new(service.into_service(), wrap_fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Service factory that produces `apply_fn` service.
|
/// Service factory that produces `apply_fn` service.
|
||||||
pub fn apply_fn_factory<T, F, R, In, Out, Err, U>(
|
///
|
||||||
service: U,
|
/// The In and Out type params refer to the request and response types for the wrapped service.
|
||||||
|
pub fn apply_fn_factory<I, SF, F, Fut, Req, In, Res, Err>(
|
||||||
|
service: I,
|
||||||
f: F,
|
f: F,
|
||||||
) -> ApplyServiceFactory<T, F, R, In, Out, Err>
|
) -> ApplyFactory<SF, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Error = Err>,
|
I: IntoServiceFactory<SF, In>,
|
||||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
SF: ServiceFactory<In, Error = Err>,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||||
U: IntoServiceFactory<T>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
ApplyServiceFactory::new(service.into_factory(), f)
|
ApplyFactory::new(service.into_factory(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `Apply` service combinator
|
/// `Apply` service combinator.
|
||||||
pub struct Apply<T, F, R, In, Out, Err>
|
///
|
||||||
|
/// The In and Out type params refer to the request and response types for the wrapped service.
|
||||||
|
pub struct Apply<S, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: Service<Error = Err>,
|
S: Service<In, Error = Err>,
|
||||||
{
|
{
|
||||||
service: T,
|
service: S,
|
||||||
f: F,
|
wrap_fn: F,
|
||||||
r: PhantomData<(In, Out, R)>,
|
_phantom: PhantomData<(Req, In, Res, Err)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> Apply<T, F, R, In, Out, Err>
|
impl<S, F, Fut, Req, In, Res, Err> Apply<S, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: Service<Error = Err>,
|
S: Service<In, Error = Err>,
|
||||||
F: FnMut(In, &mut T) -> R,
|
F: FnMut(Req, &mut S) -> Fut,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
/// Create new `Apply` combinator
|
/// Create new `Apply` combinator
|
||||||
fn new(service: T, f: F) -> Self {
|
fn new(service: S, wrap_fn: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service,
|
service,
|
||||||
f,
|
wrap_fn,
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> Clone for Apply<T, F, R, In, Out, Err>
|
impl<S, F, Fut, Req, In, Res, Err> Clone for Apply<S, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: Service<Error = Err> + Clone,
|
S: Service<In, Error = Err> + Clone,
|
||||||
F: FnMut(In, &mut T) -> R + Clone,
|
F: FnMut(Req, &mut S) -> Fut + Clone,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Apply {
|
Apply {
|
||||||
service: self.service.clone(),
|
service: self.service.clone(),
|
||||||
f: self.f.clone(),
|
wrap_fn: self.wrap_fn.clone(),
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> Service for Apply<T, F, R, In, Out, Err>
|
impl<S, F, Fut, Req, In, Res, Err> Service<Req> for Apply<S, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: Service<Error = Err>,
|
S: Service<In, Error = Err>,
|
||||||
F: FnMut(In, &mut T) -> R,
|
F: FnMut(Req, &mut S) -> Fut,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
type Request = In;
|
type Response = Res;
|
||||||
type Response = Out;
|
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type Future = R;
|
type Future = Fut;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(futures_util::ready!(self.service.poll_ready(cx)))
|
Poll::Ready(ready!(self.service.poll_ready(cx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: In) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
(self.f)(req, &mut self.service)
|
(self.wrap_fn)(req, &mut self.service)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `apply()` service factory
|
/// `ApplyFactory` service factory combinator.
|
||||||
pub struct ApplyServiceFactory<T, F, R, In, Out, Err>
|
pub struct ApplyFactory<SF, F, Req, In, Res, Err> {
|
||||||
|
factory: SF,
|
||||||
|
wrap_fn: F,
|
||||||
|
_phantom: PhantomData<(Req, In, Res, Err)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SF, F, Fut, Req, In, Res, Err> ApplyFactory<SF, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Error = Err>,
|
SF: ServiceFactory<In, Error = Err>,
|
||||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
service: T,
|
/// Create new `ApplyFactory` new service instance
|
||||||
f: F,
|
fn new(factory: SF, wrap_fn: F) -> Self {
|
||||||
r: PhantomData<(R, In, Out)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> ApplyServiceFactory<T, F, R, In, Out, Err>
|
|
||||||
where
|
|
||||||
T: ServiceFactory<Error = Err>,
|
|
||||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
|
||||||
R: Future<Output = Result<Out, Err>>,
|
|
||||||
{
|
|
||||||
/// Create new `ApplyNewService` new service instance
|
|
||||||
fn new(service: T, f: F) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
f,
|
factory,
|
||||||
service,
|
wrap_fn,
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> Clone for ApplyServiceFactory<T, F, R, In, Out, Err>
|
impl<SF, F, Fut, Req, In, Res, Err> Clone for ApplyFactory<SF, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Error = Err> + Clone,
|
SF: ServiceFactory<In, Error = Err> + Clone,
|
||||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service: self.service.clone(),
|
factory: self.factory.clone(),
|
||||||
f: self.f.clone(),
|
wrap_fn: self.wrap_fn.clone(),
|
||||||
r: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> ServiceFactory for ApplyServiceFactory<T, F, R, In, Out, Err>
|
impl<SF, F, Fut, Req, In, Res, Err> ServiceFactory<Req>
|
||||||
|
for ApplyFactory<SF, F, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Error = Err>,
|
SF: ServiceFactory<In, Error = Err>,
|
||||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
type Request = In;
|
type Response = Res;
|
||||||
type Response = Out;
|
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
|
|
||||||
type Config = T::Config;
|
type Config = SF::Config;
|
||||||
type Service = Apply<T::Service, F, R, In, Out, Err>;
|
type Service = Apply<SF::Service, F, Req, In, Res, Err>;
|
||||||
type InitError = T::InitError;
|
type InitError = SF::InitError;
|
||||||
type Future = ApplyServiceFactoryResponse<T, F, R, In, Out, Err>;
|
type Future = ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: T::Config) -> Self::Future {
|
fn new_service(&self, cfg: SF::Config) -> Self::Future {
|
||||||
ApplyServiceFactoryResponse::new(self.service.new_service(cfg), self.f.clone())
|
let svc = self.factory.new_service(cfg);
|
||||||
|
ApplyServiceFactoryResponse::new(svc, self.wrap_fn.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct ApplyServiceFactoryResponse<T, F, R, In, Out, Err>
|
pub struct ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Error = Err>,
|
SF: ServiceFactory<In, Error = Err>,
|
||||||
F: FnMut(In, &mut T::Service) -> R,
|
F: FnMut(Req, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: T::Future,
|
fut: SF::Future,
|
||||||
f: Option<F>,
|
wrap_fn: Option<F>,
|
||||||
r: PhantomData<(In, Out)>,
|
_phantom: PhantomData<(Req, Res)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> ApplyServiceFactoryResponse<T, F, R, In, Out, Err>
|
impl<SF, F, Fut, Req, In, Res, Err> ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Error = Err>,
|
SF: ServiceFactory<In, Error = Err>,
|
||||||
F: FnMut(In, &mut T::Service) -> R,
|
F: FnMut(Req, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
fn new(fut: T::Future, f: F) -> Self {
|
fn new(fut: SF::Future, wrap_fn: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
f: Some(f),
|
|
||||||
fut,
|
fut,
|
||||||
r: PhantomData,
|
wrap_fn: Some(wrap_fn),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, R, In, Out, Err> Future for ApplyServiceFactoryResponse<T, F, R, In, Out, Err>
|
impl<SF, F, Fut, Req, In, Res, Err> Future
|
||||||
|
for ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Error = Err>,
|
SF: ServiceFactory<In, Error = Err>,
|
||||||
F: FnMut(In, &mut T::Service) -> R,
|
F: FnMut(Req, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<Out, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
type Output = Result<Apply<T::Service, F, R, In, Out, Err>, T::InitError>;
|
type Output = Result<Apply<SF::Service, F, Req, In, Res, Err>, SF::InitError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
|
|
||||||
if let Poll::Ready(svc) = this.fut.poll(cx)? {
|
let svc = ready!(this.fut.poll(cx))?;
|
||||||
Poll::Ready(Ok(Apply::new(svc, this.f.take().unwrap())))
|
Poll::Ready(Ok(Apply::new(svc, Option::take(this.wrap_fn).unwrap())))
|
||||||
} else {
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,8 +219,7 @@ mod tests {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Srv;
|
struct Srv;
|
||||||
|
|
||||||
impl Service for Srv {
|
impl Service<()> for Srv {
|
||||||
type Request = ();
|
|
||||||
type Response = ();
|
type Response = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<(), ()>>;
|
type Future = Ready<Result<(), ()>>;
|
||||||
|
@ -7,152 +7,152 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
use crate::{Service, ServiceFactory};
|
use crate::{Service, ServiceFactory};
|
||||||
|
|
||||||
/// Convert `Fn(Config, &mut Service1) -> Future<Service2>` fn to a service factory
|
/// Convert `Fn(Config, &mut Service1) -> Future<Service2>` fn to a service factory.
|
||||||
pub fn apply_cfg<F, C, T, R, S, E>(
|
pub fn apply_cfg<S1, Req, F, Cfg, Fut, S2, Err>(
|
||||||
srv: T,
|
srv: S1,
|
||||||
f: F,
|
f: F,
|
||||||
) -> impl ServiceFactory<
|
) -> impl ServiceFactory<
|
||||||
Config = C,
|
Req,
|
||||||
Request = S::Request,
|
Config = Cfg,
|
||||||
Response = S::Response,
|
Response = S2::Response,
|
||||||
Error = S::Error,
|
Error = S2::Error,
|
||||||
Service = S,
|
Service = S2,
|
||||||
InitError = E,
|
InitError = Err,
|
||||||
Future = R,
|
Future = Fut,
|
||||||
> + Clone
|
> + Clone
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T) -> R,
|
S1: Service<Req>,
|
||||||
T: Service,
|
F: FnMut(Cfg, &mut S1) -> Fut,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<S2, Err>>,
|
||||||
S: Service,
|
S2: Service<Req>,
|
||||||
{
|
{
|
||||||
ApplyConfigService {
|
ApplyConfigService {
|
||||||
srv: Rc::new(RefCell::new((srv, f))),
|
srv: Rc::new(RefCell::new((srv, f))),
|
||||||
_t: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert `Fn(Config, &mut Service1) -> Future<Service2>` fn to a service factory
|
/// Convert `Fn(Config, &mut ServiceFactory1) -> Future<ServiceFactory2>` fn to a service factory.
|
||||||
///
|
///
|
||||||
/// Service1 get constructed from `T` factory.
|
/// Service1 get constructed from `T` factory.
|
||||||
pub fn apply_cfg_factory<F, C, T, R, S>(
|
pub fn apply_cfg_factory<SF, Req, F, Cfg, Fut, S>(
|
||||||
factory: T,
|
factory: SF,
|
||||||
f: F,
|
f: F,
|
||||||
) -> impl ServiceFactory<
|
) -> impl ServiceFactory<
|
||||||
Config = C,
|
Req,
|
||||||
Request = S::Request,
|
Config = Cfg,
|
||||||
Response = S::Response,
|
Response = S::Response,
|
||||||
Error = S::Error,
|
Error = S::Error,
|
||||||
Service = S,
|
Service = S,
|
||||||
InitError = T::InitError,
|
InitError = SF::InitError,
|
||||||
> + Clone
|
> + Clone
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T::Service) -> R,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
T: ServiceFactory<Config = ()>,
|
F: FnMut(Cfg, &mut SF::Service) -> Fut,
|
||||||
T::InitError: From<T::Error>,
|
SF::InitError: From<SF::Error>,
|
||||||
R: Future<Output = Result<S, T::InitError>>,
|
Fut: Future<Output = Result<S, SF::InitError>>,
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
ApplyConfigServiceFactory {
|
ApplyConfigServiceFactory {
|
||||||
srv: Rc::new(RefCell::new((factory, f))),
|
srv: Rc::new(RefCell::new((factory, f))),
|
||||||
_t: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert `Fn(Config, &mut Server) -> Future<Service>` fn to NewService\
|
/// Convert `Fn(Config, &mut Server) -> Future<Service>` fn to NewService\
|
||||||
struct ApplyConfigService<F, C, T, R, S, E>
|
struct ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T) -> R,
|
S1: Service<Req>,
|
||||||
T: Service,
|
F: FnMut(Cfg, &mut S1) -> Fut,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<S2, Err>>,
|
||||||
S: Service,
|
S2: Service<Req>,
|
||||||
{
|
{
|
||||||
srv: Rc<RefCell<(T, F)>>,
|
srv: Rc<RefCell<(S1, F)>>,
|
||||||
_t: PhantomData<(C, R, S)>,
|
_phantom: PhantomData<(Cfg, Req, Fut, S2)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, T, R, S, E> Clone for ApplyConfigService<F, C, T, R, S, E>
|
impl<S1, Req, F, Cfg, Fut, S2, Err> Clone for ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T) -> R,
|
S1: Service<Req>,
|
||||||
T: Service,
|
F: FnMut(Cfg, &mut S1) -> Fut,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<S2, Err>>,
|
||||||
S: Service,
|
S2: Service<Req>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
ApplyConfigService {
|
ApplyConfigService {
|
||||||
srv: self.srv.clone(),
|
srv: self.srv.clone(),
|
||||||
_t: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, T, R, S, E> ServiceFactory for ApplyConfigService<F, C, T, R, S, E>
|
impl<S1, Req, F, Cfg, Fut, S2, Err> ServiceFactory<Req>
|
||||||
|
for ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T) -> R,
|
S1: Service<Req>,
|
||||||
T: Service,
|
F: FnMut(Cfg, &mut S1) -> Fut,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<S2, Err>>,
|
||||||
S: Service,
|
S2: Service<Req>,
|
||||||
{
|
{
|
||||||
type Config = C;
|
type Config = Cfg;
|
||||||
type Request = S::Request;
|
type Response = S2::Response;
|
||||||
type Response = S::Response;
|
type Error = S2::Error;
|
||||||
type Error = S::Error;
|
type Service = S2;
|
||||||
type Service = S;
|
|
||||||
|
|
||||||
type InitError = E;
|
type InitError = Err;
|
||||||
type Future = R;
|
type Future = Fut;
|
||||||
|
|
||||||
fn new_service(&self, cfg: C) -> Self::Future {
|
fn new_service(&self, cfg: Cfg) -> Self::Future {
|
||||||
let (t, f) = &mut *self.srv.borrow_mut();
|
let (t, f) = &mut *self.srv.borrow_mut();
|
||||||
f(cfg, t)
|
f(cfg, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService
|
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService
|
||||||
struct ApplyConfigServiceFactory<F, C, T, R, S>
|
struct ApplyConfigServiceFactory<SF, Req, F, Cfg, Fut, S>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T::Service) -> R,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
T: ServiceFactory<Config = ()>,
|
F: FnMut(Cfg, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<S, T::InitError>>,
|
Fut: Future<Output = Result<S, SF::InitError>>,
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
srv: Rc<RefCell<(T, F)>>,
|
srv: Rc<RefCell<(SF, F)>>,
|
||||||
_t: PhantomData<(C, R, S)>,
|
_phantom: PhantomData<(Cfg, Req, Fut, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, T, R, S> Clone for ApplyConfigServiceFactory<F, C, T, R, S>
|
impl<SF, Req, F, Cfg, Fut, S> Clone for ApplyConfigServiceFactory<SF, Req, F, Cfg, Fut, S>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T::Service) -> R,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
T: ServiceFactory<Config = ()>,
|
F: FnMut(Cfg, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<S, T::InitError>>,
|
Fut: Future<Output = Result<S, SF::InitError>>,
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
srv: self.srv.clone(),
|
srv: self.srv.clone(),
|
||||||
_t: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, T, R, S> ServiceFactory for ApplyConfigServiceFactory<F, C, T, R, S>
|
impl<SF, Req, F, Cfg, Fut, S> ServiceFactory<Req>
|
||||||
|
for ApplyConfigServiceFactory<SF, Req, F, Cfg, Fut, S>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T::Service) -> R,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
T: ServiceFactory<Config = ()>,
|
SF::InitError: From<SF::Error>,
|
||||||
T::InitError: From<T::Error>,
|
F: FnMut(Cfg, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<S, T::InitError>>,
|
Fut: Future<Output = Result<S, SF::InitError>>,
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
type Config = C;
|
type Config = Cfg;
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Service = S;
|
type Service = S;
|
||||||
|
|
||||||
type InitError = T::InitError;
|
type InitError = SF::InitError;
|
||||||
type Future = ApplyConfigServiceFactoryResponse<F, C, T, R, S>;
|
type Future = ApplyConfigServiceFactoryResponse<SF, Req, F, Cfg, Fut, S>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: C) -> Self::Future {
|
fn new_service(&self, cfg: Cfg) -> Self::Future {
|
||||||
ApplyConfigServiceFactoryResponse {
|
ApplyConfigServiceFactoryResponse {
|
||||||
cfg: Some(cfg),
|
cfg: Some(cfg),
|
||||||
store: self.srv.clone(),
|
store: self.srv.clone(),
|
||||||
@ -162,42 +162,43 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
struct ApplyConfigServiceFactoryResponse<F, C, T, R, S>
|
struct ApplyConfigServiceFactoryResponse<SF, Req, F, Cfg, Fut, S>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T::Service) -> R,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
T: ServiceFactory<Config = ()>,
|
SF::InitError: From<SF::Error>,
|
||||||
T::InitError: From<T::Error>,
|
F: FnMut(Cfg, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<S, T::InitError>>,
|
Fut: Future<Output = Result<S, SF::InitError>>,
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
cfg: Option<C>,
|
cfg: Option<Cfg>,
|
||||||
store: Rc<RefCell<(T, F)>>,
|
store: Rc<RefCell<(SF, F)>>,
|
||||||
#[pin]
|
#[pin]
|
||||||
state: State<T, R, S>,
|
state: State<SF, Fut, S, Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = StateProj)]
|
#[pin_project::pin_project(project = StateProj)]
|
||||||
enum State<T, R, S>
|
enum State<SF, Fut, S, Req>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Config = ()>,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
T::InitError: From<T::Error>,
|
SF::InitError: From<SF::Error>,
|
||||||
R: Future<Output = Result<S, T::InitError>>,
|
Fut: Future<Output = Result<S, SF::InitError>>,
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
A(#[pin] T::Future),
|
A(#[pin] SF::Future),
|
||||||
B(T::Service),
|
B(SF::Service),
|
||||||
C(#[pin] R),
|
C(#[pin] Fut),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, T, R, S> Future for ApplyConfigServiceFactoryResponse<F, C, T, R, S>
|
impl<SF, Req, F, Cfg, Fut, S> Future
|
||||||
|
for ApplyConfigServiceFactoryResponse<SF, Req, F, Cfg, Fut, S>
|
||||||
where
|
where
|
||||||
F: FnMut(C, &mut T::Service) -> R,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
T: ServiceFactory<Config = ()>,
|
SF::InitError: From<SF::Error>,
|
||||||
T::InitError: From<T::Error>,
|
F: FnMut(Cfg, &mut SF::Service) -> Fut,
|
||||||
R: Future<Output = Result<S, T::InitError>>,
|
Fut: Future<Output = Result<S, SF::InitError>>,
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
type Output = Result<S, T::InitError>;
|
type Output = Result<S, SF::InitError>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let mut this = self.as_mut().project();
|
let mut this = self.as_mut().project();
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
use std::{future::Future, marker::PhantomData};
|
||||||
|
|
||||||
use futures_util::future::FutureExt;
|
use futures_util::future::FutureExt;
|
||||||
|
|
||||||
use crate::{Service, ServiceFactory};
|
use crate::{Service, ServiceFactory};
|
||||||
|
|
||||||
pub type BoxFuture<I, E> = Pin<Box<dyn Future<Output = Result<I, E>>>>;
|
pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
|
||||||
|
|
||||||
pub type BoxService<Req, Res, Err> =
|
pub type BoxService<Req, Res, Err> =
|
||||||
Box<dyn Service<Request = Req, Response = Res, Error = Err, Future = BoxFuture<Res, Err>>>;
|
Box<dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>>;
|
||||||
|
|
||||||
pub struct BoxServiceFactory<C, Req, Res, Err, InitErr>(Inner<C, Req, Res, Err, InitErr>);
|
pub struct BoxServiceFactory<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>);
|
||||||
|
|
||||||
/// Create boxed service factory
|
/// Create boxed service factory
|
||||||
pub fn factory<T>(
|
pub fn factory<SF, Req>(
|
||||||
factory: T,
|
factory: SF,
|
||||||
) -> BoxServiceFactory<T::Config, T::Request, T::Response, T::Error, T::InitError>
|
) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError>
|
||||||
where
|
where
|
||||||
T: ServiceFactory + 'static,
|
SF: ServiceFactory<Req> + 'static,
|
||||||
T::Request: 'static,
|
Req: 'static,
|
||||||
T::Response: 'static,
|
SF::Response: 'static,
|
||||||
T::Service: 'static,
|
SF::Service: 'static,
|
||||||
T::Future: 'static,
|
SF::Future: 'static,
|
||||||
T::Error: 'static,
|
SF::Error: 'static,
|
||||||
T::InitError: 'static,
|
SF::InitError: 'static,
|
||||||
{
|
{
|
||||||
BoxServiceFactory(Box::new(FactoryWrapper {
|
BoxServiceFactory(Box::new(FactoryWrapper {
|
||||||
factory,
|
factory,
|
||||||
@ -33,78 +33,75 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create boxed service
|
/// Create boxed service
|
||||||
pub fn service<T>(service: T) -> BoxService<T::Request, T::Response, T::Error>
|
pub fn service<S, Req>(service: S) -> BoxService<Req, S::Response, S::Error>
|
||||||
where
|
where
|
||||||
T: Service + 'static,
|
S: Service<Req> + 'static,
|
||||||
T::Future: 'static,
|
Req: 'static,
|
||||||
|
S::Future: 'static,
|
||||||
{
|
{
|
||||||
Box::new(ServiceWrapper(service))
|
Box::new(ServiceWrapper(service, PhantomData))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Inner<C, Req, Res, Err, InitErr> = Box<
|
type Inner<C, Req, Res, Err, InitErr> = Box<
|
||||||
dyn ServiceFactory<
|
dyn ServiceFactory<
|
||||||
|
Req,
|
||||||
Config = C,
|
Config = C,
|
||||||
Request = Req,
|
|
||||||
Response = Res,
|
Response = Res,
|
||||||
Error = Err,
|
Error = Err,
|
||||||
InitError = InitErr,
|
InitError = InitErr,
|
||||||
Service = BoxService<Req, Res, Err>,
|
Service = BoxService<Req, Res, Err>,
|
||||||
Future = BoxFuture<BoxService<Req, Res, Err>, InitErr>,
|
Future = BoxFuture<Result<BoxService<Req, Res, Err>, InitErr>>,
|
||||||
>,
|
>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
impl<C, Req, Res, Err, InitErr> ServiceFactory for BoxServiceFactory<C, Req, Res, Err, InitErr>
|
impl<C, Req, Res, Err, InitErr> ServiceFactory<Req>
|
||||||
|
for BoxServiceFactory<C, Req, Res, Err, InitErr>
|
||||||
where
|
where
|
||||||
Req: 'static,
|
Req: 'static,
|
||||||
Res: 'static,
|
Res: 'static,
|
||||||
Err: 'static,
|
Err: 'static,
|
||||||
InitErr: 'static,
|
InitErr: 'static,
|
||||||
{
|
{
|
||||||
type Request = Req;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type InitError = InitErr;
|
type InitError = InitErr;
|
||||||
type Config = C;
|
type Config = C;
|
||||||
type Service = BoxService<Req, Res, Err>;
|
type Service = BoxService<Req, Res, Err>;
|
||||||
|
|
||||||
type Future = BoxFuture<Self::Service, InitErr>;
|
type Future = BoxFuture<Result<Self::Service, InitErr>>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: C) -> Self::Future {
|
fn new_service(&self, cfg: C) -> Self::Future {
|
||||||
self.0.new_service(cfg)
|
self.0.new_service(cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FactoryWrapper<C, T: ServiceFactory> {
|
struct FactoryWrapper<SF, Req, C>
|
||||||
factory: T,
|
where
|
||||||
_t: std::marker::PhantomData<C>,
|
SF: ServiceFactory<Req>,
|
||||||
|
{
|
||||||
|
factory: SF,
|
||||||
|
_t: PhantomData<(C, Req)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, T, Req, Res, Err, InitErr> ServiceFactory for FactoryWrapper<C, T>
|
impl<SF, Req, Cfg, Res, Err, InitErr> ServiceFactory<Req> for FactoryWrapper<SF, Req, Cfg>
|
||||||
where
|
where
|
||||||
Req: 'static,
|
Req: 'static,
|
||||||
Res: 'static,
|
Res: 'static,
|
||||||
Err: 'static,
|
Err: 'static,
|
||||||
InitErr: 'static,
|
InitErr: 'static,
|
||||||
T: ServiceFactory<
|
SF: ServiceFactory<Req, Config = Cfg, Response = Res, Error = Err, InitError = InitErr>,
|
||||||
Config = C,
|
SF::Future: 'static,
|
||||||
Request = Req,
|
SF::Service: 'static,
|
||||||
Response = Res,
|
<SF::Service as Service<Req>>::Future: 'static,
|
||||||
Error = Err,
|
|
||||||
InitError = InitErr,
|
|
||||||
>,
|
|
||||||
T::Future: 'static,
|
|
||||||
T::Service: 'static,
|
|
||||||
<T::Service as Service>::Future: 'static,
|
|
||||||
{
|
{
|
||||||
type Request = Req;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type InitError = InitErr;
|
type InitError = InitErr;
|
||||||
type Config = C;
|
type Config = Cfg;
|
||||||
type Service = BoxService<Req, Res, Err>;
|
type Service = BoxService<Req, Res, Err>;
|
||||||
type Future = BoxFuture<Self::Service, Self::InitError>;
|
type Future = BoxFuture<Result<Self::Service, Self::InitError>>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: C) -> Self::Future {
|
fn new_service(&self, cfg: Cfg) -> Self::Future {
|
||||||
Box::pin(
|
Box::pin(
|
||||||
self.factory
|
self.factory
|
||||||
.new_service(cfg)
|
.new_service(cfg)
|
||||||
@ -113,33 +110,33 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ServiceWrapper<T: Service>(T);
|
struct ServiceWrapper<S: Service<Req>, Req>(S, PhantomData<Req>);
|
||||||
|
|
||||||
impl<T> ServiceWrapper<T>
|
impl<S, Req> ServiceWrapper<S, Req>
|
||||||
where
|
where
|
||||||
T: Service + 'static,
|
S: Service<Req> + 'static,
|
||||||
T::Future: 'static,
|
Req: 'static,
|
||||||
|
S::Future: 'static,
|
||||||
{
|
{
|
||||||
fn boxed(service: T) -> BoxService<T::Request, T::Response, T::Error> {
|
fn boxed(service: S) -> BoxService<Req, S::Response, S::Error> {
|
||||||
Box::new(ServiceWrapper(service))
|
Box::new(ServiceWrapper(service, PhantomData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Req, Res, Err> Service for ServiceWrapper<T>
|
impl<S, Req, Res, Err> Service<Req> for ServiceWrapper<S, Req>
|
||||||
where
|
where
|
||||||
T: Service<Request = Req, Response = Res, Error = Err>,
|
S: Service<Req, Response = Res, Error = Err>,
|
||||||
T::Future: 'static,
|
S::Future: 'static,
|
||||||
{
|
{
|
||||||
type Request = Req;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type Future = BoxFuture<Res, Err>;
|
type Future = BoxFuture<Result<Res, Err>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.0.poll_ready(ctx)
|
self.0.poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
Box::pin(self.0.call(req))
|
Box::pin(self.0.call(req))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,9 +53,11 @@ where
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn fn_factory<F, Cfg, Srv, Fut, Err>(f: F) -> FnServiceNoConfig<F, Cfg, Srv, Fut, Err>
|
pub fn fn_factory<F, Cfg, Srv, Req, Fut, Err>(
|
||||||
|
f: F,
|
||||||
|
) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||||
where
|
where
|
||||||
Srv: Service,
|
Srv: Service<Req>,
|
||||||
F: Fn() -> Fut,
|
F: Fn() -> Fut,
|
||||||
Fut: Future<Output = Result<Srv, Err>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
{
|
{
|
||||||
@ -92,13 +94,13 @@ where
|
|||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn fn_factory_with_config<F, Fut, Cfg, Srv, Err>(
|
pub fn fn_factory_with_config<F, Fut, Cfg, Srv, Req, Err>(
|
||||||
f: F,
|
f: F,
|
||||||
) -> FnServiceConfig<F, Fut, Cfg, Srv, Err>
|
) -> FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||||
where
|
where
|
||||||
F: Fn(Cfg) -> Fut,
|
F: Fn(Cfg) -> Fut,
|
||||||
Fut: Future<Output = Result<Srv, Err>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
Srv: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
FnServiceConfig::new(f)
|
FnServiceConfig::new(f)
|
||||||
}
|
}
|
||||||
@ -132,12 +134,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Req, Res, Err> Service for FnService<F, Fut, Req, Res, Err>
|
impl<F, Fut, Req, Res, Err> Service<Req> for FnService<F, Fut, Req, Res, Err>
|
||||||
where
|
where
|
||||||
F: FnMut(Req) -> Fut,
|
F: FnMut(Req) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
type Request = Req;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type Future = Fut;
|
type Future = Fut;
|
||||||
@ -151,7 +152,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Req, Res, Err> IntoService<FnService<F, Fut, Req, Res, Err>> for F
|
impl<F, Fut, Req, Res, Err> IntoService<FnService<F, Fut, Req, Res, Err>, Req> for F
|
||||||
where
|
where
|
||||||
F: FnMut(Req) -> Fut,
|
F: FnMut(Req) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
@ -190,12 +191,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Req, Res, Err> Service for FnServiceFactory<F, Fut, Req, Res, Err, ()>
|
impl<F, Fut, Req, Res, Err> Service<Req> for FnServiceFactory<F, Fut, Req, Res, Err, ()>
|
||||||
where
|
where
|
||||||
F: FnMut(Req) -> Fut + Clone,
|
F: FnMut(Req) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
type Request = Req;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
type Future = Fut;
|
type Future = Fut;
|
||||||
@ -204,17 +204,17 @@ where
|
|||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
(self.f)(req)
|
(self.f)(req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Req, Res, Err, Cfg> ServiceFactory for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
|
impl<F, Fut, Req, Res, Err, Cfg> ServiceFactory<Req>
|
||||||
|
for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
|
||||||
where
|
where
|
||||||
F: FnMut(Req) -> Fut + Clone,
|
F: FnMut(Req) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
{
|
{
|
||||||
type Request = Req;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = Err;
|
type Error = Err;
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Req, Res, Err, Cfg>
|
impl<F, Fut, Req, Res, Err, Cfg>
|
||||||
IntoServiceFactory<FnServiceFactory<F, Fut, Req, Res, Err, Cfg>> for F
|
IntoServiceFactory<FnServiceFactory<F, Fut, Req, Res, Err, Cfg>, Req> for F
|
||||||
where
|
where
|
||||||
F: Fn(Req) -> Fut + Clone,
|
F: Fn(Req) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
@ -240,32 +240,32 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService
|
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService
|
||||||
pub struct FnServiceConfig<F, Fut, Cfg, Srv, Err>
|
pub struct FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||||
where
|
where
|
||||||
F: Fn(Cfg) -> Fut,
|
F: Fn(Cfg) -> Fut,
|
||||||
Fut: Future<Output = Result<Srv, Err>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
Srv: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
f: F,
|
f: F,
|
||||||
_t: PhantomData<(Fut, Cfg, Srv, Err)>,
|
_t: PhantomData<(Fut, Cfg, Req, Srv, Err)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Cfg, Srv, Err> FnServiceConfig<F, Fut, Cfg, Srv, Err>
|
impl<F, Fut, Cfg, Srv, Req, Err> FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||||
where
|
where
|
||||||
F: Fn(Cfg) -> Fut,
|
F: Fn(Cfg) -> Fut,
|
||||||
Fut: Future<Output = Result<Srv, Err>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
Srv: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
fn new(f: F) -> Self {
|
fn new(f: F) -> Self {
|
||||||
FnServiceConfig { f, _t: PhantomData }
|
FnServiceConfig { f, _t: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Cfg, Srv, Err> Clone for FnServiceConfig<F, Fut, Cfg, Srv, Err>
|
impl<F, Fut, Cfg, Srv, Req, Err> Clone for FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||||
where
|
where
|
||||||
F: Fn(Cfg) -> Fut + Clone,
|
F: Fn(Cfg) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Srv, Err>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
Srv: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
FnServiceConfig {
|
FnServiceConfig {
|
||||||
@ -275,13 +275,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, Fut, Cfg, Srv, Err> ServiceFactory for FnServiceConfig<F, Fut, Cfg, Srv, Err>
|
impl<F, Fut, Cfg, Srv, Req, Err> ServiceFactory<Req>
|
||||||
|
for FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||||
where
|
where
|
||||||
F: Fn(Cfg) -> Fut,
|
F: Fn(Cfg) -> Fut,
|
||||||
Fut: Future<Output = Result<Srv, Err>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
Srv: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
type Request = Srv::Request;
|
|
||||||
type Response = Srv::Response;
|
type Response = Srv::Response;
|
||||||
type Error = Srv::Error;
|
type Error = Srv::Error;
|
||||||
|
|
||||||
@ -296,64 +296,65 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Converter for `Fn() -> Future<Service>` fn
|
/// Converter for `Fn() -> Future<Service>` fn
|
||||||
pub struct FnServiceNoConfig<F, C, S, R, E>
|
pub struct FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||||
where
|
where
|
||||||
F: Fn() -> R,
|
F: Fn() -> Fut,
|
||||||
S: Service,
|
Srv: Service<Req>,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
{
|
{
|
||||||
f: F,
|
f: F,
|
||||||
_t: PhantomData<C>,
|
_t: PhantomData<(Cfg, Req)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, S, R, E> FnServiceNoConfig<F, C, S, R, E>
|
impl<F, Cfg, Srv, Req, Fut, Err> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||||
where
|
where
|
||||||
F: Fn() -> R,
|
F: Fn() -> Fut,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
S: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
fn new(f: F) -> Self {
|
fn new(f: F) -> Self {
|
||||||
Self { f, _t: PhantomData }
|
Self { f, _t: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, S, R, E> ServiceFactory for FnServiceNoConfig<F, C, S, R, E>
|
impl<F, Cfg, Srv, Req, Fut, Err> ServiceFactory<Req>
|
||||||
|
for FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||||
where
|
where
|
||||||
F: Fn() -> R,
|
F: Fn() -> Fut,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
S: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
type Response = Srv::Response;
|
||||||
type Response = S::Response;
|
type Error = Srv::Error;
|
||||||
type Error = S::Error;
|
type Service = Srv;
|
||||||
type Service = S;
|
type Config = Cfg;
|
||||||
type Config = C;
|
type InitError = Err;
|
||||||
type InitError = E;
|
type Future = Fut;
|
||||||
type Future = R;
|
|
||||||
|
|
||||||
fn new_service(&self, _: C) -> Self::Future {
|
fn new_service(&self, _: Cfg) -> Self::Future {
|
||||||
(self.f)()
|
(self.f)()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, S, R, E> Clone for FnServiceNoConfig<F, C, S, R, E>
|
impl<F, Cfg, Srv, Req, Fut, Err> Clone for FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||||
where
|
where
|
||||||
F: Fn() -> R + Clone,
|
F: Fn() -> Fut + Clone,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
S: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self::new(self.f.clone())
|
Self::new(self.f.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, C, S, R, E> IntoServiceFactory<FnServiceNoConfig<F, C, S, R, E>> for F
|
impl<F, Cfg, Srv, Req, Fut, Err>
|
||||||
|
IntoServiceFactory<FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>, Req> for F
|
||||||
where
|
where
|
||||||
F: Fn() -> R,
|
F: Fn() -> Fut,
|
||||||
R: Future<Output = Result<S, E>>,
|
Fut: Future<Output = Result<Srv, Err>>,
|
||||||
S: Service,
|
Srv: Service<Req>,
|
||||||
{
|
{
|
||||||
fn into_factory(self) -> FnServiceNoConfig<F, C, S, R, E> {
|
fn into_factory(self) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err> {
|
||||||
FnServiceNoConfig::new(self)
|
FnServiceNoConfig::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,14 +72,11 @@ pub use self::transform::{apply, Transform};
|
|||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// async fn my_service(req: u8) -> Result<u64, MyError>;
|
/// async fn my_service(req: u8) -> Result<u64, MyError>;
|
||||||
/// ```
|
/// ```
|
||||||
pub trait Service {
|
pub trait Service<Req> {
|
||||||
/// Requests handled by the service.
|
|
||||||
type Request;
|
|
||||||
|
|
||||||
/// Responses given by the service.
|
/// Responses given by the service.
|
||||||
type Response;
|
type Response;
|
||||||
|
|
||||||
/// Errors produced by the service.
|
/// Errors produced by the service when polling readiness or executing call.
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
/// The future response value.
|
/// The future response value.
|
||||||
@ -109,7 +106,7 @@ pub trait Service {
|
|||||||
///
|
///
|
||||||
/// Calling `call` without calling `poll_ready` is permitted. The
|
/// Calling `call` without calling `poll_ready` is permitted. The
|
||||||
/// implementation must be resilient to this fact.
|
/// implementation must be resilient to this fact.
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future;
|
fn call(&mut self, req: Req) -> Self::Future;
|
||||||
|
|
||||||
/// Map this service's output to a different type, returning a new service
|
/// Map this service's output to a different type, returning a new service
|
||||||
/// of the resulting type.
|
/// of the resulting type.
|
||||||
@ -120,7 +117,7 @@ pub trait Service {
|
|||||||
/// Note that this function consumes the receiving service and returns a
|
/// Note that this function consumes the receiving service and returns a
|
||||||
/// wrapped version of it, similar to the existing `map` methods in the
|
/// wrapped version of it, similar to the existing `map` methods in the
|
||||||
/// standard library.
|
/// standard library.
|
||||||
fn map<F, R>(self, f: F) -> crate::dev::Map<Self, F, R>
|
fn map<F, R>(self, f: F) -> crate::dev::Map<Self, F, Req, R>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnMut(Self::Response) -> R,
|
F: FnMut(Self::Response) -> R,
|
||||||
@ -136,7 +133,7 @@ pub trait Service {
|
|||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving service and returns a
|
/// Note that this function consumes the receiving service and returns a
|
||||||
/// wrapped version of it.
|
/// wrapped version of it.
|
||||||
fn map_err<F, E>(self, f: F) -> crate::dev::MapErr<Self, F, E>
|
fn map_err<F, E>(self, f: F) -> crate::dev::MapErr<Self, Req, F, E>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(Self::Error) -> E,
|
F: Fn(Self::Error) -> E,
|
||||||
@ -154,10 +151,7 @@ pub trait Service {
|
|||||||
/// requests on that new TCP stream.
|
/// requests on that new TCP stream.
|
||||||
///
|
///
|
||||||
/// `Config` is a service factory configuration type.
|
/// `Config` is a service factory configuration type.
|
||||||
pub trait ServiceFactory {
|
pub trait ServiceFactory<Req> {
|
||||||
/// Requests handled by the created services.
|
|
||||||
type Request;
|
|
||||||
|
|
||||||
/// Responses given by the created services.
|
/// Responses given by the created services.
|
||||||
type Response;
|
type Response;
|
||||||
|
|
||||||
@ -168,11 +162,7 @@ pub trait ServiceFactory {
|
|||||||
type Config;
|
type Config;
|
||||||
|
|
||||||
/// The kind of `Service` created by this factory.
|
/// The kind of `Service` created by this factory.
|
||||||
type Service: Service<
|
type Service: Service<Req, Response = Self::Response, Error = Self::Error>;
|
||||||
Request = Self::Request,
|
|
||||||
Response = Self::Response,
|
|
||||||
Error = Self::Error,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// Errors potentially raised while building a service.
|
/// Errors potentially raised while building a service.
|
||||||
type InitError;
|
type InitError;
|
||||||
@ -185,7 +175,7 @@ pub trait ServiceFactory {
|
|||||||
|
|
||||||
/// Map this service's output to a different type, returning a new service
|
/// Map this service's output to a different type, returning a new service
|
||||||
/// of the resulting type.
|
/// of the resulting type.
|
||||||
fn map<F, R>(self, f: F) -> crate::map::MapServiceFactory<Self, F, R>
|
fn map<F, R>(self, f: F) -> crate::map::MapServiceFactory<Self, F, Req, R>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnMut(Self::Response) -> R + Clone,
|
F: FnMut(Self::Response) -> R + Clone,
|
||||||
@ -194,7 +184,7 @@ pub trait ServiceFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Map this service's error to a different error, returning a new service.
|
/// Map this service's error to a different error, returning a new service.
|
||||||
fn map_err<F, E>(self, f: F) -> crate::map_err::MapErrServiceFactory<Self, F, E>
|
fn map_err<F, E>(self, f: F) -> crate::map_err::MapErrServiceFactory<Self, Req, F, E>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(Self::Error) -> E + Clone,
|
F: Fn(Self::Error) -> E + Clone,
|
||||||
@ -203,7 +193,7 @@ pub trait ServiceFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Map this factory's init error to a different error, returning a new service.
|
/// Map this factory's init error to a different error, returning a new service.
|
||||||
fn map_init_err<F, E>(self, f: F) -> crate::map_init_err::MapInitErr<Self, F, E>
|
fn map_init_err<F, E>(self, f: F) -> crate::map_init_err::MapInitErr<Self, F, Req, E>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(Self::InitError) -> E + Clone,
|
F: Fn(Self::InitError) -> E + Clone,
|
||||||
@ -212,11 +202,10 @@ pub trait ServiceFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S> Service for &'a mut S
|
impl<'a, S, Req> Service<Req> for &'a mut S
|
||||||
where
|
where
|
||||||
S: Service + 'a,
|
S: Service<Req> + 'a,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Future = S::Future;
|
type Future = S::Future;
|
||||||
@ -225,16 +214,15 @@ where
|
|||||||
(**self).poll_ready(ctx)
|
(**self).poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: Self::Request) -> S::Future {
|
fn call(&mut self, request: Req) -> S::Future {
|
||||||
(**self).call(request)
|
(**self).call(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Service for Box<S>
|
impl<S, Req> Service<Req> for Box<S>
|
||||||
where
|
where
|
||||||
S: Service + ?Sized,
|
S: Service<Req> + ?Sized,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Future = S::Future;
|
type Future = S::Future;
|
||||||
@ -243,16 +231,15 @@ where
|
|||||||
(**self).poll_ready(ctx)
|
(**self).poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: Self::Request) -> S::Future {
|
fn call(&mut self, request: Req) -> S::Future {
|
||||||
(**self).call(request)
|
(**self).call(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Service for RefCell<S>
|
impl<S, Req> Service<Req> for RefCell<S>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Future = S::Future;
|
type Future = S::Future;
|
||||||
@ -261,16 +248,15 @@ where
|
|||||||
self.borrow_mut().poll_ready(ctx)
|
self.borrow_mut().poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: Self::Request) -> S::Future {
|
fn call(&mut self, request: Req) -> S::Future {
|
||||||
self.borrow_mut().call(request)
|
self.borrow_mut().call(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Service for Rc<RefCell<S>>
|
impl<S, Req> Service<Req> for Rc<RefCell<S>>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Future = S::Future;
|
type Future = S::Future;
|
||||||
@ -279,16 +265,15 @@ where
|
|||||||
self.borrow_mut().poll_ready(ctx)
|
self.borrow_mut().poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: Self::Request) -> S::Future {
|
fn call(&mut self, request: Req) -> S::Future {
|
||||||
(&mut (**self).borrow_mut()).call(request)
|
(&mut (**self).borrow_mut()).call(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> ServiceFactory for Rc<S>
|
impl<S, Req> ServiceFactory<Req> for Rc<S>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
S: ServiceFactory<Req>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Config = S::Config;
|
type Config = S::Config;
|
||||||
@ -301,11 +286,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> ServiceFactory for Arc<S>
|
impl<S, Req> ServiceFactory<Req> for Arc<S>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
S: ServiceFactory<Req>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Config = S::Config;
|
type Config = S::Config;
|
||||||
@ -319,52 +303,52 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for types that can be converted to a `Service`
|
/// Trait for types that can be converted to a `Service`
|
||||||
pub trait IntoService<T>
|
pub trait IntoService<S, Req>
|
||||||
where
|
where
|
||||||
T: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
/// Convert to a `Service`
|
/// Convert to a `Service`
|
||||||
fn into_service(self) -> T;
|
fn into_service(self) -> S;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for types that can be converted to a `ServiceFactory`
|
/// Trait for types that can be converted to a `ServiceFactory`
|
||||||
pub trait IntoServiceFactory<T>
|
pub trait IntoServiceFactory<SF, Req>
|
||||||
where
|
where
|
||||||
T: ServiceFactory,
|
SF: ServiceFactory<Req>,
|
||||||
{
|
{
|
||||||
/// Convert `Self` to a `ServiceFactory`
|
/// Convert `Self` to a `ServiceFactory`
|
||||||
fn into_factory(self) -> T;
|
fn into_factory(self) -> SF;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IntoService<T> for T
|
impl<S, Req> IntoService<S, Req> for S
|
||||||
where
|
where
|
||||||
T: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
fn into_service(self) -> T {
|
fn into_service(self) -> S {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IntoServiceFactory<T> for T
|
impl<SF, Req> IntoServiceFactory<SF, Req> for SF
|
||||||
where
|
where
|
||||||
T: ServiceFactory,
|
SF: ServiceFactory<Req>,
|
||||||
{
|
{
|
||||||
fn into_factory(self) -> T {
|
fn into_factory(self) -> SF {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert object of type `T` to a service `S`
|
/// Convert object of type `U` to a service `S`
|
||||||
pub fn into_service<T, S>(tp: T) -> S
|
pub fn into_service<I, S, Req>(tp: I) -> S
|
||||||
where
|
where
|
||||||
S: Service,
|
I: IntoService<S, Req>,
|
||||||
T: IntoService<S>,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
tp.into_service()
|
tp.into_service()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod dev {
|
pub mod dev {
|
||||||
pub use crate::apply::{Apply, ApplyServiceFactory};
|
pub use crate::apply::{Apply, ApplyFactory};
|
||||||
pub use crate::fn_service::{
|
pub use crate::fn_service::{
|
||||||
FnService, FnServiceConfig, FnServiceFactory, FnServiceNoConfig,
|
FnService, FnServiceConfig, FnServiceFactory, FnServiceNoConfig,
|
||||||
};
|
};
|
||||||
|
@ -8,18 +8,18 @@ use super::{Service, ServiceFactory};
|
|||||||
/// Service for the `map` combinator, changing the type of a service's response.
|
/// Service for the `map` combinator, changing the type of a service's response.
|
||||||
///
|
///
|
||||||
/// This is created by the `ServiceExt::map` method.
|
/// This is created by the `ServiceExt::map` method.
|
||||||
pub struct Map<A, F, Response> {
|
pub struct Map<A, F, Req, Res> {
|
||||||
service: A,
|
service: A,
|
||||||
f: F,
|
f: F,
|
||||||
_t: PhantomData<Response>,
|
_t: PhantomData<(Req, Res)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Response> Map<A, F, Response> {
|
impl<A, F, Req, Res> Map<A, F, Req, Res> {
|
||||||
/// Create new `Map` combinator
|
/// Create new `Map` combinator
|
||||||
pub(crate) fn new(service: A, f: F) -> Self
|
pub(crate) fn new(service: A, f: F) -> Self
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: FnMut(A::Response) -> Response,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
service,
|
service,
|
||||||
@ -29,7 +29,7 @@ impl<A, F, Response> Map<A, F, Response> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Response> Clone for Map<A, F, Response>
|
impl<A, F, Req, Res> Clone for Map<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: Clone,
|
A: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
@ -43,52 +43,51 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Response> Service for Map<A, F, Response>
|
impl<A, F, Req, Res> Service<Req> for Map<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: FnMut(A::Response) -> Response + Clone,
|
F: FnMut(A::Response) -> Res + Clone,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
type Response = Res;
|
||||||
type Response = Response;
|
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
type Future = MapFuture<A, F, Response>;
|
type Future = MapFuture<A, F, Req, Res>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.service.poll_ready(ctx)
|
self.service.poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
MapFuture::new(self.service.call(req), self.f.clone())
|
MapFuture::new(self.service.call(req), self.f.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct MapFuture<A, F, Response>
|
pub struct MapFuture<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: FnMut(A::Response) -> Response,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
f: F,
|
f: F,
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: A::Future,
|
fut: A::Future,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Response> MapFuture<A, F, Response>
|
impl<A, F, Req, Res> MapFuture<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: FnMut(A::Response) -> Response,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
MapFuture { f, fut }
|
MapFuture { f, fut }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Response> Future for MapFuture<A, F, Response>
|
impl<A, F, Req, Res> Future for MapFuture<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: FnMut(A::Response) -> Response,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
type Output = Result<Response, A::Error>;
|
type Output = Result<Res, A::Error>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
@ -102,17 +101,17 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// `MapNewService` new service combinator
|
/// `MapNewService` new service combinator
|
||||||
pub struct MapServiceFactory<A, F, Res> {
|
pub struct MapServiceFactory<A, F, Req, Res> {
|
||||||
a: A,
|
a: A,
|
||||||
f: F,
|
f: F,
|
||||||
r: PhantomData<Res>,
|
r: PhantomData<(Res, Req)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Res> MapServiceFactory<A, F, Res> {
|
impl<A, F, Req, Res> MapServiceFactory<A, F, Req, Res> {
|
||||||
/// Create new `Map` new service instance
|
/// Create new `Map` new service instance
|
||||||
pub(crate) fn new(a: A, f: F) -> Self
|
pub(crate) fn new(a: A, f: F) -> Self
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: FnMut(A::Response) -> Res,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
@ -123,7 +122,7 @@ impl<A, F, Res> MapServiceFactory<A, F, Res> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Res> Clone for MapServiceFactory<A, F, Res>
|
impl<A, F, Req, Res> Clone for MapServiceFactory<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: Clone,
|
A: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
@ -137,19 +136,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Res> ServiceFactory for MapServiceFactory<A, F, Res>
|
impl<A, F, Req, Res> ServiceFactory<Req> for MapServiceFactory<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: FnMut(A::Response) -> Res + Clone,
|
F: FnMut(A::Response) -> Res + Clone,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
|
|
||||||
type Config = A::Config;
|
type Config = A::Config;
|
||||||
type Service = Map<A::Service, F, Res>;
|
type Service = Map<A::Service, F, Req, Res>;
|
||||||
type InitError = A::InitError;
|
type InitError = A::InitError;
|
||||||
type Future = MapServiceFuture<A, F, Res>;
|
type Future = MapServiceFuture<A, F, Req, Res>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
||||||
MapServiceFuture::new(self.a.new_service(cfg), self.f.clone())
|
MapServiceFuture::new(self.a.new_service(cfg), self.f.clone())
|
||||||
@ -157,9 +155,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct MapServiceFuture<A, F, Res>
|
pub struct MapServiceFuture<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: FnMut(A::Response) -> Res,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
@ -167,9 +165,9 @@ where
|
|||||||
f: Option<F>,
|
f: Option<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Res> MapServiceFuture<A, F, Res>
|
impl<A, F, Req, Res> MapServiceFuture<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: FnMut(A::Response) -> Res,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
@ -177,12 +175,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, Res> Future for MapServiceFuture<A, F, Res>
|
impl<A, F, Req, Res> Future for MapServiceFuture<A, F, Req, Res>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: FnMut(A::Response) -> Res,
|
F: FnMut(A::Response) -> Res,
|
||||||
{
|
{
|
||||||
type Output = Result<Map<A::Service, F, Res>, A::InitError>;
|
type Output = Result<Map<A::Service, F, Req, Res>, A::InitError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
@ -204,8 +202,7 @@ mod tests {
|
|||||||
|
|
||||||
struct Srv;
|
struct Srv;
|
||||||
|
|
||||||
impl Service for Srv {
|
impl Service<()> for Srv {
|
||||||
type Request = ();
|
|
||||||
type Response = ();
|
type Response = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<(), ()>>;
|
type Future = Ready<Result<(), ()>>;
|
||||||
|
@ -6,121 +6,123 @@ use super::{IntoServiceFactory, ServiceFactory};
|
|||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving service factory and returns
|
/// Note that this function consumes the receiving service factory and returns
|
||||||
/// a wrapped version of it.
|
/// a wrapped version of it.
|
||||||
pub fn map_config<T, U, F, C>(factory: U, f: F) -> MapConfig<T, F, C>
|
pub fn map_config<I, SF, S, Req, F, Cfg>(factory: I, f: F) -> MapConfig<SF, Req, F, Cfg>
|
||||||
where
|
where
|
||||||
T: ServiceFactory,
|
I: IntoServiceFactory<SF, Req>,
|
||||||
U: IntoServiceFactory<T>,
|
SF: ServiceFactory<Req>,
|
||||||
F: Fn(C) -> T::Config,
|
F: Fn(Cfg) -> SF::Config,
|
||||||
{
|
{
|
||||||
MapConfig::new(factory.into_factory(), f)
|
MapConfig::new(factory.into_factory(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace config with unit
|
/// Replace config with unit.
|
||||||
pub fn unit_config<T, U, C>(factory: U) -> UnitConfig<T, C>
|
pub fn unit_config<I, SF, Cfg, Req>(factory: I) -> UnitConfig<SF, Cfg, Req>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<Config = ()>,
|
I: IntoServiceFactory<SF, Req>,
|
||||||
U: IntoServiceFactory<T>,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
{
|
{
|
||||||
UnitConfig::new(factory.into_factory())
|
UnitConfig::new(factory.into_factory())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `map_config()` adapter service factory
|
/// `map_config()` adapter service factory
|
||||||
pub struct MapConfig<A, F, C> {
|
pub struct MapConfig<SF, Req, F, Cfg> {
|
||||||
a: A,
|
factory: SF,
|
||||||
f: F,
|
cfg_mapper: F,
|
||||||
e: PhantomData<C>,
|
e: PhantomData<(Cfg, Req)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, C> MapConfig<A, F, C> {
|
impl<SF, Req, F, Cfg> MapConfig<SF, Req, F, Cfg> {
|
||||||
/// Create new `MapConfig` combinator
|
/// Create new `MapConfig` combinator
|
||||||
pub(crate) fn new(a: A, f: F) -> Self
|
pub(crate) fn new(factory: SF, cfg_mapper: F) -> Self
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
SF: ServiceFactory<Req>,
|
||||||
F: Fn(C) -> A::Config,
|
F: Fn(Cfg) -> SF::Config,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
a,
|
factory,
|
||||||
f,
|
cfg_mapper,
|
||||||
e: PhantomData,
|
e: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, C> Clone for MapConfig<A, F, C>
|
impl<SF, Req, F, Cfg> Clone for MapConfig<SF, Req, F, Cfg>
|
||||||
where
|
where
|
||||||
A: Clone,
|
SF: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
a: self.a.clone(),
|
factory: self.factory.clone(),
|
||||||
f: self.f.clone(),
|
cfg_mapper: self.cfg_mapper.clone(),
|
||||||
e: PhantomData,
|
e: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, C> ServiceFactory for MapConfig<A, F, C>
|
impl<SF, Req, F, Cfg> ServiceFactory<Req> for MapConfig<SF, Req, F, Cfg>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
SF: ServiceFactory<Req>,
|
||||||
F: Fn(C) -> A::Config,
|
F: Fn(Cfg) -> SF::Config,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
type Response = SF::Response;
|
||||||
type Response = A::Response;
|
type Error = SF::Error;
|
||||||
type Error = A::Error;
|
|
||||||
|
|
||||||
type Config = C;
|
type Config = Cfg;
|
||||||
type Service = A::Service;
|
type Service = SF::Service;
|
||||||
type InitError = A::InitError;
|
type InitError = SF::InitError;
|
||||||
type Future = A::Future;
|
type Future = SF::Future;
|
||||||
|
|
||||||
fn new_service(&self, cfg: C) -> Self::Future {
|
fn new_service(&self, cfg: Self::Config) -> Self::Future {
|
||||||
self.a.new_service((self.f)(cfg))
|
let mapped_cfg = (self.cfg_mapper)(cfg);
|
||||||
|
self.factory.new_service(mapped_cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `unit_config()` config combinator
|
/// `unit_config()` config combinator
|
||||||
pub struct UnitConfig<A, C> {
|
pub struct UnitConfig<SF, Cfg, Req> {
|
||||||
a: A,
|
factory: SF,
|
||||||
e: PhantomData<C>,
|
_phantom: PhantomData<(Cfg, Req)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, C> UnitConfig<A, C>
|
impl<SF, Cfg, Req> UnitConfig<SF, Cfg, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory<Config = ()>,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
{
|
{
|
||||||
/// Create new `UnitConfig` combinator
|
/// Create new `UnitConfig` combinator
|
||||||
pub(crate) fn new(a: A) -> Self {
|
pub(crate) fn new(factory: SF) -> Self {
|
||||||
Self { a, e: PhantomData }
|
Self {
|
||||||
|
factory,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, C> Clone for UnitConfig<A, C>
|
impl<SF, Cfg, Req> Clone for UnitConfig<SF, Cfg, Req>
|
||||||
where
|
where
|
||||||
A: Clone,
|
SF: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
a: self.a.clone(),
|
factory: self.factory.clone(),
|
||||||
e: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, C> ServiceFactory for UnitConfig<A, C>
|
impl<SF, Cfg, Req> ServiceFactory<Req> for UnitConfig<SF, Cfg, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory<Config = ()>,
|
SF: ServiceFactory<Req, Config = ()>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
type Response = SF::Response;
|
||||||
type Response = A::Response;
|
type Error = SF::Error;
|
||||||
type Error = A::Error;
|
|
||||||
|
|
||||||
type Config = C;
|
type Config = Cfg;
|
||||||
type Service = A::Service;
|
type Service = SF::Service;
|
||||||
type InitError = A::InitError;
|
type InitError = SF::InitError;
|
||||||
type Future = A::Future;
|
type Future = SF::Future;
|
||||||
|
|
||||||
fn new_service(&self, _: C) -> Self::Future {
|
fn new_service(&self, _: Cfg) -> Self::Future {
|
||||||
self.a.new_service(())
|
self.factory.new_service(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,18 +9,18 @@ use super::{Service, ServiceFactory};
|
|||||||
/// error.
|
/// error.
|
||||||
///
|
///
|
||||||
/// This is created by the `ServiceExt::map_err` method.
|
/// This is created by the `ServiceExt::map_err` method.
|
||||||
pub struct MapErr<A, F, E> {
|
pub struct MapErr<S, Req, F, E> {
|
||||||
service: A,
|
service: S,
|
||||||
f: F,
|
f: F,
|
||||||
_t: PhantomData<E>,
|
_t: PhantomData<(E, Req)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> MapErr<A, F, E> {
|
impl<S, Req, F, E> MapErr<S, Req, F, E> {
|
||||||
/// Create new `MapErr` combinator
|
/// Create new `MapErr` combinator
|
||||||
pub(crate) fn new(service: A, f: F) -> Self
|
pub(crate) fn new(service: S, f: F) -> Self
|
||||||
where
|
where
|
||||||
A: Service,
|
S: Service<Req>,
|
||||||
F: Fn(A::Error) -> E,
|
F: Fn(S::Error) -> E,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
service,
|
service,
|
||||||
@ -30,9 +30,9 @@ impl<A, F, E> MapErr<A, F, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> Clone for MapErr<A, F, E>
|
impl<S, Req, F, E> Clone for MapErr<S, Req, F, E>
|
||||||
where
|
where
|
||||||
A: Clone,
|
S: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
@ -44,29 +44,28 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> Service for MapErr<A, F, E>
|
impl<A, Req, F, E> Service<Req> for MapErr<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = A::Response;
|
type Response = A::Response;
|
||||||
type Error = E;
|
type Error = E;
|
||||||
type Future = MapErrFuture<A, F, E>;
|
type Future = MapErrFuture<A, Req, F, E>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.service.poll_ready(ctx).map_err(&self.f)
|
self.service.poll_ready(ctx).map_err(&self.f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
MapErrFuture::new(self.service.call(req), self.f.clone())
|
MapErrFuture::new(self.service.call(req), self.f.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct MapErrFuture<A, F, E>
|
pub struct MapErrFuture<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: Fn(A::Error) -> E,
|
F: Fn(A::Error) -> E,
|
||||||
{
|
{
|
||||||
f: F,
|
f: F,
|
||||||
@ -74,9 +73,9 @@ where
|
|||||||
fut: A::Future,
|
fut: A::Future,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> MapErrFuture<A, F, E>
|
impl<A, Req, F, E> MapErrFuture<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: Fn(A::Error) -> E,
|
F: Fn(A::Error) -> E,
|
||||||
{
|
{
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
@ -84,9 +83,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> Future for MapErrFuture<A, F, E>
|
impl<A, Req, F, E> Future for MapErrFuture<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
F: Fn(A::Error) -> E,
|
F: Fn(A::Error) -> E,
|
||||||
{
|
{
|
||||||
type Output = Result<A::Response, E>;
|
type Output = Result<A::Response, E>;
|
||||||
@ -101,19 +100,19 @@ where
|
|||||||
/// service's error.
|
/// service's error.
|
||||||
///
|
///
|
||||||
/// This is created by the `NewServiceExt::map_err` method.
|
/// This is created by the `NewServiceExt::map_err` method.
|
||||||
pub struct MapErrServiceFactory<A, F, E>
|
pub struct MapErrServiceFactory<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
a: A,
|
a: A,
|
||||||
f: F,
|
f: F,
|
||||||
e: PhantomData<E>,
|
e: PhantomData<(E, Req)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> MapErrServiceFactory<A, F, E>
|
impl<A, Req, F, E> MapErrServiceFactory<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
/// Create new `MapErr` new service instance
|
/// Create new `MapErr` new service instance
|
||||||
@ -126,9 +125,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> Clone for MapErrServiceFactory<A, F, E>
|
impl<A, Req, F, E> Clone for MapErrServiceFactory<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory + Clone,
|
A: ServiceFactory<Req> + Clone,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
@ -140,19 +139,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> ServiceFactory for MapErrServiceFactory<A, F, E>
|
impl<A, Req, F, E> ServiceFactory<Req> for MapErrServiceFactory<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = A::Response;
|
type Response = A::Response;
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
|
||||||
type Config = A::Config;
|
type Config = A::Config;
|
||||||
type Service = MapErr<A::Service, F, E>;
|
type Service = MapErr<A::Service, Req, F, E>;
|
||||||
type InitError = A::InitError;
|
type InitError = A::InitError;
|
||||||
type Future = MapErrServiceFuture<A, F, E>;
|
type Future = MapErrServiceFuture<A, Req, F, E>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
||||||
MapErrServiceFuture::new(self.a.new_service(cfg), self.f.clone())
|
MapErrServiceFuture::new(self.a.new_service(cfg), self.f.clone())
|
||||||
@ -160,9 +158,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct MapErrServiceFuture<A, F, E>
|
pub struct MapErrServiceFuture<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::Error) -> E,
|
F: Fn(A::Error) -> E,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
@ -170,9 +168,9 @@ where
|
|||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> MapErrServiceFuture<A, F, E>
|
impl<A, Req, F, E> MapErrServiceFuture<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::Error) -> E,
|
F: Fn(A::Error) -> E,
|
||||||
{
|
{
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
@ -180,12 +178,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> Future for MapErrServiceFuture<A, F, E>
|
impl<A, Req, F, E> Future for MapErrServiceFuture<A, Req, F, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::Error) -> E + Clone,
|
F: Fn(A::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
type Output = Result<MapErr<A::Service, F, E>, A::InitError>;
|
type Output = Result<MapErr<A::Service, Req, F, E>, A::InitError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
@ -206,8 +204,7 @@ mod tests {
|
|||||||
|
|
||||||
struct Srv;
|
struct Srv;
|
||||||
|
|
||||||
impl Service for Srv {
|
impl Service<()> for Srv {
|
||||||
type Request = ();
|
|
||||||
type Response = ();
|
type Response = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<(), ()>>;
|
type Future = Ready<Result<(), ()>>;
|
||||||
|
@ -6,16 +6,16 @@ use std::task::{Context, Poll};
|
|||||||
use super::ServiceFactory;
|
use super::ServiceFactory;
|
||||||
|
|
||||||
/// `MapInitErr` service combinator
|
/// `MapInitErr` service combinator
|
||||||
pub struct MapInitErr<A, F, E> {
|
pub struct MapInitErr<A, F, Req, Err> {
|
||||||
a: A,
|
a: A,
|
||||||
f: F,
|
f: F,
|
||||||
e: PhantomData<E>,
|
e: PhantomData<(Req, Err)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> MapInitErr<A, F, E>
|
impl<A, F, Req, Err> MapInitErr<A, F, Req, Err>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::InitError) -> E,
|
F: Fn(A::InitError) -> Err,
|
||||||
{
|
{
|
||||||
/// Create new `MapInitErr` combinator
|
/// Create new `MapInitErr` combinator
|
||||||
pub(crate) fn new(a: A, f: F) -> Self {
|
pub(crate) fn new(a: A, f: F) -> Self {
|
||||||
@ -27,7 +27,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> Clone for MapInitErr<A, F, E>
|
impl<A, F, Req, E> Clone for MapInitErr<A, F, Req, E>
|
||||||
where
|
where
|
||||||
A: Clone,
|
A: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
@ -41,19 +41,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> ServiceFactory for MapInitErr<A, F, E>
|
impl<A, F, Req, E> ServiceFactory<Req> for MapInitErr<A, F, Req, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::InitError) -> E + Clone,
|
F: Fn(A::InitError) -> E + Clone,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = A::Response;
|
type Response = A::Response;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
|
|
||||||
type Config = A::Config;
|
type Config = A::Config;
|
||||||
type Service = A::Service;
|
type Service = A::Service;
|
||||||
type InitError = E;
|
type InitError = E;
|
||||||
type Future = MapInitErrFuture<A, F, E>;
|
type Future = MapInitErrFuture<A, F, Req, E>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
||||||
MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone())
|
MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone())
|
||||||
@ -61,9 +60,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct MapInitErrFuture<A, F, E>
|
pub struct MapInitErrFuture<A, F, Req, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::InitError) -> E,
|
F: Fn(A::InitError) -> E,
|
||||||
{
|
{
|
||||||
f: F,
|
f: F,
|
||||||
@ -71,9 +70,9 @@ where
|
|||||||
fut: A::Future,
|
fut: A::Future,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> MapInitErrFuture<A, F, E>
|
impl<A, F, Req, E> MapInitErrFuture<A, F, Req, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::InitError) -> E,
|
F: Fn(A::InitError) -> E,
|
||||||
{
|
{
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
@ -81,9 +80,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, E> Future for MapInitErrFuture<A, F, E>
|
impl<A, F, Req, E> Future for MapInitErrFuture<A, F, Req, E>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
F: Fn(A::InitError) -> E,
|
F: Fn(A::InitError) -> E,
|
||||||
{
|
{
|
||||||
type Output = Result<A::Service, E>;
|
type Output = Result<A::Service, E>;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
use std::{future::Future, marker::PhantomData};
|
||||||
|
|
||||||
use crate::and_then::{AndThenService, AndThenServiceFactory};
|
use crate::and_then::{AndThenService, AndThenServiceFactory};
|
||||||
use crate::and_then_apply_fn::{AndThenApplyFn, AndThenApplyFnFactory};
|
use crate::and_then_apply_fn::{AndThenApplyFn, AndThenApplyFnFactory};
|
||||||
@ -10,33 +10,39 @@ use crate::then::{ThenService, ThenServiceFactory};
|
|||||||
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||||
|
|
||||||
/// Construct new pipeline with one service in pipeline chain.
|
/// Construct new pipeline with one service in pipeline chain.
|
||||||
pub fn pipeline<F, T>(service: F) -> Pipeline<T>
|
pub fn pipeline<I, S, Req>(service: I) -> Pipeline<S, Req>
|
||||||
where
|
where
|
||||||
F: IntoService<T>,
|
I: IntoService<S, Req>,
|
||||||
T: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
Pipeline {
|
Pipeline {
|
||||||
service: service.into_service(),
|
service: service.into_service(),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct new pipeline factory with one service factory.
|
/// Construct new pipeline factory with one service factory.
|
||||||
pub fn pipeline_factory<T, F>(factory: F) -> PipelineFactory<T>
|
pub fn pipeline_factory<I, SF, Req>(factory: I) -> PipelineFactory<SF, Req>
|
||||||
where
|
where
|
||||||
T: ServiceFactory,
|
I: IntoServiceFactory<SF, Req>,
|
||||||
F: IntoServiceFactory<T>,
|
SF: ServiceFactory<Req>,
|
||||||
{
|
{
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: factory.into_factory(),
|
factory: factory.into_factory(),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pipeline service - pipeline allows to compose multiple service into one service.
|
/// Pipeline service - pipeline allows to compose multiple service into one service.
|
||||||
pub struct Pipeline<T> {
|
pub struct Pipeline<S, Req> {
|
||||||
service: T,
|
service: S,
|
||||||
|
_phantom: PhantomData<Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Service> Pipeline<T> {
|
impl<S, Req> Pipeline<S, Req>
|
||||||
|
where
|
||||||
|
S: Service<Req>,
|
||||||
|
{
|
||||||
/// Call another service after call to this one has resolved successfully.
|
/// Call another service after call to this one has resolved successfully.
|
||||||
///
|
///
|
||||||
/// This function can be used to chain two services together and ensure that
|
/// This function can be used to chain two services together and ensure that
|
||||||
@ -46,41 +52,40 @@ impl<T: Service> Pipeline<T> {
|
|||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving service and returns a
|
/// Note that this function consumes the receiving service and returns a
|
||||||
/// wrapped version of it.
|
/// wrapped version of it.
|
||||||
pub fn and_then<F, U>(
|
pub fn and_then<I, S1>(
|
||||||
self,
|
self,
|
||||||
service: F,
|
service: I,
|
||||||
) -> Pipeline<
|
) -> Pipeline<impl Service<Req, Response = S1::Response, Error = S::Error> + Clone, Req>
|
||||||
impl Service<Request = T::Request, Response = U::Response, Error = T::Error> + Clone,
|
|
||||||
>
|
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: IntoService<U>,
|
I: IntoService<S1, S::Response>,
|
||||||
U: Service<Request = T::Response, Error = T::Error>,
|
S1: Service<S::Response, Error = S::Error>,
|
||||||
{
|
{
|
||||||
Pipeline {
|
Pipeline {
|
||||||
service: AndThenService::new(self.service, service.into_service()),
|
service: AndThenService::new(self.service, service.into_service()),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply function to specified service and use it as a next service in
|
/// Apply function to specified service and use it as a next service in chain.
|
||||||
/// chain.
|
|
||||||
///
|
///
|
||||||
/// Short version of `pipeline_factory(...).and_then(apply_fn_factory(...))`
|
/// Short version of `pipeline_factory(...).and_then(apply_fn(...))`
|
||||||
pub fn and_then_apply_fn<U, I, F, Fut, Res, Err>(
|
pub fn and_then_apply_fn<I, S1, F, Fut, In, Res, Err>(
|
||||||
self,
|
self,
|
||||||
service: I,
|
service: I,
|
||||||
f: F,
|
wrap_fn: F,
|
||||||
) -> Pipeline<impl Service<Request = T::Request, Response = Res, Error = Err> + Clone>
|
) -> Pipeline<impl Service<Req, Response = Res, Error = Err> + Clone, Req>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
I: IntoService<U>,
|
I: IntoService<S1, In>,
|
||||||
U: Service,
|
S1: Service<In>,
|
||||||
F: FnMut(T::Response, &mut U) -> Fut,
|
F: FnMut(S::Response, &mut S1) -> Fut,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<T::Error> + From<U::Error>,
|
Err: From<S::Error> + From<S1::Error>,
|
||||||
{
|
{
|
||||||
Pipeline {
|
Pipeline {
|
||||||
service: AndThenApplyFn::new(self.service, service.into_service(), f),
|
service: AndThenApplyFn::new(self.service, service.into_service(), wrap_fn),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,19 +94,18 @@ impl<T: Service> Pipeline<T> {
|
|||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving pipeline and returns a
|
/// Note that this function consumes the receiving pipeline and returns a
|
||||||
/// wrapped version of it.
|
/// wrapped version of it.
|
||||||
pub fn then<F, U>(
|
pub fn then<F, S1>(
|
||||||
self,
|
self,
|
||||||
service: F,
|
service: F,
|
||||||
) -> Pipeline<
|
) -> Pipeline<impl Service<Req, Response = S1::Response, Error = S::Error> + Clone, Req>
|
||||||
impl Service<Request = T::Request, Response = U::Response, Error = T::Error> + Clone,
|
|
||||||
>
|
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: IntoService<U>,
|
F: IntoService<S1, Result<S::Response, S::Error>>,
|
||||||
U: Service<Request = Result<T::Response, T::Error>, Error = T::Error>,
|
S1: Service<Result<S::Response, S::Error>, Error = S::Error>,
|
||||||
{
|
{
|
||||||
Pipeline {
|
Pipeline {
|
||||||
service: ThenService::new(self.service, service.into_service()),
|
service: ThenService::new(self.service, service.into_service()),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,13 +118,14 @@ impl<T: Service> Pipeline<T> {
|
|||||||
/// Note that this function consumes the receiving service and returns a
|
/// Note that this function consumes the receiving service and returns a
|
||||||
/// wrapped version of it, similar to the existing `map` methods in the
|
/// wrapped version of it, similar to the existing `map` methods in the
|
||||||
/// standard library.
|
/// standard library.
|
||||||
pub fn map<F, R>(self, f: F) -> Pipeline<Map<T, F, R>>
|
pub fn map<F, R>(self, f: F) -> Pipeline<Map<S, F, Req, R>, Req>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnMut(T::Response) -> R,
|
F: FnMut(S::Response) -> R,
|
||||||
{
|
{
|
||||||
Pipeline {
|
Pipeline {
|
||||||
service: Map::new(self.service, f),
|
service: Map::new(self.service, f),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,114 +137,118 @@ impl<T: Service> Pipeline<T> {
|
|||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving service and returns a
|
/// Note that this function consumes the receiving service and returns a
|
||||||
/// wrapped version of it.
|
/// wrapped version of it.
|
||||||
pub fn map_err<F, E>(self, f: F) -> Pipeline<MapErr<T, F, E>>
|
pub fn map_err<F, E>(self, f: F) -> Pipeline<MapErr<S, Req, F, E>, Req>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(T::Error) -> E,
|
F: Fn(S::Error) -> E,
|
||||||
{
|
{
|
||||||
Pipeline {
|
Pipeline {
|
||||||
service: MapErr::new(self.service, f),
|
service: MapErr::new(self.service, f),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Clone for Pipeline<T>
|
impl<T, Req> Clone for Pipeline<T, Req>
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Pipeline {
|
Pipeline {
|
||||||
service: self.service.clone(),
|
service: self.service.clone(),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Service> Service for Pipeline<T> {
|
impl<S: Service<Req>, Req> Service<Req> for Pipeline<S, Req> {
|
||||||
type Request = T::Request;
|
type Response = S::Response;
|
||||||
type Response = T::Response;
|
type Error = S::Error;
|
||||||
type Error = T::Error;
|
type Future = S::Future;
|
||||||
type Future = T::Future;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), T::Error>> {
|
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
|
||||||
self.service.poll_ready(ctx)
|
self.service.poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&mut self, req: T::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
self.service.call(req)
|
self.service.call(req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pipeline factory
|
/// Pipeline factory
|
||||||
pub struct PipelineFactory<T> {
|
pub struct PipelineFactory<SF, Req> {
|
||||||
factory: T,
|
factory: SF,
|
||||||
|
_phantom: PhantomData<Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ServiceFactory> PipelineFactory<T> {
|
impl<SF, Req> PipelineFactory<SF, Req>
|
||||||
|
where
|
||||||
|
SF: ServiceFactory<Req>,
|
||||||
|
{
|
||||||
/// Call another service after call to this one has resolved successfully.
|
/// Call another service after call to this one has resolved successfully.
|
||||||
pub fn and_then<F, U>(
|
pub fn and_then<I, SF1>(
|
||||||
self,
|
self,
|
||||||
factory: F,
|
factory: I,
|
||||||
) -> PipelineFactory<
|
) -> PipelineFactory<
|
||||||
impl ServiceFactory<
|
impl ServiceFactory<
|
||||||
Request = T::Request,
|
Req,
|
||||||
Response = U::Response,
|
Response = SF1::Response,
|
||||||
Error = T::Error,
|
Error = SF::Error,
|
||||||
Config = T::Config,
|
Config = SF::Config,
|
||||||
InitError = T::InitError,
|
InitError = SF::InitError,
|
||||||
Service = impl Service<
|
Service = impl Service<Req, Response = SF1::Response, Error = SF::Error> + Clone,
|
||||||
Request = T::Request,
|
|
||||||
Response = U::Response,
|
|
||||||
Error = T::Error,
|
|
||||||
> + Clone,
|
|
||||||
> + Clone,
|
> + Clone,
|
||||||
|
Req,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
T::Config: Clone,
|
SF::Config: Clone,
|
||||||
F: IntoServiceFactory<U>,
|
I: IntoServiceFactory<SF1, SF::Response>,
|
||||||
U: ServiceFactory<
|
SF1: ServiceFactory<
|
||||||
Config = T::Config,
|
SF::Response,
|
||||||
Request = T::Response,
|
Config = SF::Config,
|
||||||
Error = T::Error,
|
Error = SF::Error,
|
||||||
InitError = T::InitError,
|
InitError = SF::InitError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: AndThenServiceFactory::new(self.factory, factory.into_factory()),
|
factory: AndThenServiceFactory::new(self.factory, factory.into_factory()),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply function to specified service and use it as a next service in
|
/// Apply function to specified service and use it as a next service in chain.
|
||||||
/// chain.
|
|
||||||
///
|
///
|
||||||
/// Short version of `pipeline_factory(...).and_then(apply_fn_factory(...))`
|
/// Short version of `pipeline_factory(...).and_then(apply_fn_factory(...))`
|
||||||
pub fn and_then_apply_fn<U, I, F, Fut, Res, Err>(
|
pub fn and_then_apply_fn<I, SF1, Fut, F, In, Res, Err>(
|
||||||
self,
|
self,
|
||||||
factory: I,
|
factory: I,
|
||||||
f: F,
|
wrap_fn: F,
|
||||||
) -> PipelineFactory<
|
) -> PipelineFactory<
|
||||||
impl ServiceFactory<
|
impl ServiceFactory<
|
||||||
Request = T::Request,
|
Req,
|
||||||
Response = Res,
|
Response = Res,
|
||||||
Error = Err,
|
Error = Err,
|
||||||
Config = T::Config,
|
Config = SF::Config,
|
||||||
InitError = T::InitError,
|
InitError = SF::InitError,
|
||||||
Service = impl Service<Request = T::Request, Response = Res, Error = Err> + Clone,
|
Service = impl Service<Req, Response = Res, Error = Err> + Clone,
|
||||||
> + Clone,
|
> + Clone,
|
||||||
|
Req,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
T::Config: Clone,
|
SF::Config: Clone,
|
||||||
I: IntoServiceFactory<U>,
|
I: IntoServiceFactory<SF1, In>,
|
||||||
U: ServiceFactory<Config = T::Config, InitError = T::InitError>,
|
SF1: ServiceFactory<In, Config = SF::Config, InitError = SF::InitError>,
|
||||||
F: FnMut(T::Response, &mut U::Service) -> Fut + Clone,
|
F: FnMut(SF::Response, &mut SF1::Service) -> Fut + Clone,
|
||||||
Fut: Future<Output = Result<Res, Err>>,
|
Fut: Future<Output = Result<Res, Err>>,
|
||||||
Err: From<T::Error> + From<U::Error>,
|
Err: From<SF::Error> + From<SF1::Error>,
|
||||||
{
|
{
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: AndThenApplyFnFactory::new(self.factory, factory.into_factory(), f),
|
factory: AndThenApplyFnFactory::new(self.factory, factory.into_factory(), wrap_fn),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,96 +258,103 @@ impl<T: ServiceFactory> PipelineFactory<T> {
|
|||||||
///
|
///
|
||||||
/// Note that this function consumes the receiving pipeline and returns a
|
/// Note that this function consumes the receiving pipeline and returns a
|
||||||
/// wrapped version of it.
|
/// wrapped version of it.
|
||||||
pub fn then<F, U>(
|
pub fn then<I, SF1>(
|
||||||
self,
|
self,
|
||||||
factory: F,
|
factory: I,
|
||||||
) -> PipelineFactory<
|
) -> PipelineFactory<
|
||||||
impl ServiceFactory<
|
impl ServiceFactory<
|
||||||
Request = T::Request,
|
Req,
|
||||||
Response = U::Response,
|
Response = SF1::Response,
|
||||||
Error = T::Error,
|
Error = SF::Error,
|
||||||
Config = T::Config,
|
Config = SF::Config,
|
||||||
InitError = T::InitError,
|
InitError = SF::InitError,
|
||||||
Service = impl Service<
|
Service = impl Service<Req, Response = SF1::Response, Error = SF::Error> + Clone,
|
||||||
Request = T::Request,
|
|
||||||
Response = U::Response,
|
|
||||||
Error = T::Error,
|
|
||||||
> + Clone,
|
|
||||||
> + Clone,
|
> + Clone,
|
||||||
|
Req,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
T::Config: Clone,
|
SF::Config: Clone,
|
||||||
F: IntoServiceFactory<U>,
|
I: IntoServiceFactory<SF1, Result<SF::Response, SF::Error>>,
|
||||||
U: ServiceFactory<
|
SF1: ServiceFactory<
|
||||||
Config = T::Config,
|
Result<SF::Response, SF::Error>,
|
||||||
Request = Result<T::Response, T::Error>,
|
Config = SF::Config,
|
||||||
Error = T::Error,
|
Error = SF::Error,
|
||||||
InitError = T::InitError,
|
InitError = SF::InitError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: ThenServiceFactory::new(self.factory, factory.into_factory()),
|
factory: ThenServiceFactory::new(self.factory, factory.into_factory()),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map this service's output to a different type, returning a new service
|
/// Map this service's output to a different type, returning a new service
|
||||||
/// of the resulting type.
|
/// of the resulting type.
|
||||||
pub fn map<F, R>(self, f: F) -> PipelineFactory<MapServiceFactory<T, F, R>>
|
pub fn map<F, R>(self, f: F) -> PipelineFactory<MapServiceFactory<SF, F, Req, R>, Req>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnMut(T::Response) -> R + Clone,
|
F: FnMut(SF::Response) -> R + Clone,
|
||||||
{
|
{
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: MapServiceFactory::new(self.factory, f),
|
factory: MapServiceFactory::new(self.factory, f),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map this service's error to a different error, returning a new service.
|
/// Map this service's error to a different error, returning a new service.
|
||||||
pub fn map_err<F, E>(self, f: F) -> PipelineFactory<MapErrServiceFactory<T, F, E>>
|
pub fn map_err<F, E>(
|
||||||
|
self,
|
||||||
|
f: F,
|
||||||
|
) -> PipelineFactory<MapErrServiceFactory<SF, Req, F, E>, Req>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(T::Error) -> E + Clone,
|
F: Fn(SF::Error) -> E + Clone,
|
||||||
{
|
{
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: MapErrServiceFactory::new(self.factory, f),
|
factory: MapErrServiceFactory::new(self.factory, f),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map this factory's init error to a different error, returning a new service.
|
/// Map this factory's init error to a different error, returning a new service.
|
||||||
pub fn map_init_err<F, E>(self, f: F) -> PipelineFactory<MapInitErr<T, F, E>>
|
pub fn map_init_err<F, E>(self, f: F) -> PipelineFactory<MapInitErr<SF, F, Req, E>, Req>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(T::InitError) -> E + Clone,
|
F: Fn(SF::InitError) -> E + Clone,
|
||||||
{
|
{
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: MapInitErr::new(self.factory, f),
|
factory: MapInitErr::new(self.factory, f),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Clone for PipelineFactory<T>
|
impl<T, Req> Clone for PipelineFactory<T, Req>
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
PipelineFactory {
|
PipelineFactory {
|
||||||
factory: self.factory.clone(),
|
factory: self.factory.clone(),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ServiceFactory> ServiceFactory for PipelineFactory<T> {
|
impl<SF, Req> ServiceFactory<Req> for PipelineFactory<SF, Req>
|
||||||
type Config = T::Config;
|
where
|
||||||
type Request = T::Request;
|
SF: ServiceFactory<Req>,
|
||||||
type Response = T::Response;
|
{
|
||||||
type Error = T::Error;
|
type Config = SF::Config;
|
||||||
type Service = T::Service;
|
type Response = SF::Response;
|
||||||
type InitError = T::InitError;
|
type Error = SF::Error;
|
||||||
type Future = T::Future;
|
type Service = SF::Service;
|
||||||
|
type InitError = SF::InitError;
|
||||||
|
type Future = SF::Future;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new_service(&self, cfg: T::Config) -> Self::Future {
|
fn new_service(&self, cfg: SF::Config) -> Self::Future {
|
||||||
self.factory.new_service(cfg)
|
self.factory.new_service(cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
use std::{cell::RefCell, marker::PhantomData};
|
||||||
|
|
||||||
use super::{Service, ServiceFactory};
|
use super::{Service, ServiceFactory};
|
||||||
|
|
||||||
@ -10,34 +10,33 @@ use super::{Service, ServiceFactory};
|
|||||||
/// another service.
|
/// another service.
|
||||||
///
|
///
|
||||||
/// This is created by the `Pipeline::then` method.
|
/// This is created by the `Pipeline::then` method.
|
||||||
pub(crate) struct ThenService<A, B>(Rc<RefCell<(A, B)>>);
|
pub(crate) struct ThenService<A, B, Req>(Rc<RefCell<(A, B)>>, PhantomData<Req>);
|
||||||
|
|
||||||
impl<A, B> ThenService<A, B> {
|
impl<A, B, Req> ThenService<A, B, Req> {
|
||||||
/// Create new `.then()` combinator
|
/// Create new `.then()` combinator
|
||||||
pub(crate) fn new(a: A, b: B) -> ThenService<A, B>
|
pub(crate) fn new(a: A, b: B) -> ThenService<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>,
|
B: Service<Result<A::Response, A::Error>, Error = A::Error>,
|
||||||
{
|
{
|
||||||
Self(Rc::new(RefCell::new((a, b))))
|
Self(Rc::new(RefCell::new((a, b))), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for ThenService<A, B> {
|
impl<A, B, Req> Clone for ThenService<A, B, Req> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
ThenService(self.0.clone())
|
ThenService(self.0.clone(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Service for ThenService<A, B>
|
impl<A, B, Req> Service<Req> for ThenService<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = Result<A::Response, A::Error>, Error = A::Error>,
|
B: Service<Result<A::Response, A::Error>, Error = A::Error>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = B::Error;
|
type Error = B::Error;
|
||||||
type Future = ThenServiceResponse<A, B>;
|
type Future = ThenServiceResponse<A, B, Req>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
let mut srv = self.0.borrow_mut();
|
let mut srv = self.0.borrow_mut();
|
||||||
@ -49,7 +48,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: A::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
ThenServiceResponse {
|
ThenServiceResponse {
|
||||||
state: State::A(self.0.borrow_mut().0.call(req), Some(self.0.clone())),
|
state: State::A(self.0.borrow_mut().0.call(req), Some(self.0.clone())),
|
||||||
}
|
}
|
||||||
@ -57,30 +56,30 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct ThenServiceResponse<A, B>
|
pub(crate) struct ThenServiceResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = Result<A::Response, A::Error>>,
|
B: Service<Result<A::Response, A::Error>>,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
state: State<A, B>,
|
state: State<A, B, Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = StateProj)]
|
#[pin_project::pin_project(project = StateProj)]
|
||||||
enum State<A, B>
|
enum State<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = Result<A::Response, A::Error>>,
|
B: Service<Result<A::Response, A::Error>>,
|
||||||
{
|
{
|
||||||
A(#[pin] A::Future, Option<Rc<RefCell<(A, B)>>>),
|
A(#[pin] A::Future, Option<Rc<RefCell<(A, B)>>>),
|
||||||
B(#[pin] B::Future),
|
B(#[pin] B::Future),
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Future for ThenServiceResponse<A, B>
|
impl<A, B, Req> Future for ThenServiceResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: Service,
|
A: Service<Req>,
|
||||||
B: Service<Request = Result<A::Response, A::Error>>,
|
B: Service<Result<A::Response, A::Error>>,
|
||||||
{
|
{
|
||||||
type Output = Result<B::Response, B::Error>;
|
type Output = Result<B::Response, B::Error>;
|
||||||
|
|
||||||
@ -110,44 +109,43 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// `.then()` service factory combinator
|
/// `.then()` service factory combinator
|
||||||
pub(crate) struct ThenServiceFactory<A, B>(Rc<(A, B)>);
|
pub(crate) struct ThenServiceFactory<A, B, Req>(Rc<(A, B)>, PhantomData<Req>);
|
||||||
|
|
||||||
impl<A, B> ThenServiceFactory<A, B>
|
impl<A, B, Req> ThenServiceFactory<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
A::Config: Clone,
|
A::Config: Clone,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
Result<A::Response, A::Error>,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = Result<A::Response, A::Error>,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
/// Create new `AndThen` combinator
|
/// Create new `AndThen` combinator
|
||||||
pub(crate) fn new(a: A, b: B) -> Self {
|
pub(crate) fn new(a: A, b: B) -> Self {
|
||||||
Self(Rc::new((a, b)))
|
Self(Rc::new((a, b)), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> ServiceFactory for ThenServiceFactory<A, B>
|
impl<A, B, Req> ServiceFactory<Req> for ThenServiceFactory<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
A::Config: Clone,
|
A::Config: Clone,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
Result<A::Response, A::Error>,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = Result<A::Response, A::Error>,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
type Response = B::Response;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
|
|
||||||
type Config = A::Config;
|
type Config = A::Config;
|
||||||
type Service = ThenService<A::Service, B::Service>;
|
type Service = ThenService<A::Service, B::Service, Req>;
|
||||||
type InitError = A::InitError;
|
type InitError = A::InitError;
|
||||||
type Future = ThenServiceFactoryResponse<A, B>;
|
type Future = ThenServiceFactoryResponse<A, B, Req>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
||||||
let srv = &*self.0;
|
let srv = &*self.0;
|
||||||
@ -155,19 +153,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for ThenServiceFactory<A, B> {
|
impl<A, B, Req> Clone for ThenServiceFactory<A, B, Req> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.clone())
|
Self(self.0.clone(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub(crate) struct ThenServiceFactoryResponse<A, B>
|
pub(crate) struct ThenServiceFactoryResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
Result<A::Response, A::Error>,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = Result<A::Response, A::Error>,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
@ -180,12 +178,12 @@ where
|
|||||||
b: Option<B::Service>,
|
b: Option<B::Service>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> ThenServiceFactoryResponse<A, B>
|
impl<A, B, Req> ThenServiceFactoryResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
Result<A::Response, A::Error>,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = Result<A::Response, A::Error>,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
@ -200,17 +198,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Future for ThenServiceFactoryResponse<A, B>
|
impl<A, B, Req> Future for ThenServiceFactoryResponse<A, B, Req>
|
||||||
where
|
where
|
||||||
A: ServiceFactory,
|
A: ServiceFactory<Req>,
|
||||||
B: ServiceFactory<
|
B: ServiceFactory<
|
||||||
|
Result<A::Response, A::Error>,
|
||||||
Config = A::Config,
|
Config = A::Config,
|
||||||
Request = Result<A::Response, A::Error>,
|
|
||||||
Error = A::Error,
|
Error = A::Error,
|
||||||
InitError = A::InitError,
|
InitError = A::InitError,
|
||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
type Output = Result<ThenService<A::Service, B::Service>, A::InitError>;
|
type Output = Result<ThenService<A::Service, B::Service, Req>, A::InitError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
@ -249,8 +247,7 @@ mod tests {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Srv1(Rc<Cell<usize>>);
|
struct Srv1(Rc<Cell<usize>>);
|
||||||
|
|
||||||
impl Service for Srv1 {
|
impl Service<Result<&'static str, &'static str>> for Srv1 {
|
||||||
type Request = Result<&'static str, &'static str>;
|
|
||||||
type Response = &'static str;
|
type Response = &'static str;
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<Self::Response, Self::Error>>;
|
type Future = Ready<Result<Self::Response, Self::Error>>;
|
||||||
@ -270,8 +267,7 @@ mod tests {
|
|||||||
|
|
||||||
struct Srv2(Rc<Cell<usize>>);
|
struct Srv2(Rc<Cell<usize>>);
|
||||||
|
|
||||||
impl Service for Srv2 {
|
impl Service<Result<&'static str, ()>> for Srv2 {
|
||||||
type Request = Result<&'static str, ()>;
|
|
||||||
type Response = (&'static str, &'static str);
|
type Response = (&'static str, &'static str);
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = Ready<Result<Self::Response, ()>>;
|
type Future = Ready<Result<Self::Response, ()>>;
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
use std::{future::Future, marker::PhantomData};
|
||||||
|
|
||||||
use crate::transform_err::TransformMapInitErr;
|
use crate::transform_err::TransformMapInitErr;
|
||||||
use crate::{IntoServiceFactory, Service, ServiceFactory};
|
use crate::{IntoServiceFactory, Service, ServiceFactory};
|
||||||
|
|
||||||
/// Apply transform to a service.
|
/// Apply transform to a service.
|
||||||
pub fn apply<T, S, U>(t: T, factory: U) -> ApplyTransform<T, S>
|
pub fn apply<T, S, I, Req>(t: T, factory: I) -> ApplyTransform<T, S, Req>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
I: IntoServiceFactory<S, Req>,
|
||||||
T: Transform<S::Service, InitError = S::InitError>,
|
S: ServiceFactory<Req>,
|
||||||
U: IntoServiceFactory<S>,
|
T: Transform<S::Service, Req, InitError = S::InitError>,
|
||||||
{
|
{
|
||||||
ApplyTransform::new(t, factory.into_factory())
|
ApplyTransform::new(t, factory.into_factory())
|
||||||
}
|
}
|
||||||
@ -89,10 +89,7 @@ where
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub trait Transform<S> {
|
pub trait Transform<S, Req> {
|
||||||
/// Requests handled by the service.
|
|
||||||
type Request;
|
|
||||||
|
|
||||||
/// Responses given by the service.
|
/// Responses given by the service.
|
||||||
type Response;
|
type Response;
|
||||||
|
|
||||||
@ -100,11 +97,7 @@ pub trait Transform<S> {
|
|||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
/// The `TransformService` value created by this factory
|
/// The `TransformService` value created by this factory
|
||||||
type Transform: Service<
|
type Transform: Service<Req, Response = Self::Response, Error = Self::Error>;
|
||||||
Request = Self::Request,
|
|
||||||
Response = Self::Response,
|
|
||||||
Error = Self::Error,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// Errors produced while building a transform service.
|
/// Errors produced while building a transform service.
|
||||||
type InitError;
|
type InitError;
|
||||||
@ -117,7 +110,7 @@ pub trait Transform<S> {
|
|||||||
|
|
||||||
/// Map this transform's factory error to a different error,
|
/// Map this transform's factory error to a different error,
|
||||||
/// returning a new transform service factory.
|
/// returning a new transform service factory.
|
||||||
fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, F, E>
|
fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, Req, F, E>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: Fn(Self::InitError) -> E + Clone,
|
F: Fn(Self::InitError) -> E + Clone,
|
||||||
@ -126,11 +119,10 @@ pub trait Transform<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S> Transform<S> for Rc<T>
|
impl<T, S, Req> Transform<S, Req> for Rc<T>
|
||||||
where
|
where
|
||||||
T: Transform<S>,
|
T: Transform<S, Req>,
|
||||||
{
|
{
|
||||||
type Request = T::Request;
|
|
||||||
type Response = T::Response;
|
type Response = T::Response;
|
||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
type InitError = T::InitError;
|
type InitError = T::InitError;
|
||||||
@ -142,11 +134,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S> Transform<S> for Arc<T>
|
impl<T, S, Req> Transform<S, Req> for Arc<T>
|
||||||
where
|
where
|
||||||
T: Transform<S>,
|
T: Transform<S, Req>,
|
||||||
{
|
{
|
||||||
type Request = T::Request;
|
|
||||||
type Response = T::Response;
|
type Response = T::Response;
|
||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
type InitError = T::InitError;
|
type InitError = T::InitError;
|
||||||
@ -159,38 +150,37 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// `Apply` transform to new service
|
/// `Apply` transform to new service
|
||||||
pub struct ApplyTransform<T, S>(Rc<(T, S)>);
|
pub struct ApplyTransform<T, S, Req>(Rc<(T, S)>, PhantomData<Req>);
|
||||||
|
|
||||||
impl<T, S> ApplyTransform<T, S>
|
impl<T, S, Req> ApplyTransform<T, S, Req>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
S: ServiceFactory<Req>,
|
||||||
T: Transform<S::Service, InitError = S::InitError>,
|
T: Transform<S::Service, Req, InitError = S::InitError>,
|
||||||
{
|
{
|
||||||
/// Create new `ApplyTransform` new service instance
|
/// Create new `ApplyTransform` new service instance
|
||||||
fn new(t: T, service: S) -> Self {
|
fn new(t: T, service: S) -> Self {
|
||||||
Self(Rc::new((t, service)))
|
Self(Rc::new((t, service)), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S> Clone for ApplyTransform<T, S> {
|
impl<T, S, Req> Clone for ApplyTransform<T, S, Req> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
ApplyTransform(self.0.clone())
|
ApplyTransform(self.0.clone(), PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S> ServiceFactory for ApplyTransform<T, S>
|
impl<T, S, Req> ServiceFactory<Req> for ApplyTransform<T, S, Req>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
S: ServiceFactory<Req>,
|
||||||
T: Transform<S::Service, InitError = S::InitError>,
|
T: Transform<S::Service, Req, InitError = S::InitError>,
|
||||||
{
|
{
|
||||||
type Request = T::Request;
|
|
||||||
type Response = T::Response;
|
type Response = T::Response;
|
||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
|
|
||||||
type Config = S::Config;
|
type Config = S::Config;
|
||||||
type Service = T::Transform;
|
type Service = T::Transform;
|
||||||
type InitError = T::InitError;
|
type InitError = T::InitError;
|
||||||
type Future = ApplyTransformFuture<T, S>;
|
type Future = ApplyTransformFuture<T, S, Req>;
|
||||||
|
|
||||||
fn new_service(&self, cfg: S::Config) -> Self::Future {
|
fn new_service(&self, cfg: S::Config) -> Self::Future {
|
||||||
ApplyTransformFuture {
|
ApplyTransformFuture {
|
||||||
@ -201,30 +191,30 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct ApplyTransformFuture<T, S>
|
pub struct ApplyTransformFuture<T, S, Req>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
S: ServiceFactory<Req>,
|
||||||
T: Transform<S::Service, InitError = S::InitError>,
|
T: Transform<S::Service, Req, InitError = S::InitError>,
|
||||||
{
|
{
|
||||||
store: Rc<(T, S)>,
|
store: Rc<(T, S)>,
|
||||||
#[pin]
|
#[pin]
|
||||||
state: ApplyTransformFutureState<T, S>,
|
state: ApplyTransformFutureState<T, S, Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project(project = ApplyTransformFutureStateProj)]
|
#[pin_project::pin_project(project = ApplyTransformFutureStateProj)]
|
||||||
pub enum ApplyTransformFutureState<T, S>
|
pub enum ApplyTransformFutureState<T, S, Req>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
S: ServiceFactory<Req>,
|
||||||
T: Transform<S::Service, InitError = S::InitError>,
|
T: Transform<S::Service, Req, InitError = S::InitError>,
|
||||||
{
|
{
|
||||||
A(#[pin] S::Future),
|
A(#[pin] S::Future),
|
||||||
B(#[pin] T::Future),
|
B(#[pin] T::Future),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S> Future for ApplyTransformFuture<T, S>
|
impl<T, S, Req> Future for ApplyTransformFuture<T, S, Req>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
S: ServiceFactory<Req>,
|
||||||
T: Transform<S::Service, InitError = S::InitError>,
|
T: Transform<S::Service, Req, InitError = S::InitError>,
|
||||||
{
|
{
|
||||||
type Output = Result<T::Transform, T::InitError>;
|
type Output = Result<T::Transform, T::InitError>;
|
||||||
|
|
||||||
|
@ -9,65 +9,64 @@ use super::Transform;
|
|||||||
/// transform's init error.
|
/// transform's init error.
|
||||||
///
|
///
|
||||||
/// This is created by the `Transform::map_init_err` method.
|
/// This is created by the `Transform::map_init_err` method.
|
||||||
pub struct TransformMapInitErr<T, S, F, E> {
|
pub struct TransformMapInitErr<T, S, Req, F, E> {
|
||||||
t: T,
|
transform: T,
|
||||||
f: F,
|
mapper: F,
|
||||||
e: PhantomData<(S, E)>,
|
_phantom: PhantomData<(S, Req, E)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, E> TransformMapInitErr<T, S, F, E> {
|
impl<T, S, F, E, Req> TransformMapInitErr<T, S, Req, F, E> {
|
||||||
pub(crate) fn new(t: T, f: F) -> Self
|
pub(crate) fn new(t: T, f: F) -> Self
|
||||||
where
|
where
|
||||||
T: Transform<S>,
|
T: Transform<S, Req>,
|
||||||
F: Fn(T::InitError) -> E,
|
F: Fn(T::InitError) -> E,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
t,
|
transform: t,
|
||||||
f,
|
mapper: f,
|
||||||
e: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, E> Clone for TransformMapInitErr<T, S, F, E>
|
impl<T, S, Req, F, E> Clone for TransformMapInitErr<T, S, Req, F, E>
|
||||||
where
|
where
|
||||||
T: Clone,
|
T: Clone,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
t: self.t.clone(),
|
transform: self.transform.clone(),
|
||||||
f: self.f.clone(),
|
mapper: self.mapper.clone(),
|
||||||
e: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, E> Transform<S> for TransformMapInitErr<T, S, F, E>
|
impl<T, S, F, E, Req> Transform<S, Req> for TransformMapInitErr<T, S, Req, F, E>
|
||||||
where
|
where
|
||||||
T: Transform<S>,
|
T: Transform<S, Req>,
|
||||||
F: Fn(T::InitError) -> E + Clone,
|
F: Fn(T::InitError) -> E + Clone,
|
||||||
{
|
{
|
||||||
type Request = T::Request;
|
|
||||||
type Response = T::Response;
|
type Response = T::Response;
|
||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
type Transform = T::Transform;
|
type Transform = T::Transform;
|
||||||
|
|
||||||
type InitError = E;
|
type InitError = E;
|
||||||
type Future = TransformMapInitErrFuture<T, S, F, E>;
|
type Future = TransformMapInitErrFuture<T, S, F, E, Req>;
|
||||||
|
|
||||||
fn new_transform(&self, service: S) -> Self::Future {
|
fn new_transform(&self, service: S) -> Self::Future {
|
||||||
TransformMapInitErrFuture {
|
TransformMapInitErrFuture {
|
||||||
fut: self.t.new_transform(service),
|
fut: self.transform.new_transform(service),
|
||||||
f: self.f.clone(),
|
f: self.mapper.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
#[pin_project::pin_project]
|
||||||
pub struct TransformMapInitErrFuture<T, S, F, E>
|
pub struct TransformMapInitErrFuture<T, S, F, E, Req>
|
||||||
where
|
where
|
||||||
T: Transform<S>,
|
T: Transform<S, Req>,
|
||||||
F: Fn(T::InitError) -> E,
|
F: Fn(T::InitError) -> E,
|
||||||
{
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
@ -75,9 +74,9 @@ where
|
|||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, E> Future for TransformMapInitErrFuture<T, S, F, E>
|
impl<T, S, F, E, Req> Future for TransformMapInitErrFuture<T, S, F, E, Req>
|
||||||
where
|
where
|
||||||
T: Transform<S>,
|
T: Transform<S, Req>,
|
||||||
F: Fn(T::InitError) -> E + Clone,
|
F: Fn(T::InitError) -> E + Clone,
|
||||||
{
|
{
|
||||||
type Output = Result<T::Transform, E>;
|
type Output = Result<T::Transform, E>;
|
||||||
|
@ -27,12 +27,11 @@ impl<S, F> TracingService<S, F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, F> Service for TracingService<S, F>
|
impl<S, Req, F> Service<Req> for TracingService<S, F>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
F: Fn(&S::Request) -> Option<tracing::Span>,
|
F: Fn(&Req) -> Option<tracing::Span>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Future = Either<S::Future, Instrumented<S::Future>>;
|
type Future = Either<S::Future, Instrumented<S::Future>>;
|
||||||
@ -41,7 +40,7 @@ where
|
|||||||
self.inner.poll_ready(ctx)
|
self.inner.poll_ready(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
let span = (self.make_span)(&req);
|
let span = (self.make_span)(&req);
|
||||||
let _enter = span.as_ref().map(|s| s.enter());
|
let _enter = span.as_ref().map(|s| s.enter());
|
||||||
|
|
||||||
@ -74,18 +73,12 @@ impl<S, U, F> TracingTransform<S, U, F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, U, F> Transform<S> for TracingTransform<S, U, F>
|
impl<S, Req, U, F> Transform<S, Req> for TracingTransform<S, U, F>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
U: ServiceFactory<
|
U: ServiceFactory<Req, Response = S::Response, Error = S::Error, Service = S>,
|
||||||
Request = S::Request,
|
F: Fn(&Req) -> Option<tracing::Span> + Clone,
|
||||||
Response = S::Response,
|
|
||||||
Error = S::Error,
|
|
||||||
Service = S,
|
|
||||||
>,
|
|
||||||
F: Fn(&S::Request) -> Option<tracing::Span> + Clone,
|
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = S::Error;
|
type Error = S::Error;
|
||||||
type Transform = TracingService<S, F>;
|
type Transform = TracingService<S, F>;
|
||||||
@ -110,14 +103,14 @@ where
|
|||||||
/// |req: &Request| Some(span!(Level::INFO, "request", req.id))
|
/// |req: &Request| Some(span!(Level::INFO, "request", req.id))
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn trace<S, U, F>(
|
pub fn trace<S, Req, I, F>(
|
||||||
service_factory: U,
|
service_factory: I,
|
||||||
make_span: F,
|
make_span: F,
|
||||||
) -> ApplyTransform<TracingTransform<S::Service, S, F>, S>
|
) -> ApplyTransform<TracingTransform<S::Service, S, F>, S, Req>
|
||||||
where
|
where
|
||||||
S: ServiceFactory,
|
I: IntoServiceFactory<S, Req>,
|
||||||
F: Fn(&S::Request) -> Option<tracing::Span> + Clone,
|
S: ServiceFactory<Req>,
|
||||||
U: IntoServiceFactory<S>,
|
F: Fn(&Req) -> Option<tracing::Span> + Clone,
|
||||||
{
|
{
|
||||||
apply(
|
apply(
|
||||||
TracingTransform::new(make_span),
|
TracingTransform::new(make_span),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-utils"
|
name = "actix-utils"
|
||||||
version = "3.0.0"
|
version = "2.0.0"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Various network related services and utilities for the Actix ecosystem."
|
description = "Various network related services and utilities for the Actix ecosystem."
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! Framed dispatcher service and related utilities
|
//! Framed dispatcher service and related utilities.
|
||||||
|
|
||||||
#![allow(type_alias_bounds)]
|
#![allow(type_alias_bounds)]
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed};
|
|||||||
use actix_service::{IntoService, Service};
|
use actix_service::{IntoService, Service};
|
||||||
use futures_core::stream::Stream;
|
use futures_core::stream::Stream;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
use crate::mpsc;
|
use crate::mpsc;
|
||||||
|
|
||||||
@ -62,12 +63,12 @@ pub enum Message<T> {
|
|||||||
Close,
|
Close,
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project! {
|
||||||
/// Dispatcher is a future that reads frames from Framed object
|
/// Dispatcher is a future that reads frames from Framed object
|
||||||
/// and passes them to the service.
|
/// and passes them to the service.
|
||||||
pub struct Dispatcher<S, T, U, I>
|
pub struct Dispatcher<S, T, U, I>
|
||||||
where
|
where
|
||||||
S: Service<Request = <U as Decoder>::Item, Response = I>,
|
S: Service<<U as Decoder>::Item, Response = I>,
|
||||||
S::Error: 'static,
|
S::Error: 'static,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
T: AsyncRead,
|
T: AsyncRead,
|
||||||
@ -86,7 +87,11 @@ pin_project_lite::pin_project! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State<S: Service, U: Encoder<I> + Decoder, I> {
|
enum State<S, U, I>
|
||||||
|
where
|
||||||
|
S: Service<<U as Decoder>::Item>,
|
||||||
|
U: Encoder<I> + Decoder,
|
||||||
|
{
|
||||||
Processing,
|
Processing,
|
||||||
Error(DispatcherError<S::Error, U, I>),
|
Error(DispatcherError<S::Error, U, I>),
|
||||||
FramedError(DispatcherError<S::Error, U, I>),
|
FramedError(DispatcherError<S::Error, U, I>),
|
||||||
@ -94,7 +99,11 @@ enum State<S: Service, U: Encoder<I> + Decoder, I> {
|
|||||||
Stopping,
|
Stopping,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Service, U: Encoder<I> + Decoder, I> State<S, U, I> {
|
impl<S, U, I> State<S, U, I>
|
||||||
|
where
|
||||||
|
S: Service<<U as Decoder>::Item>,
|
||||||
|
U: Encoder<I> + Decoder,
|
||||||
|
{
|
||||||
fn take_error(&mut self) -> DispatcherError<S::Error, U, I> {
|
fn take_error(&mut self) -> DispatcherError<S::Error, U, I> {
|
||||||
match mem::replace(self, State::Processing) {
|
match mem::replace(self, State::Processing) {
|
||||||
State::Error(err) => err,
|
State::Error(err) => err,
|
||||||
@ -112,7 +121,7 @@ impl<S: Service, U: Encoder<I> + Decoder, I> State<S, U, I> {
|
|||||||
|
|
||||||
impl<S, T, U, I> Dispatcher<S, T, U, I>
|
impl<S, T, U, I> Dispatcher<S, T, U, I>
|
||||||
where
|
where
|
||||||
S: Service<Request = <U as Decoder>::Item, Response = I>,
|
S: Service<<U as Decoder>::Item, Response = I>,
|
||||||
S::Error: 'static,
|
S::Error: 'static,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
@ -121,7 +130,10 @@ where
|
|||||||
<U as Decoder>::Error: fmt::Debug,
|
<U as Decoder>::Error: fmt::Debug,
|
||||||
<U as Encoder<I>>::Error: fmt::Debug,
|
<U as Encoder<I>>::Error: fmt::Debug,
|
||||||
{
|
{
|
||||||
pub fn new<F: IntoService<S>>(framed: Framed<T, U>, service: F) -> Self {
|
pub fn new<F>(framed: Framed<T, U>, service: F) -> Self
|
||||||
|
where
|
||||||
|
F: IntoService<S, <U as Decoder>::Item>,
|
||||||
|
{
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
Dispatcher {
|
Dispatcher {
|
||||||
framed,
|
framed,
|
||||||
@ -133,11 +145,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Construct new `Dispatcher` instance with customer `mpsc::Receiver`
|
/// Construct new `Dispatcher` instance with customer `mpsc::Receiver`
|
||||||
pub fn with_rx<F: IntoService<S>>(
|
pub fn with_rx<F>(
|
||||||
framed: Framed<T, U>,
|
framed: Framed<T, U>,
|
||||||
service: F,
|
service: F,
|
||||||
rx: mpsc::Receiver<Result<Message<I>, S::Error>>,
|
rx: mpsc::Receiver<Result<Message<I>, S::Error>>,
|
||||||
) -> Self {
|
) -> Self
|
||||||
|
where
|
||||||
|
F: IntoService<S, <U as Decoder>::Item>,
|
||||||
|
{
|
||||||
let tx = rx.sender();
|
let tx = rx.sender();
|
||||||
Dispatcher {
|
Dispatcher {
|
||||||
framed,
|
framed,
|
||||||
@ -176,7 +191,7 @@ where
|
|||||||
|
|
||||||
fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
|
fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
|
||||||
where
|
where
|
||||||
S: Service<Request = <U as Decoder>::Item, Response = I>,
|
S: Service<<U as Decoder>::Item, Response = I>,
|
||||||
S::Error: 'static,
|
S::Error: 'static,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
@ -220,7 +235,7 @@ where
|
|||||||
/// write to framed object
|
/// write to framed object
|
||||||
fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
|
fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
|
||||||
where
|
where
|
||||||
S: Service<Request = <U as Decoder>::Item, Response = I>,
|
S: Service<<U as Decoder>::Item, Response = I>,
|
||||||
S::Error: 'static,
|
S::Error: 'static,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
@ -271,7 +286,7 @@ where
|
|||||||
|
|
||||||
impl<S, T, U, I> Future for Dispatcher<S, T, U, I>
|
impl<S, T, U, I> Future for Dispatcher<S, T, U, I>
|
||||||
where
|
where
|
||||||
S: Service<Request = <U as Decoder>::Item, Response = I>,
|
S: Service<<U as Decoder>::Item, Response = I>,
|
||||||
S::Error: 'static,
|
S::Error: 'static,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! If the response does not complete within the specified timeout, the response
|
//! If the response does not complete within the specified timeout, the response
|
||||||
//! will be aborted.
|
//! will be aborted.
|
||||||
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
@ -10,6 +11,7 @@ use core::{fmt, time};
|
|||||||
|
|
||||||
use actix_rt::time::{delay_for, Delay};
|
use actix_rt::time::{delay_for, Delay};
|
||||||
use actix_service::{IntoService, Service, Transform};
|
use actix_service::{IntoService, Service, Transform};
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
/// Applies a timeout to requests.
|
/// Applies a timeout to requests.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -77,21 +79,21 @@ impl<E> Clone for Timeout<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, E> Transform<S> for Timeout<E>
|
impl<S, E, Req> Transform<S, Req> for Timeout<E>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = TimeoutError<S::Error>;
|
type Error = TimeoutError<S::Error>;
|
||||||
type Transform = TimeoutService<S>;
|
|
||||||
type InitError = E;
|
type InitError = E;
|
||||||
|
type Transform = TimeoutService<S, Req>;
|
||||||
type Future = TimeoutFuture<Self::Transform, Self::InitError>;
|
type Future = TimeoutFuture<Self::Transform, Self::InitError>;
|
||||||
|
|
||||||
fn new_transform(&self, service: S) -> Self::Future {
|
fn new_transform(&self, service: S) -> Self::Future {
|
||||||
let service = TimeoutService {
|
let service = TimeoutService {
|
||||||
service,
|
service,
|
||||||
timeout: self.timeout,
|
timeout: self.timeout,
|
||||||
|
_phantom: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
TimeoutFuture {
|
TimeoutFuture {
|
||||||
@ -118,40 +120,41 @@ impl<T, E> Future for TimeoutFuture<T, E> {
|
|||||||
|
|
||||||
/// Applies a timeout to requests.
|
/// Applies a timeout to requests.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TimeoutService<S> {
|
pub struct TimeoutService<S, Req> {
|
||||||
service: S,
|
service: S,
|
||||||
timeout: time::Duration,
|
timeout: time::Duration,
|
||||||
|
_phantom: PhantomData<Req>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> TimeoutService<S>
|
impl<S, Req> TimeoutService<S, Req>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
pub fn new<U>(timeout: time::Duration, service: U) -> Self
|
pub fn new<U>(timeout: time::Duration, service: U) -> Self
|
||||||
where
|
where
|
||||||
U: IntoService<S>,
|
U: IntoService<S, Req>,
|
||||||
{
|
{
|
||||||
TimeoutService {
|
TimeoutService {
|
||||||
timeout,
|
timeout,
|
||||||
service: service.into_service(),
|
service: service.into_service(),
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Service for TimeoutService<S>
|
impl<S, Req> Service<Req> for TimeoutService<S, Req>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
type Response = S::Response;
|
||||||
type Error = TimeoutError<S::Error>;
|
type Error = TimeoutError<S::Error>;
|
||||||
type Future = TimeoutServiceResponse<S>;
|
type Future = TimeoutServiceResponse<S, Req>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
self.service.poll_ready(cx).map_err(TimeoutError::Service)
|
self.service.poll_ready(cx).map_err(TimeoutError::Service)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, request: S::Request) -> Self::Future {
|
fn call(&mut self, request: Req) -> Self::Future {
|
||||||
TimeoutServiceResponse {
|
TimeoutServiceResponse {
|
||||||
fut: self.service.call(request),
|
fut: self.service.call(request),
|
||||||
sleep: delay_for(self.timeout),
|
sleep: delay_for(self.timeout),
|
||||||
@ -159,21 +162,24 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_project_lite::pin_project! {
|
pin_project! {
|
||||||
/// `TimeoutService` response future
|
/// `TimeoutService` response future
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TimeoutServiceResponse<T: Service> {
|
pub struct TimeoutServiceResponse<S, Req>
|
||||||
|
where
|
||||||
|
S: Service<Req>
|
||||||
|
{
|
||||||
#[pin]
|
#[pin]
|
||||||
fut: T::Future,
|
fut: S::Future,
|
||||||
sleep: Delay,
|
sleep: Delay,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Future for TimeoutServiceResponse<T>
|
impl<S, Req> Future for TimeoutServiceResponse<S, Req>
|
||||||
where
|
where
|
||||||
T: Service,
|
S: Service<Req>,
|
||||||
{
|
{
|
||||||
type Output = Result<T::Response, TimeoutError<T::Error>>;
|
type Output = Result<S::Response, TimeoutError<S::Error>>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
@ -204,8 +210,7 @@ mod tests {
|
|||||||
|
|
||||||
struct SleepService(Duration);
|
struct SleepService(Duration);
|
||||||
|
|
||||||
impl Service for SleepService {
|
impl Service<()> for SleepService {
|
||||||
type Request = ();
|
|
||||||
type Response = ();
|
type Response = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
type Future = LocalBoxFuture<'static, Result<(), ()>>;
|
type Future = LocalBoxFuture<'static, Result<(), ()>>;
|
||||||
|
Loading…
Reference in New Issue
Block a user