drop IntoFuture trait

This commit is contained in:
Nikolay Kim 2019-11-11 13:35:35 +06:00
parent 68e00ec18c
commit ae40042ea7
6 changed files with 189 additions and 324 deletions

View File

@ -4,28 +4,31 @@ use std::marker::PhantomData;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use super::IntoFuture;
use super::{Factory, IntoFactory, IntoService, Service}; use super::{Factory, IntoFactory, IntoService, Service};
/// Apply tranform function to a service /// Apply tranform function to a service
pub fn apply_fn<T, F, In, Out, U>(service: U, f: F) -> Apply<T, F, In, Out> pub fn apply_fn<T, F, R, In, Out, Err, U>(
service: U,
f: F,
) -> impl Service<Request = In, Response = Out, Error = Err>
where where
T: Service, T: Service<Error = Err>,
F: FnMut(In, &mut T) -> Out, F: FnMut(In, &mut T) -> R,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
Out::Error: From<T::Error>,
U: IntoService<T>, U: IntoService<T>,
{ {
Apply::new(service.into_service(), f) Apply::new(service.into_service(), f)
} }
/// Create factory for `apply` service. /// Create factory for `apply` service.
pub fn apply_fn_factory<T, F, In, Out, U>(service: U, f: F) -> ApplyNewService<T, F, In, Out> pub fn apply_fn_factory<T, F, R, In, Out, Err, U>(
service: U,
f: F,
) -> impl Factory<Request = In, Response = Out, Error = Err>
where where
T: Factory, T: Factory<Error = Err>,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
Out::Error: From<T::Error>,
U: IntoFactory<T>, U: IntoFactory<T>,
{ {
ApplyNewService::new(service.into_factory(), f) ApplyNewService::new(service.into_factory(), f)
@ -34,25 +37,24 @@ where
#[doc(hidden)] #[doc(hidden)]
/// `Apply` service combinator /// `Apply` service combinator
#[pin_project] #[pin_project]
pub struct Apply<T, F, In, Out> struct Apply<T, F, R, In, Out, Err>
where where
T: Service, T: Service<Error = Err>,
{ {
#[pin] #[pin]
service: T, service: T,
f: F, f: F,
r: PhantomData<(In, Out)>, r: PhantomData<(In, Out, R)>,
} }
impl<T, F, In, Out> Apply<T, F, In, Out> impl<T, F, R, In, Out, Err> Apply<T, F, R, In, Out, Err>
where where
T: Service, T: Service<Error = Err>,
F: FnMut(In, &mut T) -> Out, F: FnMut(In, &mut T) -> R,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
Out::Error: From<T::Error>,
{ {
/// Create new `Apply` combinator /// Create new `Apply` combinator
pub(crate) fn new(service: T, f: F) -> Self { fn new(service: T, f: F) -> Self {
Self { Self {
service, service,
f, f,
@ -61,60 +63,44 @@ where
} }
} }
impl<T, F, In, Out> Clone for Apply<T, F, In, Out> impl<T, F, R, In, Out, Err> Service for Apply<T, F, R, In, Out, Err>
where where
T: Service + Clone, T: Service<Error = Err>,
F: Clone, F: FnMut(In, &mut T) -> R,
{ R: Future<Output = Result<Out, Err>>,
fn clone(&self) -> Self {
Apply {
service: self.service.clone(),
f: self.f.clone(),
r: PhantomData,
}
}
}
impl<T, F, In, Out> Service for Apply<T, F, In, Out>
where
T: Service,
F: FnMut(In, &mut T) -> Out,
Out: IntoFuture,
Out::Error: From<T::Error>,
{ {
type Request = In; type Request = In;
type Response = Out::Item; type Response = Out;
type Error = Out::Error; type Error = Err;
type Future = Out::Future; type Future = R;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(futures::ready!(self.service.poll_ready(ctx)).map_err(|e| e.into())) Poll::Ready(futures::ready!(self.service.poll_ready(ctx)))
} }
fn call(&mut self, req: In) -> Self::Future { fn call(&mut self, req: In) -> Self::Future {
(self.f)(req, &mut self.service).into_future() (self.f)(req, &mut self.service)
} }
} }
/// `ApplyNewService` new service combinator /// `ApplyNewService` new service combinator
pub struct ApplyNewService<T, F, In, Out> struct ApplyNewService<T, F, R, In, Out, Err>
where where
T: Factory, T: Factory<Error = Err>,
{ {
service: T, service: T,
f: F, f: F,
r: PhantomData<(In, Out)>, r: PhantomData<(R, In, Out)>,
} }
impl<T, F, In, Out> ApplyNewService<T, F, In, Out> impl<T, F, R, In, Out, Err> ApplyNewService<T, F, R, In, Out, Err>
where where
T: Factory, T: Factory<Error = Err>,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
Out::Error: From<T::Error>,
{ {
/// Create new `ApplyNewService` new service instance /// Create new `ApplyNewService` new service instance
pub(crate) fn new(service: T, f: F) -> Self { fn new(service: T, f: F) -> Self {
Self { Self {
f, f,
service, service,
@ -123,36 +109,20 @@ where
} }
} }
impl<T, F, In, Out> Clone for ApplyNewService<T, F, In, Out> impl<T, F, R, In, Out, Err> Factory for ApplyNewService<T, F, R, In, Out, Err>
where where
T: Factory + Clone, T: Factory<Error = Err>,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
{
fn clone(&self) -> Self {
Self {
service: self.service.clone(),
f: self.f.clone(),
r: PhantomData,
}
}
}
impl<T, F, In, Out> Factory for ApplyNewService<T, F, In, Out>
where
T: Factory,
F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture,
Out::Error: From<T::Error>,
{ {
type Request = In; type Request = In;
type Response = Out::Item; type Response = Out;
type Error = Out::Error; type Error = Err;
type Config = T::Config; type Config = T::Config;
type Service = Apply<T::Service, F, In, Out>; type Service = Apply<T::Service, F, R, In, Out, Err>;
type InitError = T::InitError; type InitError = T::InitError;
type Future = ApplyNewServiceFuture<T, F, In, Out>; type Future = ApplyNewServiceFuture<T, F, R, In, Out, Err>;
fn new_service(&self, cfg: &T::Config) -> Self::Future { fn new_service(&self, cfg: &T::Config) -> Self::Future {
ApplyNewServiceFuture::new(self.service.new_service(cfg), self.f.clone()) ApplyNewServiceFuture::new(self.service.new_service(cfg), self.f.clone())
@ -160,11 +130,11 @@ where
} }
#[pin_project] #[pin_project]
pub struct ApplyNewServiceFuture<T, F, In, Out> struct ApplyNewServiceFuture<T, F, R, In, Out, Err>
where where
T: Factory, T: Factory<Error = Err>,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
{ {
#[pin] #[pin]
fut: T::Future, fut: T::Future,
@ -172,11 +142,11 @@ where
r: PhantomData<(In, Out)>, r: PhantomData<(In, Out)>,
} }
impl<T, F, In, Out> ApplyNewServiceFuture<T, F, In, Out> impl<T, F, R, In, Out, Err> ApplyNewServiceFuture<T, F, R, In, Out, Err>
where where
T: Factory, T: Factory<Error = Err>,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
{ {
fn new(fut: T::Future, f: F) -> Self { fn new(fut: T::Future, f: F) -> Self {
ApplyNewServiceFuture { ApplyNewServiceFuture {
@ -187,14 +157,13 @@ where
} }
} }
impl<T, F, In, Out> Future for ApplyNewServiceFuture<T, F, In, Out> impl<T, F, R, In, Out, Err> Future for ApplyNewServiceFuture<T, F, R, In, Out, Err>
where where
T: Factory, T: Factory<Error = Err>,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> R + Clone,
Out: IntoFuture, R: Future<Output = Result<Out, Err>>,
Out::Error: From<T::Error>,
{ {
type Output = Result<Apply<T::Service, F, In, Out>, T::InitError>; type Output = Result<Apply<T::Service, F, R, In, Out, Err>, T::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();

View File

@ -7,10 +7,10 @@ use futures::ready;
use pin_project::pin_project; use pin_project::pin_project;
use crate::cell::Cell; use crate::cell::Cell;
use crate::{Factory, IntoFuture, IntoService, Service}; use crate::{Factory, IntoService, Service};
/// Convert `Fn(&Config, &mut Service) -> Future<Service>` fn to a NewService /// Convert `Fn(&Config, &mut Service) -> Future<Service>` fn to a NewService
pub fn apply_cfg<F, C, T, R, S>( pub fn apply_cfg<F, C, T, R, S, E>(
srv: T, srv: T,
f: F, f: F,
) -> impl Factory< ) -> impl Factory<
@ -19,18 +19,17 @@ pub fn apply_cfg<F, C, T, R, S>(
Response = S::Response, Response = S::Response,
Error = S::Error, Error = S::Error,
Service = S, Service = S,
InitError = R::Error, InitError = E,
> + Clone > + Clone
where where
F: FnMut(&C, &mut T) -> R, F: FnMut(&C, &mut T) -> R,
T: Service, T: Service,
R: IntoFuture, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
ApplyConfigService { ApplyConfigService {
f: Cell::new(f), f: Cell::new(f),
srv: Cell::new(srv.into_service()), srv: Cell::new(srv),
_t: PhantomData, _t: PhantomData,
} }
} }
@ -53,8 +52,7 @@ where
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: Factory<Config = ()>, T: Factory<Config = ()>,
T::InitError: From<T::Error>, T::InitError: From<T::Error>,
R: IntoFuture<Error = T::InitError>, R: Future<Output = Result<S, T::InitError>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
ApplyConfigNewService { ApplyConfigNewService {
@ -66,12 +64,11 @@ where
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService\ /// Convert `Fn(&Config) -> Future<Service>` fn to NewService\
#[pin_project] #[pin_project]
struct ApplyConfigService<F, C, T, R, S> struct ApplyConfigService<F, C, T, R, S, E>
where where
F: FnMut(&C, &mut T) -> R, F: FnMut(&C, &mut T) -> R,
T: Service, T: Service,
R: IntoFuture, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
f: Cell<F>, f: Cell<F>,
@ -80,12 +77,11 @@ where
_t: PhantomData<(C, R, S)>, _t: PhantomData<(C, R, S)>,
} }
impl<F, C, T, R, S> Clone for ApplyConfigService<F, C, T, R, S> impl<F, C, T, R, S, E> Clone for ApplyConfigService<F, C, T, R, S, E>
where where
F: FnMut(&C, &mut T) -> R, F: FnMut(&C, &mut T) -> R,
T: Service, T: Service,
R: IntoFuture, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -97,12 +93,11 @@ where
} }
} }
impl<F, C, T, R, S> Factory for ApplyConfigService<F, C, T, R, S> impl<F, C, T, R, S, E> Factory for ApplyConfigService<F, C, T, R, S, E>
where where
F: FnMut(&C, &mut T) -> R, F: FnMut(&C, &mut T) -> R,
T: Service, T: Service,
R: IntoFuture, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
type Config = C; type Config = C;
@ -111,37 +106,34 @@ where
type Error = S::Error; type Error = S::Error;
type Service = S; type Service = S;
type InitError = R::Error; type InitError = E;
type Future = FnNewServiceConfigFut<R, S>; type Future = FnNewServiceConfigFut<R, S, E>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &C) -> Self::Future {
FnNewServiceConfigFut { FnNewServiceConfigFut {
fut: unsafe { (self.f.get_mut_unsafe())(cfg, self.srv.get_mut_unsafe()) } fut: unsafe { (self.f.get_mut_unsafe())(cfg, self.srv.get_mut_unsafe()) },
.into_future(),
_t: PhantomData, _t: PhantomData,
} }
} }
} }
#[pin_project] #[pin_project]
struct FnNewServiceConfigFut<R, S> struct FnNewServiceConfigFut<R, S, E>
where where
R: IntoFuture, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
#[pin] #[pin]
fut: R::Future, fut: R,
_t: PhantomData<(S,)>, _t: PhantomData<(S,)>,
} }
impl<R, S> Future for FnNewServiceConfigFut<R, S> impl<R, S, E> Future for FnNewServiceConfigFut<R, S, E>
where where
R: IntoFuture, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
type Output = Result<S, R::Error>; type Output = Result<S, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(Ok(ready!(self.project().fut.poll(cx))?.into_service())) Poll::Ready(Ok(ready!(self.project().fut.poll(cx))?.into_service()))
@ -154,8 +146,7 @@ where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: Factory<Config = ()>, T: Factory<Config = ()>,
R: IntoFuture<Error = T::InitError>, R: Future<Output = Result<S, T::InitError>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
f: Cell<F>, f: Cell<F>,
@ -168,8 +159,7 @@ where
C: Clone, C: Clone,
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: Factory<Config = ()>, T: Factory<Config = ()>,
R: IntoFuture<Error = T::InitError>, R: Future<Output = Result<S, T::InitError>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -187,8 +177,7 @@ where
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: Factory<Config = ()>, T: Factory<Config = ()>,
T::InitError: From<T::Error>, T::InitError: From<T::Error>,
R: IntoFuture<Error = T::InitError>, R: Future<Output = Result<S, T::InitError>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
type Config = C; type Config = C;
@ -197,7 +186,7 @@ where
type Error = S::Error; type Error = S::Error;
type Service = S; type Service = S;
type InitError = R::Error; type InitError = T::InitError;
type Future = ApplyConfigNewServiceFut<F, C, T, R, S>; type Future = ApplyConfigNewServiceFut<F, C, T, R, S>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &C) -> Self::Future {
@ -219,8 +208,7 @@ where
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: Factory<Config = ()>, T: Factory<Config = ()>,
T::InitError: From<T::Error>, T::InitError: From<T::Error>,
R: IntoFuture<Error = T::InitError>, R: Future<Output = Result<S, T::InitError>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
cfg: C, cfg: C,
@ -229,7 +217,7 @@ where
#[pin] #[pin]
srv_fut: Option<T::Future>, srv_fut: Option<T::Future>,
#[pin] #[pin]
fut: Option<R::Future>, fut: Option<R>,
_t: PhantomData<(S,)>, _t: PhantomData<(S,)>,
} }
@ -239,11 +227,10 @@ where
F: FnMut(&C, &mut T::Service) -> R, F: FnMut(&C, &mut T::Service) -> R,
T: Factory<Config = ()>, T: Factory<Config = ()>,
T::InitError: From<T::Error>, T::InitError: From<T::Error>,
R: IntoFuture<Error = T::InitError>, R: Future<Output = Result<S, T::InitError>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
type Output = Result<S, R::Error>; type Output = Result<S, T::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 mut this = self.project(); let mut this = self.project();
@ -264,8 +251,7 @@ where
} else if let Some(ref mut srv) = this.srv { } else if let Some(ref mut srv) = this.srv {
match srv.poll_ready(cx)? { match srv.poll_ready(cx)? {
Poll::Ready(_) => { Poll::Ready(_) => {
this.fut this.fut.set(Some(this.f.get_mut()(&this.cfg, srv)));
.set(Some(this.f.get_mut()(&this.cfg, srv).into_future()));
continue 'poll; continue 'poll;
} }
Poll::Pending => return Poll::Pending, Poll::Pending => return Poll::Pending,

View File

@ -7,7 +7,7 @@ use std::task::{Context, Poll};
use futures::future::{err, ok, Either, Ready}; use futures::future::{err, ok, Either, Ready};
use futures::future::{FutureExt, LocalBoxFuture}; use futures::future::{FutureExt, LocalBoxFuture};
use crate::{Factory, IntoFuture, Service}; use crate::{Factory, Service};
pub type BoxedService<Req, Res, Err> = Box< pub type BoxedService<Req, Res, Err> = Box<
dyn Service< dyn Service<

View File

@ -6,163 +6,154 @@ use std::task::{Context, Poll};
use futures::future::{ok, Ready}; use futures::future::{ok, Ready};
use pin_project::pin_project; use pin_project::pin_project;
use crate::IntoFuture;
use crate::{Factory, IntoFactory, IntoService, Service}; use crate::{Factory, IntoFactory, IntoService, Service};
/// Create `NewService` for function that can act as a Service /// Create `Factory` for function that can act as a Service
pub fn service_fn<F, Req, Out, Cfg>( pub fn service_fn<F, Fut, Req, Res, Err, Cfg>(
f: F, f: F,
) -> impl Factory< ) -> impl Factory<Config = Cfg, Request = Req, Response = Res, Error = Err, InitError = ()> + Clone
Config = Cfg,
Request = Req,
Response = Out::Item,
Error = Out::Error,
InitError = (),
>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Fut + Clone,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
NewServiceFn::new(f) NewServiceFn::new(f)
} }
/// Create `Factory` for function that can produce services /// Create `Factory` for function that can produce services
pub fn factory_fn<F, C, R, S, E>( pub fn service_fn_factory<S, F, Cfg, Fut, Err>(
f: F, f: F,
) -> impl Factory< ) -> impl Factory<
Config = C, Config = Cfg,
Request = S::Request, Request = S::Request,
Response = S::Response, Response = S::Response,
Error = S::Error, Error = S::Error,
InitError = E, InitError = Err,
Future = R::Future, Future = Fut,
> >
where where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
R::Item: IntoService<S>,
S: Service, S: Service,
F: Fn() -> Fut,
Fut: Future<Output = Result<S, Err>>,
{ {
FnNewServiceNoConfig::new(f) FnNewServiceNoConfig::new(f)
} }
/// Create `NewService` for function that can produce services with configuration /// Create `Factory` for function that can produce services with configuration
pub fn new_service_cfg<F, C, R, S, E>( pub fn service_fn_config<F, Fut, Cfg, Srv, Err>(
f: F, f: F,
) -> impl Factory< ) -> impl Factory<
Config = C, Config = Cfg,
Request = S::Request, Request = Srv::Request,
Response = S::Response, Response = Srv::Response,
Error = S::Error, Error = Srv::Error,
InitError = E, InitError = Err,
> >
where where
F: Fn(&C) -> R, F: Fn(&Cfg) -> Fut,
R: IntoFuture<Error = E>, Fut: Future<Output = Result<Srv, Err>>,
R::Item: IntoService<S>, Srv: Service,
S: Service,
{ {
FnNewServiceConfig::new(f) FnNewServiceConfig::new(f)
} }
pub(crate) struct ServiceFn<F, Req, Out> pub struct ServiceFn<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Fut,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
f: F, f: F,
_t: PhantomData<Req>, _t: PhantomData<Req>,
} }
impl<F, Req, Out> ServiceFn<F, Req, Out> impl<F, Fut, Req, Res, Err> ServiceFn<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Fut,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
pub(crate) fn new(f: F) -> Self { pub(crate) fn new(f: F) -> Self {
ServiceFn { f, _t: PhantomData } ServiceFn { f, _t: PhantomData }
} }
} }
impl<F, Req, Out> Clone for ServiceFn<F, Req, Out> impl<F, Fut, Req, Res, Err> Clone for ServiceFn<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Fut + Clone,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
ServiceFn::new(self.f.clone()) ServiceFn::new(self.f.clone())
} }
} }
impl<F, Req, Out> Service for ServiceFn<F, Req, Out> impl<F, Fut, Req, Res, Err> Service for ServiceFn<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Fut + Clone,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
type Request = Req; type Request = Req;
type Response = Out::Item; type Response = Res;
type Error = Out::Error; type Error = Err;
type Future = Out::Future; type Future = Fut;
fn poll_ready(&mut self, _ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&mut self, _ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
fn call(&mut self, req: Req) -> Self::Future { fn call(&mut self, req: Req) -> Self::Future {
(self.f)(req).into_future() (self.f)(req)
} }
} }
impl<F, Req, Out> IntoService<ServiceFn<F, Req, Out>> for F impl<F, Fut, Req, Res, Err> IntoService<ServiceFn<F, Fut, Req, Res, Err>> for F
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Fut + Clone,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
fn into_service(self) -> ServiceFn<F, Req, Out> { fn into_service(self) -> ServiceFn<F, Fut, Req, Res, Err> {
ServiceFn::new(self) ServiceFn::new(self)
} }
} }
pub(crate) struct NewServiceFn<F, Req, Out, Cfg> struct NewServiceFn<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Fut,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
f: F, f: F,
_t: PhantomData<(Req, Cfg)>, _t: PhantomData<(Req, Cfg)>,
} }
impl<F, Req, Out, Cfg> NewServiceFn<F, Req, Out, Cfg> impl<F, Fut, Req, Res, Err, Cfg> NewServiceFn<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Fut + Clone,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
pub(crate) fn new(f: F) -> Self { fn new(f: F) -> Self {
NewServiceFn { f, _t: PhantomData } NewServiceFn { f, _t: PhantomData }
} }
} }
impl<F, Req, Out, Cfg> Clone for NewServiceFn<F, Req, Out, Cfg> impl<F, Fut, Req, Res, Err, Cfg> Clone for NewServiceFn<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Fut + Clone,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
NewServiceFn::new(self.f.clone()) NewServiceFn::new(self.f.clone())
} }
} }
impl<F, Req, Out, Cfg> Factory for NewServiceFn<F, Req, Out, Cfg> impl<F, Fut, Req, Res, Err, Cfg> Factory for NewServiceFn<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Fut + Clone,
Out: IntoFuture, Fut: Future<Output = Result<Res, Err>>,
{ {
type Request = Req; type Request = Req;
type Response = Out::Item; type Response = Res;
type Error = Out::Error; type Error = Err;
type Config = Cfg; type Config = Cfg;
type Service = ServiceFn<F, Req, Out>; type Service = ServiceFn<F, Fut, Req, Res, Err>;
type InitError = (); type InitError = ();
type Future = Ready<Result<Self::Service, Self::InitError>>; type Future = Ready<Result<Self::Service, Self::InitError>>;
@ -171,118 +162,79 @@ where
} }
} }
impl<F, Req, Out, Cfg> IntoService<ServiceFn<F, Req, Out>> for NewServiceFn<F, Req, Out, Cfg>
where
F: FnMut(Req) -> Out + Clone,
Out: IntoFuture,
{
fn into_service(self) -> ServiceFn<F, Req, Out> {
ServiceFn::new(self.f.clone())
}
}
impl<F, Req, Out, Cfg> IntoFactory<NewServiceFn<F, Req, Out, Cfg>> for F
where
F: Fn(Req) -> Out + Clone,
Out: IntoFuture,
{
fn into_factory(self) -> NewServiceFn<F, Req, Out, Cfg> {
NewServiceFn::new(self)
}
}
/// Convert `Fn(&Config) -> Future<Service>` fn to NewService /// Convert `Fn(&Config) -> Future<Service>` fn to NewService
pub(crate) struct FnNewServiceConfig<F, C, R, S, E> struct FnNewServiceConfig<F, Fut, Cfg, Srv, Err>
where where
F: Fn(&C) -> R, F: Fn(&Cfg) -> Fut,
R: IntoFuture<Error = E>, Fut: Future<Output = Result<Srv, Err>>,
R::Item: IntoService<S>, Srv: Service,
S: Service,
{ {
f: F, f: F,
_t: PhantomData<(C, R, S, E)>, _t: PhantomData<(Fut, Cfg, Srv, Err)>,
} }
impl<F, C, R, S, E> FnNewServiceConfig<F, C, R, S, E> impl<F, Fut, Cfg, Srv, Err> FnNewServiceConfig<F, Fut, Cfg, Srv, Err>
where where
F: Fn(&C) -> R, F: Fn(&Cfg) -> Fut,
R: IntoFuture<Error = E>, Fut: Future<Output = Result<Srv, Err>>,
R::Item: IntoService<S>, Srv: Service,
S: Service,
{ {
pub fn new(f: F) -> Self { pub fn new(f: F) -> Self {
FnNewServiceConfig { f, _t: PhantomData } FnNewServiceConfig { f, _t: PhantomData }
} }
} }
impl<F, C, R, S, E> Factory for FnNewServiceConfig<F, C, R, S, E> impl<F, Fut, Cfg, Srv, Err> Factory for FnNewServiceConfig<F, Fut, Cfg, Srv, Err>
where where
F: Fn(&C) -> R, F: Fn(&Cfg) -> Fut,
R: IntoFuture<Error = E>, Fut: Future<Output = Result<Srv, Err>>,
R::Item: IntoService<S>, Srv: Service,
S: Service,
{ {
type Request = S::Request; type Request = Srv::Request;
type Response = S::Response; type Response = Srv::Response;
type Error = S::Error; type Error = Srv::Error;
type Config = C; type Config = Cfg;
type Service = S; type Service = Srv;
type InitError = E; type InitError = Err;
type Future = FnNewServiceConfigFut<R, S, E>; type Future = FnNewServiceConfigFut<Fut, Srv, Err>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &Cfg) -> Self::Future {
FnNewServiceConfigFut { FnNewServiceConfigFut {
fut: (self.f)(cfg).into_future(), fut: (self.f)(cfg),
_t: PhantomData, _t: PhantomData,
} }
} }
} }
#[pin_project] #[pin_project]
pub(crate) struct FnNewServiceConfigFut<R, S, E> struct FnNewServiceConfigFut<R, S, E>
where where
R: IntoFuture<Error = E>, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
#[pin] #[pin]
fut: R::Future, fut: R,
_t: PhantomData<(S,)>, _t: PhantomData<(S,)>,
} }
impl<R, S, E> Future for FnNewServiceConfigFut<R, S, E> impl<R, S, E> Future for FnNewServiceConfigFut<R, S, E>
where where
R: IntoFuture<Error = E>, R: Future<Output = Result<S, E>>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
type Output = Result<S, R::Error>; type Output = Result<S, E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(Ok( Poll::Ready(Ok(futures::ready!(self.project().fut.poll(cx))?))
futures::ready!(self.project().fut.poll(cx))?.into_service()
))
}
}
impl<F, C, R, S, E> Clone for FnNewServiceConfig<F, C, R, S, E>
where
F: Fn(&C) -> R + Clone,
R: IntoFuture<Error = E>,
R::Item: IntoService<S>,
S: Service,
{
fn clone(&self) -> Self {
Self::new(self.f.clone())
} }
} }
/// Converter for `Fn() -> Future<Service>` fn /// Converter for `Fn() -> Future<Service>` fn
pub(crate) struct FnNewServiceNoConfig<F, C, R, S, E> pub struct FnNewServiceNoConfig<F, C, R, S, E>
where where
F: Fn() -> R, F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
f: F, f: F,
@ -292,10 +244,10 @@ where
impl<F, C, R, S, E> FnNewServiceNoConfig<F, C, R, S, E> impl<F, C, R, S, E> FnNewServiceNoConfig<F, C, R, S, E>
where where
F: Fn() -> R, F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
pub fn new(f: F) -> Self { fn new(f: F) -> Self {
FnNewServiceNoConfig { f, _t: PhantomData } FnNewServiceNoConfig { f, _t: PhantomData }
} }
} }
@ -303,7 +255,7 @@ where
impl<F, C, R, S, E> Factory for FnNewServiceNoConfig<F, C, R, S, E> impl<F, C, R, S, E> Factory for FnNewServiceNoConfig<F, C, R, S, E>
where where
F: Fn() -> R, F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
type Request = S::Request; type Request = S::Request;
@ -312,17 +264,17 @@ where
type Service = S; type Service = S;
type Config = C; type Config = C;
type InitError = E; type InitError = E;
type Future = R::Future; type Future = R;
fn new_service(&self, _: &C) -> Self::Future { fn new_service(&self, _: &C) -> Self::Future {
(self.f)().into_future() (self.f)()
} }
} }
impl<F, C, R, S, E> Clone for FnNewServiceNoConfig<F, C, R, S, E> impl<F, C, R, S, E> Clone for FnNewServiceNoConfig<F, C, R, S, E>
where where
F: Fn() -> R + Clone, F: Fn() -> R + Clone,
R: IntoFuture<Item = S, Error = E>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -333,7 +285,7 @@ where
impl<F, C, R, S, E> IntoFactory<FnNewServiceNoConfig<F, C, R, S, E>> for F impl<F, C, R, S, E> IntoFactory<FnNewServiceNoConfig<F, C, R, S, E>> for F
where where
F: Fn() -> R, F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>, R: Future<Output = Result<S, E>>,
S: Service, S: Service,
{ {
fn into_factory(self) -> FnNewServiceNoConfig<F, C, R, S, E> { fn into_factory(self) -> FnNewServiceNoConfig<F, C, R, S, E> {

View File

@ -22,29 +22,12 @@ mod transform_err;
pub use self::apply::{apply_fn, apply_fn_factory}; pub use self::apply::{apply_fn, apply_fn_factory};
pub use self::apply_cfg::{apply_cfg, apply_cfg_factory}; pub use self::apply_cfg::{apply_cfg, apply_cfg_factory};
pub use self::fn_service::{factory_fn, new_service_cfg, service_fn}; pub use self::fn_service::{service_fn, service_fn_config, service_fn_factory};
pub use self::into::{into_factory, into_service, FactoryMapper, ServiceMapper}; pub use self::into::{into_factory, into_service, FactoryMapper, ServiceMapper};
pub use self::map_config::{map_config, unit_config, MappedConfig}; pub use self::map_config::{map_config, unit_config, MappedConfig};
pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory}; pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory};
pub use self::transform::{apply_transform, IntoTransform, Transform}; pub use self::transform::{apply_transform, IntoTransform, Transform};
pub trait IntoFuture {
type Item;
type Error;
type Future: Future<Output = Result<Self::Item, Self::Error>>;
fn into_future(self) -> Self::Future;
}
impl<F: Future<Output = Result<I, E>>, I, E> IntoFuture for F {
type Item = I;
type Error = E;
type Future = F;
fn into_future(self) -> Self::Future {
self
}
}
/// An asynchronous function from `Request` to a `Response`. /// An asynchronous function from `Request` to a `Response`.
pub trait Service { pub trait Service {
/// Requests handled by the service. /// Requests handled by the service.
@ -80,31 +63,6 @@ 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: Self::Request) -> Self::Future;
// #[cfg(test)]
// fn poll_test(&mut self) -> Poll<Result<(), Self::Error>> {
// // kinda stupid method, but works for our test purposes
// unsafe {
// let mut this = Pin::new_unchecked(self);
// tokio::runtime::current_thread::Builder::new()
// .build()
// .unwrap()
// .block_on(futures::future::poll_fn(move |cx| {
// let this = &mut this;
// Poll::Ready(this.as_mut().poll_ready(cx))
// }))
// }
// }
// fn poll_once<'a>(&'a mut self) -> LocalBoxFuture<'a, Poll<Result<(), Self::Error>>> {
// unsafe {
// let mut this = Pin::new_unchecked(self);
// Pin::new_unchecked(Box::new(futures::future::poll_fn(move |cx| {
// //let this = &mut this;
// Poll::Ready(this.get_unchecked_mut().poll_ready(cx))
// })))
// }
// }
} }
/// Creates new `Service` values. /// Creates new `Service` values.
@ -243,7 +201,7 @@ where
fn into_service(self) -> T; fn into_service(self) -> T;
} }
/// Trait for types that can be converted to a `ServiceFactory` /// Trait for types that can be converted to a `Factory`
pub trait IntoFactory<T> pub trait IntoFactory<T>
where where
T: Factory, T: Factory,

View File

@ -9,7 +9,7 @@ pub enum MappedConfig<'a, T> {
/// Adapt external config to a config for provided new service /// Adapt external config to a config for provided new service
pub fn map_config<T, F, C>( pub fn map_config<T, F, C>(
new_service: T, factory: T,
f: F, f: F,
) -> impl Factory< ) -> impl Factory<
Config = C, Config = C,
@ -22,7 +22,7 @@ where
T: Factory, T: Factory,
F: Fn(&C) -> MappedConfig<T::Config>, F: Fn(&C) -> MappedConfig<T::Config>,
{ {
MapConfig::new(new_service, f) MapConfig::new(factory, f)
} }
/// Replace config with unit /// Replace config with unit