mirror of https://github.com/fafhrd91/actix-net
phase 3/3
This commit is contained in:
parent
bff68c3f76
commit
0d19050269
|
@ -121,6 +121,7 @@ where
|
|||
>,
|
||||
{
|
||||
inner: Rc<(A, B)>,
|
||||
_phantom: PhantomData<Req>,
|
||||
}
|
||||
|
||||
impl<A, B, Req> AndThenServiceFactory<A, B, Req>
|
||||
|
@ -138,6 +139,7 @@ where
|
|||
pub(crate) fn new(a: A, b: B) -> Self {
|
||||
Self {
|
||||
inner: Rc::new((a, b)),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +186,7 @@ where
|
|||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: self.inner.clone(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,65 +8,67 @@ use std::task::{Context, Poll};
|
|||
use crate::{Service, ServiceFactory};
|
||||
|
||||
/// `Apply` service combinator
|
||||
pub(crate) struct AndThenApplyFn<A, B, F, Fut, Req, Res, Err>
|
||||
pub(crate) struct AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: Service<Req>,
|
||||
B: Service<Result<A::Response, A::Error>>,
|
||||
F: FnMut(A::Response, &mut B) -> Fut,
|
||||
S1: Service<Req>,
|
||||
S2: Service<In>,
|
||||
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||
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)>>,
|
||||
r: PhantomData<(Fut, Res, Err)>,
|
||||
svc: Rc<RefCell<(S1, S2, F)>>,
|
||||
_phantom: PhantomData<(Fut, Req, In, Res, Err)>,
|
||||
}
|
||||
|
||||
impl<A, B, F, Fut, Req, Res, Err> AndThenApplyFn<A, B, F, Fut, Req, Res, Err>
|
||||
impl<S1, S2, F, Fut, Req, In, Res, Err> AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: Service<Req>,
|
||||
B: Service<Result<A::Response, A::Error>>,
|
||||
F: FnMut(A::Response, &mut B) -> Fut,
|
||||
S1: Service<Req>,
|
||||
S2: Service<In>,
|
||||
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error> + From<B::Error>,
|
||||
Err: From<S1::Error> + From<S2::Error>,
|
||||
{
|
||||
/// 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 {
|
||||
srv: Rc::new(RefCell::new((a, b, f))),
|
||||
r: PhantomData,
|
||||
svc: Rc::new(RefCell::new((a, b, wrap_fn))),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, F, Fut, Req, Res, Err> Clone for AndThenApplyFn<A, B, F, Fut, Req, Res, Err>
|
||||
impl<S1, S2, F, Fut, Req, In, Res, Err> Clone
|
||||
for AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: Service<Req>,
|
||||
B: Service<Result<A::Response, A::Error>>,
|
||||
F: FnMut(A::Response, &mut B) -> Fut,
|
||||
S1: Service<Req>,
|
||||
S2: Service<In>,
|
||||
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error> + From<B::Error>,
|
||||
Err: From<S1::Error> + From<S2::Error>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
AndThenApplyFn {
|
||||
srv: self.srv.clone(),
|
||||
r: PhantomData,
|
||||
svc: self.svc.clone(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, F, Fut, Req, Res, Err> Service<Req> for AndThenApplyFn<A, B, F, Fut, Req, Res, Err>
|
||||
impl<S1, S2, F, Fut, Req, In, Res, Err> Service<Req>
|
||||
for AndThenApplyFn<S1, S2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: Service<Req>,
|
||||
B: Service<Result<A::Response, A::Error>>,
|
||||
F: FnMut(A::Response, &mut B) -> Fut,
|
||||
S1: Service<Req>,
|
||||
S2: Service<In>,
|
||||
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error> + From<B::Error>,
|
||||
Err: From<S1::Error> + From<S2::Error>,
|
||||
{
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
type Future = AndThenApplyFnFuture<A, B, F, Fut, Req, 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>> {
|
||||
let mut inner = self.srv.borrow_mut();
|
||||
let mut inner = self.svc.borrow_mut();
|
||||
let not_ready = inner.0.poll_ready(cx)?.is_pending();
|
||||
if inner.1.poll_ready(cx)?.is_pending() || not_ready {
|
||||
Poll::Pending
|
||||
|
@ -76,49 +78,48 @@ where
|
|||
}
|
||||
|
||||
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 {
|
||||
state: State::A(fut, Some(self.srv.clone())),
|
||||
state: State::A(fut, Some(self.svc.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project::pin_project]
|
||||
pub(crate) struct AndThenApplyFnFuture<A, B, F, Fut, Req, Res, Err>
|
||||
pub(crate) struct AndThenApplyFnFuture<S1, S2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: Service<Req>,
|
||||
B: Service<Result<A::Response, A::Error>>,
|
||||
F: FnMut(A::Response, &mut B) -> Fut,
|
||||
S1: Service<Req>,
|
||||
S2: Service<In>,
|
||||
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error>,
|
||||
Err: From<B::Error>,
|
||||
Err: From<S1::Error> + From<S2::Error>,
|
||||
{
|
||||
#[pin]
|
||||
state: State<A, B, F, Fut, Req, Res, Err>,
|
||||
state: State<S1, S2, F, Fut, Req, In, Res, Err>,
|
||||
}
|
||||
|
||||
#[pin_project::pin_project(project = StateProj)]
|
||||
enum State<A, B, F, Fut, Req, Res, Err>
|
||||
enum State<S1, S2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: Service<Req>,
|
||||
B: Service<Result<A::Response, A::Error>>,
|
||||
F: FnMut(A::Response, &mut B) -> Fut,
|
||||
S1: Service<Req>,
|
||||
S2: Service<In>,
|
||||
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error>,
|
||||
Err: From<B::Error>,
|
||||
Err: From<S1::Error> + From<S2::Error>,
|
||||
{
|
||||
A(#[pin] A::Future, Option<Rc<RefCell<(A, B, F)>>>),
|
||||
A(#[pin] S1::Future, Option<Rc<RefCell<(S1, S2, F)>>>),
|
||||
B(#[pin] Fut),
|
||||
Empty,
|
||||
Empty(PhantomData<In>),
|
||||
}
|
||||
|
||||
impl<A, B, F, Fut, Req, Res, Err> Future for AndThenApplyFnFuture<A, B, F, Fut, Req, Res, Err>
|
||||
impl<S1, S2, F, Fut, Req, In, Res, Err> Future
|
||||
for AndThenApplyFnFuture<S1, S2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: Service<Req>,
|
||||
B: Service<Result<A::Response, A::Error>>,
|
||||
F: FnMut(A::Response, &mut B) -> Fut,
|
||||
S1: Service<Req>,
|
||||
S2: Service<In>,
|
||||
F: FnMut(S1::Response, &mut S2) -> Fut,
|
||||
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>;
|
||||
|
||||
|
@ -128,8 +129,8 @@ where
|
|||
match this.state.as_mut().project() {
|
||||
StateProj::A(fut, b) => match fut.poll(cx)? {
|
||||
Poll::Ready(res) => {
|
||||
let b = b.take().unwrap();
|
||||
this.state.set(State::Empty);
|
||||
let b = Option::take(b).unwrap();
|
||||
this.state.set(State::Empty(PhantomData));
|
||||
let (_, b, f) = &mut *b.borrow_mut();
|
||||
let fut = f(res, b);
|
||||
this.state.set(State::B(fut));
|
||||
|
@ -138,10 +139,10 @@ where
|
|||
Poll::Pending => Poll::Pending,
|
||||
},
|
||||
StateProj::B(fut) => fut.poll(cx).map(|r| {
|
||||
this.state.set(State::Empty);
|
||||
this.state.set(State::Empty(PhantomData));
|
||||
r
|
||||
}),
|
||||
StateProj::Empty => {
|
||||
StateProj::Empty(_) => {
|
||||
panic!("future must not be polled after it returned `Poll::Ready`")
|
||||
}
|
||||
}
|
||||
|
@ -149,136 +150,127 @@ where
|
|||
}
|
||||
|
||||
/// `AndThenApplyFn` service factory
|
||||
pub(crate) struct AndThenApplyFnFactory<A, B, F, Req, Fut, Res, Err> {
|
||||
srv: Rc<(A, B, F)>,
|
||||
r: PhantomData<(Req, Fut, Res, Err)>,
|
||||
pub(crate) struct AndThenApplyFnFactory<SF1, SF2, F, Fut, Req, In, Res, Err> {
|
||||
srv: Rc<(SF1, SF2, F)>,
|
||||
_phantom: PhantomData<(Fut, Req, In, Res, Err)>,
|
||||
}
|
||||
|
||||
impl<A, B, F, Fut, Req, Res, Err> AndThenApplyFnFactory<A, B, F, Req, Fut, Res, Err>
|
||||
impl<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||
AndThenApplyFnFactory<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
B: ServiceFactory<
|
||||
Result<A::Response, A::Error>,
|
||||
Config = A::Config,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
||||
SF1: ServiceFactory<Req>,
|
||||
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||
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
|
||||
pub(crate) fn new(a: A, b: B, f: F) -> Self {
|
||||
pub(crate) fn new(a: SF1, b: SF2, wrap_fn: F) -> Self {
|
||||
Self {
|
||||
srv: Rc::new((a, b, f)),
|
||||
r: PhantomData,
|
||||
srv: Rc::new((a, b, wrap_fn)),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, F, Req, Fut, Res, Err> Clone for AndThenApplyFnFactory<A, B, F, Req, 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 {
|
||||
Self {
|
||||
srv: self.srv.clone(),
|
||||
r: PhantomData,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, F, Req, Fut, Res, Err> ServiceFactory<Req>
|
||||
for AndThenApplyFnFactory<A, B, F, Req, 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
|
||||
A: ServiceFactory<Req>,
|
||||
A::Config: Clone,
|
||||
B: ServiceFactory<
|
||||
Result<A::Response, A::Error>,
|
||||
Config = A::Config,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
||||
SF1: ServiceFactory<Req>,
|
||||
SF1::Config: Clone,
|
||||
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error> + From<B::Error>,
|
||||
Err: From<SF1::Error> + From<SF2::Error>,
|
||||
{
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
type Service = AndThenApplyFn<A::Service, B::Service, F, Fut, Req, Res, Err>;
|
||||
type Config = A::Config;
|
||||
type InitError = A::InitError;
|
||||
type Future = AndThenApplyFnFactoryResponse<A, B, F, Fut, Req, Res, Err>;
|
||||
type Service = AndThenApplyFn<SF1::Service, SF2::Service, F, Fut, Req, In, Res, Err>;
|
||||
type Config = SF1::Config;
|
||||
type InitError = SF1::InitError;
|
||||
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;
|
||||
AndThenApplyFnFactoryResponse {
|
||||
a: None,
|
||||
b: None,
|
||||
f: srv.2.clone(),
|
||||
fut_a: srv.0.new_service(cfg.clone()),
|
||||
fut_b: srv.1.new_service(cfg),
|
||||
s1: None,
|
||||
s2: None,
|
||||
wrap_fn: srv.2.clone(),
|
||||
fut_s1: srv.0.new_service(cfg.clone()),
|
||||
fut_s2: srv.1.new_service(cfg),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project::pin_project]
|
||||
pub(crate) struct AndThenApplyFnFactoryResponse<A, B, F, Fut, Req, Res, Err>
|
||||
pub(crate) struct AndThenApplyFnFactoryResponse<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
B: ServiceFactory<
|
||||
Result<A::Response, A::Error>,
|
||||
Config = A::Config,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
||||
SF1: ServiceFactory<Req>,
|
||||
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error>,
|
||||
Err: From<B::Error>,
|
||||
Err: From<SF1::Error>,
|
||||
Err: From<SF2::Error>,
|
||||
{
|
||||
#[pin]
|
||||
fut_b: B::Future,
|
||||
fut_s1: SF1::Future,
|
||||
#[pin]
|
||||
fut_a: A::Future,
|
||||
f: F,
|
||||
a: Option<A::Service>,
|
||||
b: Option<B::Service>,
|
||||
fut_s2: SF2::Future,
|
||||
wrap_fn: F,
|
||||
s1: Option<SF1::Service>,
|
||||
s2: Option<SF2::Service>,
|
||||
_phantom: PhantomData<In>,
|
||||
}
|
||||
|
||||
impl<A, B, F, Fut, Req, Res, Err> Future
|
||||
for AndThenApplyFnFactoryResponse<A, B, F, Fut, Req, Res, Err>
|
||||
impl<SF1, SF2, F, Fut, Req, In, Res, Err> Future
|
||||
for AndThenApplyFnFactoryResponse<SF1, SF2, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
B: ServiceFactory<
|
||||
Result<A::Response, A::Error>,
|
||||
Config = A::Config,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
F: FnMut(A::Response, &mut B::Service) -> Fut + Clone,
|
||||
SF1: ServiceFactory<Req>,
|
||||
SF2: ServiceFactory<In, Config = SF1::Config, InitError = SF1::InitError>,
|
||||
F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<A::Error> + From<B::Error>,
|
||||
Err: From<SF1::Error> + From<SF2::Error>,
|
||||
{
|
||||
type Output =
|
||||
Result<AndThenApplyFn<A::Service, B::Service, F, Fut, Req, Res, Err>, A::InitError>;
|
||||
type Output = Result<
|
||||
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> {
|
||||
let this = self.project();
|
||||
|
||||
if this.a.is_none() {
|
||||
if let Poll::Ready(service) = this.fut_a.poll(cx)? {
|
||||
*this.a = Some(service);
|
||||
if this.s1.is_none() {
|
||||
if let Poll::Ready(service) = this.fut_s1.poll(cx)? {
|
||||
*this.s1 = Some(service);
|
||||
}
|
||||
}
|
||||
|
||||
if this.b.is_none() {
|
||||
if let Poll::Ready(service) = this.fut_b.poll(cx)? {
|
||||
*this.b = Some(service);
|
||||
if this.s2.is_none() {
|
||||
if let Poll::Ready(service) = this.fut_s2.poll(cx)? {
|
||||
*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 {
|
||||
srv: Rc::new(RefCell::new((
|
||||
this.a.take().unwrap(),
|
||||
this.b.take().unwrap(),
|
||||
this.f.clone(),
|
||||
svc: Rc::new(RefCell::new((
|
||||
Option::take(this.s1).unwrap(),
|
||||
Option::take(this.s2).unwrap(),
|
||||
this.wrap_fn.clone(),
|
||||
))),
|
||||
r: PhantomData,
|
||||
_phantom: PhantomData,
|
||||
}))
|
||||
} else {
|
||||
Poll::Pending
|
||||
|
@ -296,29 +288,29 @@ mod tests {
|
|||
|
||||
#[derive(Clone)]
|
||||
struct Srv;
|
||||
impl Service<()> for Srv {
|
||||
|
||||
impl Service<u8> for Srv {
|
||||
type Response = ();
|
||||
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>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
#[allow(clippy::unit_arg)]
|
||||
fn call(&mut self, req: ()) -> Self::Future {
|
||||
ok(req)
|
||||
fn call(&mut self, req: u8) -> Self::Future {
|
||||
let _ = req;
|
||||
ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service() {
|
||||
let mut srv = pipeline(|| async { Ok(2) })
|
||||
.and_then_apply_fn(Srv, |req: &'static str, s| {
|
||||
s.call(()).map_ok(move |res| (req, res))
|
||||
});
|
||||
let mut srv = pipeline(ok).and_then_apply_fn(Srv, |req: &'static str, s| {
|
||||
s.call(1).map_ok(move |res| (req, res))
|
||||
});
|
||||
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;
|
||||
assert!(res.is_ok());
|
||||
|
@ -329,11 +321,11 @@ mod tests {
|
|||
async fn test_service_factory() {
|
||||
let new_srv = pipeline_factory(|| ok::<_, ()>(fn_service(ok))).and_then_apply_fn(
|
||||
|| 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 res = lazy(|cx| srv.poll_ready(cx)).await;
|
||||
assert_eq!(res, Poll::Ready(Ok(())));
|
||||
assert!(res.is_ready());
|
||||
|
||||
let res = srv.call("srv").await;
|
||||
assert!(res.is_ok());
|
||||
|
|
|
@ -1,208 +1,209 @@
|
|||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{
|
||||
future::Future,
|
||||
marker::PhantomData,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use futures_util::ready;
|
||||
|
||||
use super::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||
|
||||
/// Apply transform function to a service.
|
||||
pub fn apply_fn<T, Req, F, R, In, Out, Err, U>(
|
||||
///
|
||||
/// The In and Out type params refer to the request and response types for the wrapped service.
|
||||
pub fn apply_fn<U, S, F, Fut, Req, In, Res, Err>(
|
||||
service: U,
|
||||
f: F,
|
||||
) -> Apply<T, Req, F, R, In, Out, Err>
|
||||
wrap_fn: F,
|
||||
) -> Apply<S, F, Req, In, Res, Err>
|
||||
where
|
||||
T: Service<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T) -> R,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
U: IntoService<T, Req>,
|
||||
U: IntoService<S, In>,
|
||||
S: Service<In, Error = Err>,
|
||||
F: FnMut(Req, &mut S) -> Fut,
|
||||
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.
|
||||
pub fn apply_fn_factory<T, Req, F, R, In, Out, Err, U>(
|
||||
///
|
||||
/// The In and Out type params refer to the request and response types for the wrapped service.
|
||||
pub fn apply_fn_factory<U, SF, F, Fut, Req, In, Res, Err>(
|
||||
service: U,
|
||||
f: F,
|
||||
) -> ApplyServiceFactory<T, Req, F, R, In, Out, Err>
|
||||
) -> ApplyFactory<SF, F, Req, In, Res, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
U: IntoServiceFactory<T, Req>,
|
||||
U: IntoServiceFactory<SF, In>,
|
||||
SF: ServiceFactory<In, Error = Err>,
|
||||
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
ApplyServiceFactory::new(service.into_factory(), f)
|
||||
ApplyFactory::new(service.into_factory(), f)
|
||||
}
|
||||
|
||||
/// `Apply` service combinator
|
||||
pub struct Apply<T, Req, F, R, In, Out, Err>
|
||||
/// `Apply` service combinator.
|
||||
///
|
||||
/// 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
|
||||
T: Service<Req, Error = Err>,
|
||||
S: Service<In, Error = Err>,
|
||||
{
|
||||
service: T,
|
||||
f: F,
|
||||
r: PhantomData<(In, Out, R)>,
|
||||
service: S,
|
||||
wrap_fn: F,
|
||||
_phantom: PhantomData<(Req, In, Res, Err)>,
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> Apply<T, Req, F, R, In, Out, Err>
|
||||
impl<S, F, Fut, Req, In, Res, Err> Apply<S, F, Req, In, Res, Err>
|
||||
where
|
||||
T: Service<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T) -> R,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
S: Service<In, Error = Err>,
|
||||
F: FnMut(Req, &mut S) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
/// Create new `Apply` combinator
|
||||
fn new(service: T, f: F) -> Self {
|
||||
fn new(service: S, wrap_fn: F) -> Self {
|
||||
Self {
|
||||
service,
|
||||
f,
|
||||
r: PhantomData,
|
||||
wrap_fn,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> Clone for Apply<T, Req, F, R, In, Out, Err>
|
||||
impl<S, F, Fut, Req, In, Res, Err> Clone for Apply<S, F, Req, In, Res, Err>
|
||||
where
|
||||
T: Service<Req, Error = Err> + Clone,
|
||||
F: FnMut(In, &mut T) -> R + Clone,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
S: Service<In, Error = Err> + Clone,
|
||||
F: FnMut(Req, &mut S) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Apply {
|
||||
service: self.service.clone(),
|
||||
f: self.f.clone(),
|
||||
r: PhantomData,
|
||||
wrap_fn: self.wrap_fn.clone(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> Service<Req> for Apply<T, Req, F, R, In, Out, Err>
|
||||
impl<S, F, Fut, Req, In, Res, Err> Service<Req> for Apply<S, F, Req, In, Res, Err>
|
||||
where
|
||||
T: Service<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T) -> R,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
S: Service<In, Error = Err>,
|
||||
F: FnMut(Req, &mut S) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
// type Request = In;
|
||||
type Response = Out;
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
type Future = R;
|
||||
type Future = Fut;
|
||||
|
||||
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 {
|
||||
(self.f)(req, &mut self.service)
|
||||
fn call(&mut self, req: Req) -> Self::Future {
|
||||
(self.wrap_fn)(req, &mut self.service)
|
||||
}
|
||||
}
|
||||
|
||||
/// `apply()` service factory
|
||||
pub struct ApplyServiceFactory<T, Req, F, R, In, Out, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
{
|
||||
service: T,
|
||||
f: F,
|
||||
r: PhantomData<(R, In, Out)>,
|
||||
/// `ApplyFactory` service factory combinator.
|
||||
pub struct ApplyFactory<SF, F, Req, In, Res, Err> {
|
||||
factory: SF,
|
||||
wrap_fn: F,
|
||||
_phantom: PhantomData<(Req, In, Res, Err)>,
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> ApplyServiceFactory<T, Req, F, R, In, Out, Err>
|
||||
impl<SF, F, Fut, Req, In, Res, Err> ApplyFactory<SF, F, Req, In, Res, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
SF: ServiceFactory<In, Error = Err>,
|
||||
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
/// Create new `ApplyNewService` new service instance
|
||||
fn new(service: T, f: F) -> Self {
|
||||
/// Create new `ApplyFactory` new service instance
|
||||
fn new(factory: SF, wrap_fn: F) -> Self {
|
||||
Self {
|
||||
f,
|
||||
service,
|
||||
r: PhantomData,
|
||||
factory,
|
||||
wrap_fn,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> Clone for ApplyServiceFactory<T, Req, F, R, In, Out, Err>
|
||||
impl<SF, F, Fut, Req, In, Res, Err> Clone for ApplyFactory<SF, F, Req, In, Res, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err> + Clone,
|
||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
SF: ServiceFactory<In, Error = Err> + Clone,
|
||||
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
service: self.service.clone(),
|
||||
f: self.f.clone(),
|
||||
r: PhantomData,
|
||||
factory: self.factory.clone(),
|
||||
wrap_fn: self.wrap_fn.clone(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> ServiceFactory<Req>
|
||||
for ApplyServiceFactory<T, Req, F, R, In, Out, Err>
|
||||
impl<SF, F, Fut, Req, In, Res, Err> ServiceFactory<Req>
|
||||
for ApplyFactory<SF, F, Req, In, Res, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T::Service) -> R + Clone,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
SF: ServiceFactory<In, Error = Err>,
|
||||
F: FnMut(Req, &mut SF::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
// type Request = In;
|
||||
type Response = Out;
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
|
||||
type Config = T::Config;
|
||||
type Service = Apply<T::Service, Req, F, R, In, Out, Err>;
|
||||
type InitError = T::InitError;
|
||||
type Future = ApplyServiceFactoryResponse<T,Req, F, R, In, Out, Err>;
|
||||
type Config = SF::Config;
|
||||
type Service = Apply<SF::Service, F, Req, In, Res, Err>;
|
||||
type InitError = SF::InitError;
|
||||
type Future = ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>;
|
||||
|
||||
fn new_service(&self, cfg: T::Config) -> Self::Future {
|
||||
ApplyServiceFactoryResponse::new(self.service.new_service(cfg), self.f.clone())
|
||||
fn new_service(&self, cfg: SF::Config) -> Self::Future {
|
||||
let svc = self.factory.new_service(cfg);
|
||||
ApplyServiceFactoryResponse::new(svc, self.wrap_fn.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project::pin_project]
|
||||
pub struct ApplyServiceFactoryResponse<T, Req, F, R, In, Out, Err>
|
||||
pub struct ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T::Service) -> R,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
SF: ServiceFactory<In, Error = Err>,
|
||||
F: FnMut(Req, &mut SF::Service) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
#[pin]
|
||||
fut: T::Future,
|
||||
f: Option<F>,
|
||||
r: PhantomData<(In, Out)>,
|
||||
fut: SF::Future,
|
||||
wrap_fn: Option<F>,
|
||||
_phantom: PhantomData<(Req, Res)>,
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> ApplyServiceFactoryResponse<T, Req, F, R, In, Out, Err>
|
||||
impl<SF, F, Fut, Req, In, Res, Err> ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T::Service) -> R,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
SF: ServiceFactory<In, Error = Err>,
|
||||
F: FnMut(Req, &mut SF::Service) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
fn new(fut: T::Future, f: F) -> Self {
|
||||
fn new(fut: SF::Future, wrap_fn: F) -> Self {
|
||||
Self {
|
||||
f: Some(f),
|
||||
fut,
|
||||
r: PhantomData,
|
||||
wrap_fn: Some(wrap_fn),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req, F, R, In, Out, Err> Future
|
||||
for ApplyServiceFactoryResponse<T, Req, F, R, In, Out, Err>
|
||||
impl<SF, F, Fut, Req, In, Res, Err> Future
|
||||
for ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
|
||||
where
|
||||
T: ServiceFactory<Req, Error = Err>,
|
||||
F: FnMut(In, &mut T::Service) -> R,
|
||||
R: Future<Output = Result<Out, Err>>,
|
||||
SF: ServiceFactory<In, Error = Err>,
|
||||
F: FnMut(Req, &mut SF::Service) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
{
|
||||
type Output = Result<Apply<T::Service, Req, 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> {
|
||||
let this = self.project();
|
||||
|
||||
if let Poll::Ready(svc) = this.fut.poll(cx)? {
|
||||
Poll::Ready(Ok(Apply::new(svc, this.f.take().unwrap())))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
let svc = ready!(this.fut.poll(cx))?;
|
||||
Poll::Ready(Ok(Apply::new(svc, Option::take(this.wrap_fn).unwrap())))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ where
|
|||
S: Service<Req>,
|
||||
{
|
||||
srv: Rc<RefCell<(T, F)>>,
|
||||
_t: PhantomData<(C, R, S)>,
|
||||
_t: PhantomData<(C, Req, R, S)>,
|
||||
}
|
||||
|
||||
impl<F, C, Req, T, R, S, E> Clone for ApplyConfigService<F, C, Req, T, R, S, E>
|
||||
|
@ -116,7 +116,7 @@ where
|
|||
S: Service<Req>,
|
||||
{
|
||||
srv: Rc<RefCell<(T, F)>>,
|
||||
_t: PhantomData<(C, R, S)>,
|
||||
_t: PhantomData<(C, Req, R, S)>,
|
||||
}
|
||||
|
||||
impl<F, C, Req, T, R, S> Clone for ApplyConfigServiceFactory<F, C, Req, T, R, S>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
use futures_util::future::FutureExt;
|
||||
|
||||
|
@ -36,9 +36,10 @@ where
|
|||
pub fn service<S, Req>(service: S) -> BoxService<Req, S::Response, S::Error>
|
||||
where
|
||||
S: Service<Req> + 'static,
|
||||
Req: 'static,
|
||||
S::Future: 'static,
|
||||
{
|
||||
Box::new(ServiceWrapper(service))
|
||||
Box::new(ServiceWrapper(service, PhantomData))
|
||||
}
|
||||
|
||||
type Inner<C, Req, Res, Err, InitErr> = Box<
|
||||
|
@ -74,9 +75,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
struct FactoryWrapper<C, T: ServiceFactory<Req>, Req> {
|
||||
struct FactoryWrapper<C, T, Req>
|
||||
where
|
||||
T: ServiceFactory<Req>,
|
||||
{
|
||||
factory: T,
|
||||
_t: std::marker::PhantomData<C>,
|
||||
_t: PhantomData<(C, Req)>,
|
||||
}
|
||||
|
||||
impl<C, T, Req, Res, Err, InitErr> ServiceFactory<Req> for FactoryWrapper<C, T, Req>
|
||||
|
@ -106,15 +110,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
struct ServiceWrapper<S: Service<Req>, Req>(S);
|
||||
struct ServiceWrapper<S: Service<Req>, Req>(S, PhantomData<Req>);
|
||||
|
||||
impl<S, Req> ServiceWrapper<S, Req>
|
||||
where
|
||||
S: Service<Req> + 'static,
|
||||
Req: 'static,
|
||||
S::Future: 'static,
|
||||
{
|
||||
fn boxed(service: S) -> BoxService<Req, S::Response, S::Error> {
|
||||
Box::new(ServiceWrapper(service))
|
||||
Box::new(ServiceWrapper(service, PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ where
|
|||
/// ```
|
||||
pub fn fn_factory<F, Cfg, Srv, Req, Fut, Err>(
|
||||
f: F,
|
||||
) -> FnServiceNoConfig<F, Cfg, Srv, Fut, Req, Err>
|
||||
) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||
where
|
||||
Srv: Service<Req>,
|
||||
F: Fn() -> Fut,
|
||||
|
@ -247,7 +247,7 @@ where
|
|||
Srv: Service<Req>,
|
||||
{
|
||||
f: F,
|
||||
_t: PhantomData<(Fut, Cfg, Srv, Err)>,
|
||||
_t: PhantomData<(Fut, Cfg, Req, Srv, Err)>,
|
||||
}
|
||||
|
||||
impl<F, Fut, Cfg, Srv, Req, Err> FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||
|
@ -303,7 +303,7 @@ where
|
|||
Fut: Future<Output = Result<Srv, Err>>,
|
||||
{
|
||||
f: F,
|
||||
_t: PhantomData<Cfg>,
|
||||
_t: PhantomData<(Cfg, Req)>,
|
||||
}
|
||||
|
||||
impl<F, Cfg, Srv, Req, Fut, Err> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||
|
|
|
@ -303,52 +303,52 @@ where
|
|||
}
|
||||
|
||||
/// Trait for types that can be converted to a `Service`
|
||||
pub trait IntoService<T, Req>
|
||||
pub trait IntoService<S, Req>
|
||||
where
|
||||
T: Service<Req>,
|
||||
S: Service<Req>,
|
||||
{
|
||||
/// Convert to a `Service`
|
||||
fn into_service(self) -> T;
|
||||
fn into_service(self) -> S;
|
||||
}
|
||||
|
||||
/// Trait for types that can be converted to a `ServiceFactory`
|
||||
pub trait IntoServiceFactory<T, Req>
|
||||
pub trait IntoServiceFactory<SF, Req>
|
||||
where
|
||||
T: ServiceFactory<Req>,
|
||||
SF: ServiceFactory<Req>,
|
||||
{
|
||||
/// Convert `Self` to a `ServiceFactory`
|
||||
fn into_factory(self) -> T;
|
||||
fn into_factory(self) -> SF;
|
||||
}
|
||||
|
||||
impl<T, Req> IntoService<T, Req> for T
|
||||
impl<S, Req> IntoService<S, Req> for S
|
||||
where
|
||||
T: Service<Req>,
|
||||
S: Service<Req>,
|
||||
{
|
||||
fn into_service(self) -> T {
|
||||
fn into_service(self) -> S {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req> IntoServiceFactory<T, Req> for T
|
||||
impl<SF, Req> IntoServiceFactory<SF, Req> for SF
|
||||
where
|
||||
T: ServiceFactory<Req>,
|
||||
SF: ServiceFactory<Req>,
|
||||
{
|
||||
fn into_factory(self) -> T {
|
||||
fn into_factory(self) -> SF {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert object of type `T` to a service `S`
|
||||
pub fn into_service<T, S, Req>(tp: T) -> S
|
||||
pub fn into_service<U, S, Req>(tp: U) -> S
|
||||
where
|
||||
U: IntoService<S, Req>,
|
||||
S: Service<Req>,
|
||||
T: IntoService<S, Req>,
|
||||
{
|
||||
tp.into_service()
|
||||
}
|
||||
|
||||
pub mod dev {
|
||||
pub use crate::apply::{Apply, ApplyServiceFactory};
|
||||
pub use crate::apply::{Apply, ApplyFactory};
|
||||
pub use crate::fn_service::{
|
||||
FnService, FnServiceConfig, FnServiceFactory, FnServiceNoConfig,
|
||||
};
|
||||
|
|
|
@ -104,7 +104,7 @@ where
|
|||
pub struct MapServiceFactory<A, F, Req, Res> {
|
||||
a: A,
|
||||
f: F,
|
||||
r: PhantomData<Res>,
|
||||
r: PhantomData<(Res, Req)>,
|
||||
}
|
||||
|
||||
impl<A, F, Req, Res> MapServiceFactory<A, F, Req, Res> {
|
||||
|
|
|
@ -6,119 +6,123 @@ use super::{IntoServiceFactory, ServiceFactory};
|
|||
///
|
||||
/// Note that this function consumes the receiving service factory and returns
|
||||
/// a wrapped version of it.
|
||||
pub fn map_config<T, U, F, C, Req>(factory: U, f: F) -> MapConfig<T, Req, F, C>
|
||||
pub fn map_config<U, SF, S, Req, F, Cfg>(factory: U, f: F) -> MapConfig<SF, Req, F, Cfg>
|
||||
where
|
||||
T: ServiceFactory<Req>,
|
||||
U: IntoServiceFactory<T, Req>,
|
||||
F: Fn(C) -> T::Config,
|
||||
U: IntoServiceFactory<SF, Req>,
|
||||
SF: ServiceFactory<Req>,
|
||||
F: Fn(Cfg) -> SF::Config,
|
||||
{
|
||||
MapConfig::new(factory.into_factory(), f)
|
||||
}
|
||||
|
||||
/// Replace config with unit
|
||||
pub fn unit_config<T, U, C, Req>(factory: U) -> UnitConfig<T, C, Req>
|
||||
/// Replace config with unit.
|
||||
pub fn unit_config<U, SF, Cfg, Req>(factory: U) -> UnitConfig<SF, Cfg, Req>
|
||||
where
|
||||
T: ServiceFactory<Req, Config = ()>,
|
||||
U: IntoServiceFactory<T, Req>,
|
||||
U: IntoServiceFactory<SF, Req>,
|
||||
SF: ServiceFactory<Req, Config = ()>,
|
||||
{
|
||||
UnitConfig::new(factory.into_factory())
|
||||
}
|
||||
|
||||
/// `map_config()` adapter service factory
|
||||
pub struct MapConfig<A, Req, F, C> {
|
||||
a: A,
|
||||
f: F,
|
||||
e: PhantomData<(C, Req)>,
|
||||
pub struct MapConfig<SF, Req, F, Cfg> {
|
||||
factory: SF,
|
||||
cfg_mapper: F,
|
||||
e: PhantomData<(Cfg, Req)>,
|
||||
}
|
||||
|
||||
impl<T, F, C, Req> MapConfig<T, F, C, Req> {
|
||||
impl<SF, Req, F, Cfg> MapConfig<SF, Req, F, Cfg> {
|
||||
/// Create new `MapConfig` combinator
|
||||
pub(crate) fn new(a: T, f: F) -> Self
|
||||
pub(crate) fn new(factory: SF, cfg_mapper: F) -> Self
|
||||
where
|
||||
T: ServiceFactory<Req>,
|
||||
F: Fn(C) -> T::Config,
|
||||
SF: ServiceFactory<Req>,
|
||||
F: Fn(Cfg) -> SF::Config,
|
||||
{
|
||||
Self {
|
||||
a,
|
||||
f,
|
||||
factory,
|
||||
cfg_mapper,
|
||||
e: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req, F, C> Clone for MapConfig<T, Req, F, C>
|
||||
impl<SF, Req, F, Cfg> Clone for MapConfig<SF, Req, F, Cfg>
|
||||
where
|
||||
T: Clone,
|
||||
SF: Clone,
|
||||
F: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
a: self.a.clone(),
|
||||
f: self.f.clone(),
|
||||
factory: self.factory.clone(),
|
||||
cfg_mapper: self.cfg_mapper.clone(),
|
||||
e: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req, F, C> ServiceFactory<Req> for MapConfig<T, Req, F, C>
|
||||
impl<SF, Req, F, Cfg> ServiceFactory<Req> for MapConfig<SF, Req, F, Cfg>
|
||||
where
|
||||
T: ServiceFactory<Req>,
|
||||
F: Fn(C) -> T::Config,
|
||||
SF: ServiceFactory<Req>,
|
||||
F: Fn(Cfg) -> SF::Config,
|
||||
{
|
||||
type Response = T::Response;
|
||||
type Error = T::Error;
|
||||
type Response = SF::Response;
|
||||
type Error = SF::Error;
|
||||
|
||||
type Config = C;
|
||||
type Service = T::Service;
|
||||
type InitError = T::InitError;
|
||||
type Future = T::Future;
|
||||
type Config = Cfg;
|
||||
type Service = SF::Service;
|
||||
type InitError = SF::InitError;
|
||||
type Future = SF::Future;
|
||||
|
||||
fn new_service(&self, cfg: C) -> Self::Future {
|
||||
self.a.new_service((self.f)(cfg))
|
||||
fn new_service(&self, cfg: Self::Config) -> Self::Future {
|
||||
let mapped_cfg = (self.cfg_mapper)(cfg);
|
||||
self.factory.new_service(mapped_cfg)
|
||||
}
|
||||
}
|
||||
|
||||
/// `unit_config()` config combinator
|
||||
pub struct UnitConfig<T, C, Req> {
|
||||
a: T,
|
||||
e: PhantomData<(C, Req)>,
|
||||
pub struct UnitConfig<SF, Cfg, Req> {
|
||||
factory: SF,
|
||||
_phantom: PhantomData<(Cfg, Req)>,
|
||||
}
|
||||
|
||||
impl<T, C, Req> UnitConfig<T, C, Req>
|
||||
impl<SF, Cfg, Req> UnitConfig<SF, Cfg, Req>
|
||||
where
|
||||
T: ServiceFactory<Req, Config = ()>,
|
||||
SF: ServiceFactory<Req, Config = ()>,
|
||||
{
|
||||
/// Create new `UnitConfig` combinator
|
||||
pub(crate) fn new(a: T) -> Self {
|
||||
Self { a, e: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C, Req> Clone for UnitConfig<T, C, Req>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
pub(crate) fn new(factory: SF) -> Self {
|
||||
Self {
|
||||
a: self.a.clone(),
|
||||
e: PhantomData,
|
||||
factory,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C, Req> ServiceFactory<Req> for UnitConfig<T, C, Req>
|
||||
impl<SF, Cfg, Req> Clone for UnitConfig<SF, Cfg, Req>
|
||||
where
|
||||
T: ServiceFactory<Req, Config = ()>,
|
||||
SF: Clone,
|
||||
{
|
||||
type Response = T::Response;
|
||||
type Error = T::Error;
|
||||
|
||||
type Config = C;
|
||||
type Service = T::Service;
|
||||
type InitError = T::InitError;
|
||||
type Future = T::Future;
|
||||
|
||||
fn new_service(&self, _: C) -> Self::Future {
|
||||
self.a.new_service(())
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
factory: self.factory.clone(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<SF, Cfg, Req> ServiceFactory<Req> for UnitConfig<SF, Cfg, Req>
|
||||
where
|
||||
SF: ServiceFactory<Req, Config = ()>,
|
||||
{
|
||||
type Response = SF::Response;
|
||||
type Error = SF::Error;
|
||||
|
||||
type Config = Cfg;
|
||||
type Service = SF::Service;
|
||||
type InitError = SF::InitError;
|
||||
type Future = SF::Future;
|
||||
|
||||
fn new_service(&self, _: Cfg) -> Self::Future {
|
||||
self.factory.new_service(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use super::{Service, ServiceFactory};
|
|||
pub struct MapErr<S, Req, F, E> {
|
||||
service: S,
|
||||
f: F,
|
||||
_t: PhantomData<E>,
|
||||
_t: PhantomData<(E, Req)>,
|
||||
}
|
||||
|
||||
impl<S, Req, F, E> MapErr<S, Req, F, E> {
|
||||
|
@ -107,7 +107,7 @@ where
|
|||
{
|
||||
a: A,
|
||||
f: F,
|
||||
e: PhantomData<E>,
|
||||
e: PhantomData<(E, Req)>,
|
||||
}
|
||||
|
||||
impl<A, Req, F, E> MapErrServiceFactory<A, Req, F, E>
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct MapInitErr<A, F, Req, Err> {
|
|||
e: PhantomData<(Req, Err)>,
|
||||
}
|
||||
|
||||
impl<A, Req, F, Err> MapInitErr<A, Req, F, Err>
|
||||
impl<A, F, Req, Err> MapInitErr<A, F, Req, Err>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
F: Fn(A::InitError) -> Err,
|
||||
|
@ -41,7 +41,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<A, Req, F, E> ServiceFactory<Req> for MapInitErr<A, Req, F, E>
|
||||
impl<A, F, Req, E> ServiceFactory<Req> for MapInitErr<A, F, Req, E>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
F: Fn(A::InitError) -> E + Clone,
|
||||
|
@ -52,7 +52,7 @@ where
|
|||
type Config = A::Config;
|
||||
type Service = A::Service;
|
||||
type InitError = E;
|
||||
type Future = MapInitErrFuture<A, Req, F, E>;
|
||||
type Future = MapInitErrFuture<A, F, Req, E>;
|
||||
|
||||
fn new_service(&self, cfg: A::Config) -> Self::Future {
|
||||
MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone())
|
||||
|
@ -60,7 +60,7 @@ where
|
|||
}
|
||||
|
||||
#[pin_project::pin_project]
|
||||
pub struct MapInitErrFuture<A, Req, F, E>
|
||||
pub struct MapInitErrFuture<A, F, Req, E>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
F: Fn(A::InitError) -> E,
|
||||
|
@ -70,7 +70,7 @@ where
|
|||
fut: A::Future,
|
||||
}
|
||||
|
||||
impl<A, Req, F, E> MapInitErrFuture<A, Req, F, E>
|
||||
impl<A, F, Req, E> MapInitErrFuture<A, F, Req, E>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
F: Fn(A::InitError) -> E,
|
||||
|
@ -80,7 +80,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<A, Req, F, E> Future for MapInitErrFuture<A, Req, F, E>
|
||||
impl<A, F, Req, E> Future for MapInitErrFuture<A, F, Req, E>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
F: Fn(A::InitError) -> E,
|
||||
|
|
|
@ -10,10 +10,10 @@ use crate::then::{ThenService, ThenServiceFactory};
|
|||
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||
|
||||
/// Construct new pipeline with one service in pipeline chain.
|
||||
pub fn pipeline<F, T, Req>(service: F) -> Pipeline<T, Req>
|
||||
pub fn pipeline<U, S, Req>(service: U) -> Pipeline<S, Req>
|
||||
where
|
||||
F: IntoService<T, Req>,
|
||||
T: Service<Req>,
|
||||
U: IntoService<S, Req>,
|
||||
S: Service<Req>,
|
||||
{
|
||||
Pipeline {
|
||||
service: service.into_service(),
|
||||
|
@ -22,10 +22,10 @@ where
|
|||
}
|
||||
|
||||
/// Construct new pipeline factory with one service factory.
|
||||
pub fn pipeline_factory<T, F, Req>(factory: F) -> PipelineFactory<T, Req>
|
||||
pub fn pipeline_factory<U, SF, Req>(factory: U) -> PipelineFactory<SF, Req>
|
||||
where
|
||||
T: ServiceFactory<Req>,
|
||||
F: IntoServiceFactory<T, Req>,
|
||||
U: IntoServiceFactory<SF, Req>,
|
||||
SF: ServiceFactory<Req>,
|
||||
{
|
||||
PipelineFactory {
|
||||
factory: factory.into_factory(),
|
||||
|
@ -34,12 +34,15 @@ where
|
|||
}
|
||||
|
||||
/// Pipeline service - pipeline allows to compose multiple service into one service.
|
||||
pub struct Pipeline<T, Req> {
|
||||
service: T,
|
||||
pub struct Pipeline<S, Req> {
|
||||
service: S,
|
||||
_phantom: PhantomData<Req>,
|
||||
}
|
||||
|
||||
impl<T: Service<Req>, Req> Pipeline<T, Req> {
|
||||
impl<S, Req> Pipeline<S, Req>
|
||||
where
|
||||
S: Service<Req>,
|
||||
{
|
||||
/// Call another service after call to this one has resolved successfully.
|
||||
///
|
||||
/// This function can be used to chain two services together and ensure that
|
||||
|
@ -52,11 +55,11 @@ impl<T: Service<Req>, Req> Pipeline<T, Req> {
|
|||
pub fn and_then<F, U>(
|
||||
self,
|
||||
service: F,
|
||||
) -> Pipeline<impl Service<Req, Response = U::Response, Error = T::Error> + Clone, Req>
|
||||
) -> Pipeline<impl Service<Req, Response = U::Response, Error = S::Error> + Clone, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: IntoService<U, Req>,
|
||||
U: Service<T::Response, Error = T::Error>,
|
||||
F: IntoService<U, S::Response>,
|
||||
U: Service<S::Response, Error = S::Error>,
|
||||
{
|
||||
Pipeline {
|
||||
service: AndThenService::new(self.service, service.into_service()),
|
||||
|
@ -64,25 +67,24 @@ impl<T: Service<Req>, Req> Pipeline<T, Req> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Apply function to specified service and use it as a next service in
|
||||
/// chain.
|
||||
/// Apply function to specified service and use it as a next service in chain.
|
||||
///
|
||||
/// Short version of `pipeline_factory(...).and_then(apply_fn_factory(...))`
|
||||
pub fn and_then_apply_fn<U, I, F, Fut, Res, Err>(
|
||||
/// Short version of `pipeline_factory(...).and_then(apply_fn(...))`
|
||||
pub fn and_then_apply_fn<U, S1, F, Fut, In, Res, Err>(
|
||||
self,
|
||||
service: I,
|
||||
f: F,
|
||||
service: U,
|
||||
wrap_fn: F,
|
||||
) -> Pipeline<impl Service<Req, Response = Res, Error = Err> + Clone, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
I: IntoService<U, Req>,
|
||||
U: Service<Req>,
|
||||
F: FnMut(T::Response, &mut U) -> Fut,
|
||||
U: IntoService<S1, In>,
|
||||
S1: Service<In>,
|
||||
F: FnMut(S::Response, &mut S1) -> Fut,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<T::Error> + From<U::Error>,
|
||||
Err: From<S::Error> + From<S1::Error>,
|
||||
{
|
||||
Pipeline {
|
||||
service: AndThenApplyFn::new(self.service, service.into_service(), f),
|
||||
service: AndThenApplyFn::new(self.service, service.into_service(), wrap_fn),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -95,11 +97,11 @@ impl<T: Service<Req>, Req> Pipeline<T, Req> {
|
|||
pub fn then<F, U>(
|
||||
self,
|
||||
service: F,
|
||||
) -> Pipeline<impl Service<Req, Response = U::Response, Error = T::Error> + Clone, Req>
|
||||
) -> Pipeline<impl Service<Req, Response = U::Response, Error = S::Error> + Clone, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: IntoService<U, Req>,
|
||||
U: Service<Result<T::Response, T::Error>, Error = T::Error>,
|
||||
F: IntoService<U, Result<S::Response, S::Error>>,
|
||||
U: Service<Result<S::Response, S::Error>, Error = S::Error>,
|
||||
{
|
||||
Pipeline {
|
||||
service: ThenService::new(self.service, service.into_service()),
|
||||
|
@ -116,10 +118,10 @@ impl<T: Service<Req>, Req> Pipeline<T, Req> {
|
|||
/// Note that this function consumes the receiving service and returns a
|
||||
/// wrapped version of it, similar to the existing `map` methods in the
|
||||
/// standard library.
|
||||
pub fn map<F, R>(self, f: F) -> Pipeline<Map<T, F, Req, R>, Req>
|
||||
pub fn map<F, R>(self, f: F) -> Pipeline<Map<S, F, Req, R>, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(T::Response) -> R,
|
||||
F: FnMut(S::Response) -> R,
|
||||
{
|
||||
Pipeline {
|
||||
service: Map::new(self.service, f),
|
||||
|
@ -135,10 +137,10 @@ impl<T: Service<Req>, Req> Pipeline<T, Req> {
|
|||
///
|
||||
/// Note that this function consumes the receiving service and returns a
|
||||
/// wrapped version of it.
|
||||
pub fn map_err<F, E>(self, f: F) -> Pipeline<MapErr<T, Req, F, E>, Req>
|
||||
pub fn map_err<F, E>(self, f: F) -> Pipeline<MapErr<S, Req, F, E>, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(T::Error) -> E,
|
||||
F: Fn(S::Error) -> E,
|
||||
{
|
||||
Pipeline {
|
||||
service: MapErr::new(self.service, f),
|
||||
|
@ -176,40 +178,39 @@ impl<T: Service<Req>, Req> Service<Req> for Pipeline<T, Req> {
|
|||
}
|
||||
|
||||
/// Pipeline factory
|
||||
pub struct PipelineFactory<T, Req> {
|
||||
factory: T,
|
||||
pub struct PipelineFactory<SF, Req> {
|
||||
factory: SF,
|
||||
_phantom: PhantomData<Req>,
|
||||
}
|
||||
|
||||
impl<T: ServiceFactory<Req>, Req> PipelineFactory<T, Req> {
|
||||
impl<SF, Req> PipelineFactory<SF, Req>
|
||||
where
|
||||
SF: ServiceFactory<Req>,
|
||||
{
|
||||
/// Call another service after call to this one has resolved successfully.
|
||||
pub fn and_then<F, U>(
|
||||
self,
|
||||
factory: F,
|
||||
) -> PipelineFactory<
|
||||
impl ServiceFactory<
|
||||
Request = T::Request,
|
||||
Req,
|
||||
Response = U::Response,
|
||||
Error = T::Error,
|
||||
Config = T::Config,
|
||||
InitError = T::InitError,
|
||||
Service = impl Service<
|
||||
Request = T::Request,
|
||||
Response = U::Response,
|
||||
Error = T::Error,
|
||||
> + Clone,
|
||||
Error = SF::Error,
|
||||
Config = SF::Config,
|
||||
InitError = SF::InitError,
|
||||
Service = impl Service<Req, Response = U::Response, Error = SF::Error> + Clone,
|
||||
> + Clone,
|
||||
Req,
|
||||
>
|
||||
where
|
||||
Self: Sized,
|
||||
T::Config: Clone,
|
||||
F: IntoServiceFactory<U, Req>,
|
||||
SF::Config: Clone,
|
||||
F: IntoServiceFactory<U, SF::Response>,
|
||||
U: ServiceFactory<
|
||||
T::Response,
|
||||
Config = T::Config,
|
||||
Error = T::Error,
|
||||
InitError = T::InitError,
|
||||
SF::Response,
|
||||
Config = SF::Config,
|
||||
Error = SF::Error,
|
||||
InitError = SF::InitError,
|
||||
>,
|
||||
{
|
||||
PipelineFactory {
|
||||
|
@ -218,36 +219,35 @@ impl<T: ServiceFactory<Req>, Req> PipelineFactory<T, Req> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Apply function to specified service and use it as a next service in
|
||||
/// chain.
|
||||
/// Apply function to specified service and use it as a next service in chain.
|
||||
///
|
||||
/// 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<U, SF1, Fut, F, In, Res, Err>(
|
||||
self,
|
||||
factory: I,
|
||||
f: F,
|
||||
factory: U,
|
||||
wrap_fn: F,
|
||||
) -> PipelineFactory<
|
||||
impl ServiceFactory<
|
||||
Request = T::Request,
|
||||
Req,
|
||||
Response = Res,
|
||||
Error = Err,
|
||||
Config = T::Config,
|
||||
InitError = T::InitError,
|
||||
Service = impl Service<Request = T::Request, Response = Res, Error = Err> + Clone,
|
||||
Config = SF::Config,
|
||||
InitError = SF::InitError,
|
||||
Service = impl Service<Req, Response = Res, Error = Err> + Clone,
|
||||
> + Clone,
|
||||
Req,
|
||||
>
|
||||
where
|
||||
Self: Sized,
|
||||
T::Config: Clone,
|
||||
I: IntoServiceFactory<U, Req>,
|
||||
U: ServiceFactory<Req, Config = T::Config, InitError = T::InitError>,
|
||||
F: FnMut(T::Response, &mut U::Service) -> Fut + Clone,
|
||||
SF::Config: Clone,
|
||||
U: IntoServiceFactory<SF1, In>,
|
||||
SF1: ServiceFactory<In, Config = SF::Config, InitError = SF::InitError>,
|
||||
F: FnMut(SF::Response, &mut SF1::Service) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
Err: From<T::Error> + From<U::Error>,
|
||||
Err: From<SF::Error> + From<SF1::Error>,
|
||||
{
|
||||
PipelineFactory {
|
||||
factory: AndThenApplyFnFactory::new(self.factory, factory.into_factory(), f),
|
||||
factory: AndThenApplyFnFactory::new(self.factory, factory.into_factory(), wrap_fn),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -263,28 +263,24 @@ impl<T: ServiceFactory<Req>, Req> PipelineFactory<T, Req> {
|
|||
factory: F,
|
||||
) -> PipelineFactory<
|
||||
impl ServiceFactory<
|
||||
Request = T::Request,
|
||||
Req,
|
||||
Response = U::Response,
|
||||
Error = T::Error,
|
||||
Config = T::Config,
|
||||
InitError = T::InitError,
|
||||
Service = impl Service<
|
||||
Request = T::Request,
|
||||
Response = U::Response,
|
||||
Error = T::Error,
|
||||
> + Clone,
|
||||
Error = SF::Error,
|
||||
Config = SF::Config,
|
||||
InitError = SF::InitError,
|
||||
Service = impl Service<Req, Response = U::Response, Error = SF::Error> + Clone,
|
||||
> + Clone,
|
||||
Req,
|
||||
>
|
||||
where
|
||||
Self: Sized,
|
||||
T::Config: Clone,
|
||||
F: IntoServiceFactory<U, Req>,
|
||||
SF::Config: Clone,
|
||||
F: IntoServiceFactory<U, Result<SF::Response, SF::Error>>,
|
||||
U: ServiceFactory<
|
||||
Result<T::Response, T::Error>,
|
||||
Config = T::Config,
|
||||
Error = T::Error,
|
||||
InitError = T::InitError,
|
||||
Result<SF::Response, SF::Error>,
|
||||
Config = SF::Config,
|
||||
Error = SF::Error,
|
||||
InitError = SF::InitError,
|
||||
>,
|
||||
{
|
||||
PipelineFactory {
|
||||
|
@ -295,10 +291,10 @@ impl<T: ServiceFactory<Req>, Req> PipelineFactory<T, Req> {
|
|||
|
||||
/// Map this service's output to a different type, returning a new service
|
||||
/// of the resulting type.
|
||||
pub fn map<F, R>(self, f: F) -> PipelineFactory<MapServiceFactory<T, F, Req, R>, Req>
|
||||
pub fn map<F, R>(self, f: F) -> PipelineFactory<MapServiceFactory<SF, F, Req, R>, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(T::Response) -> R + Clone,
|
||||
F: FnMut(SF::Response) -> R + Clone,
|
||||
{
|
||||
PipelineFactory {
|
||||
factory: MapServiceFactory::new(self.factory, f),
|
||||
|
@ -307,10 +303,13 @@ impl<T: ServiceFactory<Req>, Req> PipelineFactory<T, Req> {
|
|||
}
|
||||
|
||||
/// 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, Req, F, E>, Req>
|
||||
pub fn map_err<F, E>(
|
||||
self,
|
||||
f: F,
|
||||
) -> PipelineFactory<MapErrServiceFactory<SF, Req, F, E>, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(T::Error) -> E + Clone,
|
||||
F: Fn(SF::Error) -> E + Clone,
|
||||
{
|
||||
PipelineFactory {
|
||||
factory: MapErrServiceFactory::new(self.factory, f),
|
||||
|
@ -319,10 +318,10 @@ impl<T: ServiceFactory<Req>, Req> PipelineFactory<T, Req> {
|
|||
}
|
||||
|
||||
/// 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, Req, E>, Req>
|
||||
pub fn map_init_err<F, E>(self, f: F) -> PipelineFactory<MapInitErr<SF, F, Req, E>, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(T::InitError) -> E + Clone,
|
||||
F: Fn(SF::InitError) -> E + Clone,
|
||||
{
|
||||
PipelineFactory {
|
||||
factory: MapInitErr::new(self.factory, f),
|
||||
|
|
Loading…
Reference in New Issue