diff --git a/actix-service/src/and_then.rs b/actix-service/src/and_then.rs index 4ff24e03..04caf79d 100644 --- a/actix-service/src/and_then.rs +++ b/actix-service/src/and_then.rs @@ -121,6 +121,7 @@ where >, { inner: Rc<(A, B)>, + _phantom: PhantomData, } impl AndThenServiceFactory @@ -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, } } } diff --git a/actix-service/src/and_then_apply_fn.rs b/actix-service/src/and_then_apply_fn.rs index f0602b3d..c7bd098c 100644 --- a/actix-service/src/and_then_apply_fn.rs +++ b/actix-service/src/and_then_apply_fn.rs @@ -8,65 +8,67 @@ use std::task::{Context, Poll}; use crate::{Service, ServiceFactory}; /// `Apply` service combinator -pub(crate) struct AndThenApplyFn +pub(crate) struct AndThenApplyFn where - A: Service, - B: Service>, - F: FnMut(A::Response, &mut B) -> Fut, + S1: Service, + S2: Service, + F: FnMut(S1::Response, &mut S2) -> Fut, Fut: Future>, - Err: From + From, + Err: From + From, { - srv: Rc>, - r: PhantomData<(Fut, Res, Err)>, + svc: Rc>, + _phantom: PhantomData<(Fut, Req, In, Res, Err)>, } -impl AndThenApplyFn +impl AndThenApplyFn where - A: Service, - B: Service>, - F: FnMut(A::Response, &mut B) -> Fut, + S1: Service, + S2: Service, + F: FnMut(S1::Response, &mut S2) -> Fut, Fut: Future>, - Err: From + From, + Err: From + From, { /// 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 Clone for AndThenApplyFn +impl Clone + for AndThenApplyFn where - A: Service, - B: Service>, - F: FnMut(A::Response, &mut B) -> Fut, + S1: Service, + S2: Service, + F: FnMut(S1::Response, &mut S2) -> Fut, Fut: Future>, - Err: From + From, + Err: From + From, { fn clone(&self) -> Self { AndThenApplyFn { - srv: self.srv.clone(), - r: PhantomData, + svc: self.svc.clone(), + _phantom: PhantomData, } } } -impl Service for AndThenApplyFn +impl Service + for AndThenApplyFn where - A: Service, - B: Service>, - F: FnMut(A::Response, &mut B) -> Fut, + S1: Service, + S2: Service, + F: FnMut(S1::Response, &mut S2) -> Fut, Fut: Future>, - Err: From + From, + Err: From + From, { type Response = Res; type Error = Err; - type Future = AndThenApplyFnFuture; + type Future = AndThenApplyFnFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - 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 +pub(crate) struct AndThenApplyFnFuture where - A: Service, - B: Service>, - F: FnMut(A::Response, &mut B) -> Fut, + S1: Service, + S2: Service, + F: FnMut(S1::Response, &mut S2) -> Fut, Fut: Future>, - Err: From, - Err: From, + Err: From + From, { #[pin] - state: State, + state: State, } #[pin_project::pin_project(project = StateProj)] -enum State +enum State where - A: Service, - B: Service>, - F: FnMut(A::Response, &mut B) -> Fut, + S1: Service, + S2: Service, + F: FnMut(S1::Response, &mut S2) -> Fut, Fut: Future>, - Err: From, - Err: From, + Err: From + From, { - A(#[pin] A::Future, Option>>), + A(#[pin] S1::Future, Option>>), B(#[pin] Fut), - Empty, + Empty(PhantomData), } -impl Future for AndThenApplyFnFuture +impl Future + for AndThenApplyFnFuture where - A: Service, - B: Service>, - F: FnMut(A::Response, &mut B) -> Fut, + S1: Service, + S2: Service, + F: FnMut(S1::Response, &mut S2) -> Fut, Fut: Future>, - Err: From + From, + Err: From + From, { type Output = Result; @@ -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 { - srv: Rc<(A, B, F)>, - r: PhantomData<(Req, Fut, Res, Err)>, +pub(crate) struct AndThenApplyFnFactory { + srv: Rc<(SF1, SF2, F)>, + _phantom: PhantomData<(Fut, Req, In, Res, Err)>, } -impl AndThenApplyFnFactory +impl + AndThenApplyFnFactory where - A: ServiceFactory, - B: ServiceFactory< - Result, - Config = A::Config, - InitError = A::InitError, - >, - F: FnMut(A::Response, &mut B::Service) -> Fut + Clone, + SF1: ServiceFactory, + SF2: ServiceFactory, + F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, Fut: Future>, - Err: From + From, + Err: From + From, { /// 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 Clone for AndThenApplyFnFactory { +impl Clone + for AndThenApplyFnFactory +{ fn clone(&self) -> Self { Self { srv: self.srv.clone(), - r: PhantomData, + _phantom: PhantomData, } } } -impl ServiceFactory - for AndThenApplyFnFactory +impl ServiceFactory + for AndThenApplyFnFactory where - A: ServiceFactory, - A::Config: Clone, - B: ServiceFactory< - Result, - Config = A::Config, - InitError = A::InitError, - >, - F: FnMut(A::Response, &mut B::Service) -> Fut + Clone, + SF1: ServiceFactory, + SF1::Config: Clone, + SF2: ServiceFactory, + F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, Fut: Future>, - Err: From + From, + Err: From + From, { type Response = Res; type Error = Err; - type Service = AndThenApplyFn; - type Config = A::Config; - type InitError = A::InitError; - type Future = AndThenApplyFnFactoryResponse; + type Service = AndThenApplyFn; + type Config = SF1::Config; + type InitError = SF1::InitError; + type Future = AndThenApplyFnFactoryResponse; - 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 +pub(crate) struct AndThenApplyFnFactoryResponse where - A: ServiceFactory, - B: ServiceFactory< - Result, - Config = A::Config, - InitError = A::InitError, - >, - F: FnMut(A::Response, &mut B::Service) -> Fut + Clone, + SF1: ServiceFactory, + SF2: ServiceFactory, + F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, Fut: Future>, - Err: From, - Err: From, + Err: From, + Err: From, { #[pin] - fut_b: B::Future, + fut_s1: SF1::Future, #[pin] - fut_a: A::Future, - f: F, - a: Option, - b: Option, + fut_s2: SF2::Future, + wrap_fn: F, + s1: Option, + s2: Option, + _phantom: PhantomData, } -impl Future - for AndThenApplyFnFactoryResponse +impl Future + for AndThenApplyFnFactoryResponse where - A: ServiceFactory, - B: ServiceFactory< - Result, - Config = A::Config, - InitError = A::InitError, - >, - F: FnMut(A::Response, &mut B::Service) -> Fut + Clone, + SF1: ServiceFactory, + SF2: ServiceFactory, + F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, Fut: Future>, - Err: From + From, + Err: From + From, { - type Output = - Result, A::InitError>; + type Output = Result< + AndThenApplyFn, + SF1::InitError, + >; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { 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 for Srv { type Response = (); type Error = (); - type Future = Ready>; + type Future = Ready>; fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { 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()); diff --git a/actix-service/src/apply.rs b/actix-service/src/apply.rs index b6f6ee07..16d077ef 100644 --- a/actix-service/src/apply.rs +++ b/actix-service/src/apply.rs @@ -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( +/// +/// The In and Out type params refer to the request and response types for the wrapped service. +pub fn apply_fn( service: U, - f: F, -) -> Apply + wrap_fn: F, +) -> Apply where - T: Service, - F: FnMut(In, &mut T) -> R, - R: Future>, - U: IntoService, + U: IntoService, + S: Service, + F: FnMut(Req, &mut S) -> Fut, + Fut: Future>, { - 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( +/// +/// The In and Out type params refer to the request and response types for the wrapped service. +pub fn apply_fn_factory( service: U, f: F, -) -> ApplyServiceFactory +) -> ApplyFactory where - T: ServiceFactory, - F: FnMut(In, &mut T::Service) -> R + Clone, - R: Future>, - U: IntoServiceFactory, + U: IntoServiceFactory, + SF: ServiceFactory, + F: FnMut(Req, &mut SF::Service) -> Fut + Clone, + Fut: Future>, { - ApplyServiceFactory::new(service.into_factory(), f) + ApplyFactory::new(service.into_factory(), f) } -/// `Apply` service combinator -pub struct Apply +/// `Apply` service combinator. +/// +/// The In and Out type params refer to the request and response types for the wrapped service. +pub struct Apply where - T: Service, + S: Service, { - service: T, - f: F, - r: PhantomData<(In, Out, R)>, + service: S, + wrap_fn: F, + _phantom: PhantomData<(Req, In, Res, Err)>, } -impl Apply +impl Apply where - T: Service, - F: FnMut(In, &mut T) -> R, - R: Future>, + S: Service, + F: FnMut(Req, &mut S) -> Fut, + Fut: Future>, { /// 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 Clone for Apply +impl Clone for Apply where - T: Service + Clone, - F: FnMut(In, &mut T) -> R + Clone, - R: Future>, + S: Service + Clone, + F: FnMut(Req, &mut S) -> Fut + Clone, + Fut: Future>, { fn clone(&self) -> Self { Apply { service: self.service.clone(), - f: self.f.clone(), - r: PhantomData, + wrap_fn: self.wrap_fn.clone(), + _phantom: PhantomData, } } } -impl Service for Apply +impl Service for Apply where - T: Service, - F: FnMut(In, &mut T) -> R, - R: Future>, + S: Service, + F: FnMut(Req, &mut S) -> Fut, + Fut: Future>, { - // 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> { - 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 -where - T: ServiceFactory, - F: FnMut(In, &mut T::Service) -> R + Clone, - R: Future>, -{ - service: T, - f: F, - r: PhantomData<(R, In, Out)>, +/// `ApplyFactory` service factory combinator. +pub struct ApplyFactory { + factory: SF, + wrap_fn: F, + _phantom: PhantomData<(Req, In, Res, Err)>, } -impl ApplyServiceFactory +impl ApplyFactory where - T: ServiceFactory, - F: FnMut(In, &mut T::Service) -> R + Clone, - R: Future>, + SF: ServiceFactory, + F: FnMut(Req, &mut SF::Service) -> Fut + Clone, + Fut: Future>, { - /// 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 Clone for ApplyServiceFactory +impl Clone for ApplyFactory where - T: ServiceFactory + Clone, - F: FnMut(In, &mut T::Service) -> R + Clone, - R: Future>, + SF: ServiceFactory + Clone, + F: FnMut(Req, &mut SF::Service) -> Fut + Clone, + Fut: Future>, { 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 ServiceFactory - for ApplyServiceFactory +impl ServiceFactory + for ApplyFactory where - T: ServiceFactory, - F: FnMut(In, &mut T::Service) -> R + Clone, - R: Future>, + SF: ServiceFactory, + F: FnMut(Req, &mut SF::Service) -> Fut + Clone, + Fut: Future>, { - // type Request = In; - type Response = Out; + type Response = Res; type Error = Err; - type Config = T::Config; - type Service = Apply; - type InitError = T::InitError; - type Future = ApplyServiceFactoryResponse; + type Config = SF::Config; + type Service = Apply; + type InitError = SF::InitError; + type Future = ApplyServiceFactoryResponse; - 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 +pub struct ApplyServiceFactoryResponse where - T: ServiceFactory, - F: FnMut(In, &mut T::Service) -> R, - R: Future>, + SF: ServiceFactory, + F: FnMut(Req, &mut SF::Service) -> Fut, + Fut: Future>, { #[pin] - fut: T::Future, - f: Option, - r: PhantomData<(In, Out)>, + fut: SF::Future, + wrap_fn: Option, + _phantom: PhantomData<(Req, Res)>, } -impl ApplyServiceFactoryResponse +impl ApplyServiceFactoryResponse where - T: ServiceFactory, - F: FnMut(In, &mut T::Service) -> R, - R: Future>, + SF: ServiceFactory, + F: FnMut(Req, &mut SF::Service) -> Fut, + Fut: Future>, { - 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 Future - for ApplyServiceFactoryResponse +impl Future + for ApplyServiceFactoryResponse where - T: ServiceFactory, - F: FnMut(In, &mut T::Service) -> R, - R: Future>, + SF: ServiceFactory, + F: FnMut(Req, &mut SF::Service) -> Fut, + Fut: Future>, { - type Output = Result, T::InitError>; + type Output = Result, SF::InitError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { 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()))) } } diff --git a/actix-service/src/apply_cfg.rs b/actix-service/src/apply_cfg.rs index 61132ebb..bb491485 100644 --- a/actix-service/src/apply_cfg.rs +++ b/actix-service/src/apply_cfg.rs @@ -68,7 +68,7 @@ where S: Service, { srv: Rc>, - _t: PhantomData<(C, R, S)>, + _t: PhantomData<(C, Req, R, S)>, } impl Clone for ApplyConfigService @@ -116,7 +116,7 @@ where S: Service, { srv: Rc>, - _t: PhantomData<(C, R, S)>, + _t: PhantomData<(C, Req, R, S)>, } impl Clone for ApplyConfigServiceFactory diff --git a/actix-service/src/boxed.rs b/actix-service/src/boxed.rs index acf796b8..baf84e79 100644 --- a/actix-service/src/boxed.rs +++ b/actix-service/src/boxed.rs @@ -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(service: S) -> BoxService where S: Service + 'static, + Req: 'static, S::Future: 'static, { - Box::new(ServiceWrapper(service)) + Box::new(ServiceWrapper(service, PhantomData)) } type Inner = Box< @@ -74,9 +75,12 @@ where } } -struct FactoryWrapper, Req> { +struct FactoryWrapper +where + T: ServiceFactory, +{ factory: T, - _t: std::marker::PhantomData, + _t: PhantomData<(C, Req)>, } impl ServiceFactory for FactoryWrapper @@ -106,15 +110,16 @@ where } } -struct ServiceWrapper, Req>(S); +struct ServiceWrapper, Req>(S, PhantomData); impl ServiceWrapper where S: Service + 'static, + Req: 'static, S::Future: 'static, { fn boxed(service: S) -> BoxService { - Box::new(ServiceWrapper(service)) + Box::new(ServiceWrapper(service, PhantomData)) } } diff --git a/actix-service/src/fn_service.rs b/actix-service/src/fn_service.rs index 5a2a1b60..7d15304d 100644 --- a/actix-service/src/fn_service.rs +++ b/actix-service/src/fn_service.rs @@ -55,7 +55,7 @@ where /// ``` pub fn fn_factory( f: F, -) -> FnServiceNoConfig +) -> FnServiceNoConfig where Srv: Service, F: Fn() -> Fut, @@ -247,7 +247,7 @@ where Srv: Service, { f: F, - _t: PhantomData<(Fut, Cfg, Srv, Err)>, + _t: PhantomData<(Fut, Cfg, Req, Srv, Err)>, } impl FnServiceConfig @@ -303,7 +303,7 @@ where Fut: Future>, { f: F, - _t: PhantomData, + _t: PhantomData<(Cfg, Req)>, } impl FnServiceNoConfig diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs index 6067595c..64d731ba 100644 --- a/actix-service/src/lib.rs +++ b/actix-service/src/lib.rs @@ -303,52 +303,52 @@ where } /// Trait for types that can be converted to a `Service` -pub trait IntoService +pub trait IntoService where - T: Service, + S: 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` -pub trait IntoServiceFactory +pub trait IntoServiceFactory where - T: ServiceFactory, + SF: ServiceFactory, { /// Convert `Self` to a `ServiceFactory` - fn into_factory(self) -> T; + fn into_factory(self) -> SF; } -impl IntoService for T +impl IntoService for S where - T: Service, + S: Service, { - fn into_service(self) -> T { + fn into_service(self) -> S { self } } -impl IntoServiceFactory for T +impl IntoServiceFactory for SF where - T: ServiceFactory, + SF: ServiceFactory, { - fn into_factory(self) -> T { + fn into_factory(self) -> SF { self } } /// Convert object of type `T` to a service `S` -pub fn into_service(tp: T) -> S +pub fn into_service(tp: U) -> S where + U: IntoService, S: Service, - T: IntoService, { 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, }; diff --git a/actix-service/src/map.rs b/actix-service/src/map.rs index 05a9401a..04ef8c5f 100644 --- a/actix-service/src/map.rs +++ b/actix-service/src/map.rs @@ -104,7 +104,7 @@ where pub struct MapServiceFactory { a: A, f: F, - r: PhantomData, + r: PhantomData<(Res, Req)>, } impl MapServiceFactory { diff --git a/actix-service/src/map_config.rs b/actix-service/src/map_config.rs index 93abf49e..d4382409 100644 --- a/actix-service/src/map_config.rs +++ b/actix-service/src/map_config.rs @@ -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(factory: U, f: F) -> MapConfig +pub fn map_config(factory: U, f: F) -> MapConfig where - T: ServiceFactory, - U: IntoServiceFactory, - F: Fn(C) -> T::Config, + U: IntoServiceFactory, + SF: ServiceFactory, + F: Fn(Cfg) -> SF::Config, { MapConfig::new(factory.into_factory(), f) } -/// Replace config with unit -pub fn unit_config(factory: U) -> UnitConfig +/// Replace config with unit. +pub fn unit_config(factory: U) -> UnitConfig where - T: ServiceFactory, - U: IntoServiceFactory, + U: IntoServiceFactory, + SF: ServiceFactory, { UnitConfig::new(factory.into_factory()) } /// `map_config()` adapter service factory -pub struct MapConfig { - a: A, - f: F, - e: PhantomData<(C, Req)>, +pub struct MapConfig { + factory: SF, + cfg_mapper: F, + e: PhantomData<(Cfg, Req)>, } -impl MapConfig { +impl MapConfig { /// 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, - F: Fn(C) -> T::Config, + SF: ServiceFactory, + F: Fn(Cfg) -> SF::Config, { Self { - a, - f, + factory, + cfg_mapper, e: PhantomData, } } } -impl Clone for MapConfig +impl Clone for MapConfig 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 ServiceFactory for MapConfig +impl ServiceFactory for MapConfig where - T: ServiceFactory, - F: Fn(C) -> T::Config, + SF: ServiceFactory, + 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 { - a: T, - e: PhantomData<(C, Req)>, +pub struct UnitConfig { + factory: SF, + _phantom: PhantomData<(Cfg, Req)>, } -impl UnitConfig +impl UnitConfig where - T: ServiceFactory, + SF: ServiceFactory, { /// Create new `UnitConfig` combinator - pub(crate) fn new(a: T) -> Self { - Self { a, e: PhantomData } - } -} - -impl Clone for UnitConfig -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 ServiceFactory for UnitConfig +impl Clone for UnitConfig where - T: ServiceFactory, + 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 ServiceFactory for UnitConfig +where + SF: ServiceFactory, +{ + 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(()) } } diff --git a/actix-service/src/map_err.rs b/actix-service/src/map_err.rs index 970cf714..ae7442cc 100644 --- a/actix-service/src/map_err.rs +++ b/actix-service/src/map_err.rs @@ -12,7 +12,7 @@ use super::{Service, ServiceFactory}; pub struct MapErr { service: S, f: F, - _t: PhantomData, + _t: PhantomData<(E, Req)>, } impl MapErr { @@ -107,7 +107,7 @@ where { a: A, f: F, - e: PhantomData, + e: PhantomData<(E, Req)>, } impl MapErrServiceFactory diff --git a/actix-service/src/map_init_err.rs b/actix-service/src/map_init_err.rs index f71f3add..518daaf6 100644 --- a/actix-service/src/map_init_err.rs +++ b/actix-service/src/map_init_err.rs @@ -12,7 +12,7 @@ pub struct MapInitErr { e: PhantomData<(Req, Err)>, } -impl MapInitErr +impl MapInitErr where A: ServiceFactory, F: Fn(A::InitError) -> Err, @@ -41,7 +41,7 @@ where } } -impl ServiceFactory for MapInitErr +impl ServiceFactory for MapInitErr where A: ServiceFactory, 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; + type Future = MapInitErrFuture; 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 +pub struct MapInitErrFuture where A: ServiceFactory, F: Fn(A::InitError) -> E, @@ -70,7 +70,7 @@ where fut: A::Future, } -impl MapInitErrFuture +impl MapInitErrFuture where A: ServiceFactory, F: Fn(A::InitError) -> E, @@ -80,7 +80,7 @@ where } } -impl Future for MapInitErrFuture +impl Future for MapInitErrFuture where A: ServiceFactory, F: Fn(A::InitError) -> E, diff --git a/actix-service/src/pipeline.rs b/actix-service/src/pipeline.rs index 31ad705a..fd615d36 100644 --- a/actix-service/src/pipeline.rs +++ b/actix-service/src/pipeline.rs @@ -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(service: F) -> Pipeline +pub fn pipeline(service: U) -> Pipeline where - F: IntoService, - T: Service, + U: IntoService, + S: Service, { Pipeline { service: service.into_service(), @@ -22,10 +22,10 @@ where } /// Construct new pipeline factory with one service factory. -pub fn pipeline_factory(factory: F) -> PipelineFactory +pub fn pipeline_factory(factory: U) -> PipelineFactory where - T: ServiceFactory, - F: IntoServiceFactory, + U: IntoServiceFactory, + SF: ServiceFactory, { PipelineFactory { factory: factory.into_factory(), @@ -34,12 +34,15 @@ where } /// Pipeline service - pipeline allows to compose multiple service into one service. -pub struct Pipeline { - service: T, +pub struct Pipeline { + service: S, _phantom: PhantomData, } -impl, Req> Pipeline { +impl Pipeline +where + S: Service, +{ /// 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, Req> Pipeline { pub fn and_then( self, service: F, - ) -> Pipeline + Clone, Req> + ) -> Pipeline + Clone, Req> where Self: Sized, - F: IntoService, - U: Service, + F: IntoService, + U: Service, { Pipeline { service: AndThenService::new(self.service, service.into_service()), @@ -64,25 +67,24 @@ impl, Req> Pipeline { } } - /// 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( + /// Short version of `pipeline_factory(...).and_then(apply_fn(...))` + pub fn and_then_apply_fn( self, - service: I, - f: F, + service: U, + wrap_fn: F, ) -> Pipeline + Clone, Req> where Self: Sized, - I: IntoService, - U: Service, - F: FnMut(T::Response, &mut U) -> Fut, + U: IntoService, + S1: Service, + F: FnMut(S::Response, &mut S1) -> Fut, Fut: Future>, - Err: From + From, + Err: From + From, { 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, Req> Pipeline { pub fn then( self, service: F, - ) -> Pipeline + Clone, Req> + ) -> Pipeline + Clone, Req> where Self: Sized, - F: IntoService, - U: Service, Error = T::Error>, + F: IntoService>, + U: Service, Error = S::Error>, { Pipeline { service: ThenService::new(self.service, service.into_service()), @@ -116,10 +118,10 @@ impl, Req> Pipeline { /// 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(self, f: F) -> Pipeline, Req> + pub fn map(self, f: F) -> Pipeline, 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, Req> Pipeline { /// /// Note that this function consumes the receiving service and returns a /// wrapped version of it. - pub fn map_err(self, f: F) -> Pipeline, Req> + pub fn map_err(self, f: F) -> Pipeline, 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, Req> Service for Pipeline { } /// Pipeline factory -pub struct PipelineFactory { - factory: T, +pub struct PipelineFactory { + factory: SF, _phantom: PhantomData, } -impl, Req> PipelineFactory { +impl PipelineFactory +where + SF: ServiceFactory, +{ /// Call another service after call to this one has resolved successfully. pub fn and_then( 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 + Clone, > + Clone, Req, > where Self: Sized, - T::Config: Clone, - F: IntoServiceFactory, + SF::Config: Clone, + F: IntoServiceFactory, 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, Req> PipelineFactory { } } - /// 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( + pub fn and_then_apply_fn( 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 + Clone, + Config = SF::Config, + InitError = SF::InitError, + Service = impl Service + Clone, > + Clone, Req, > where Self: Sized, - T::Config: Clone, - I: IntoServiceFactory, - U: ServiceFactory, - F: FnMut(T::Response, &mut U::Service) -> Fut + Clone, + SF::Config: Clone, + U: IntoServiceFactory, + SF1: ServiceFactory, + F: FnMut(SF::Response, &mut SF1::Service) -> Fut + Clone, Fut: Future>, - Err: From + From, + Err: From + From, { 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, Req> PipelineFactory { 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 + Clone, > + Clone, Req, > where Self: Sized, - T::Config: Clone, - F: IntoServiceFactory, + SF::Config: Clone, + F: IntoServiceFactory>, U: ServiceFactory< - Result, - Config = T::Config, - Error = T::Error, - InitError = T::InitError, + Result, + Config = SF::Config, + Error = SF::Error, + InitError = SF::InitError, >, { PipelineFactory { @@ -295,10 +291,10 @@ impl, Req> PipelineFactory { /// Map this service's output to a different type, returning a new service /// of the resulting type. - pub fn map(self, f: F) -> PipelineFactory, Req> + pub fn map(self, f: F) -> PipelineFactory, 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, Req> PipelineFactory { } /// Map this service's error to a different error, returning a new service. - pub fn map_err(self, f: F) -> PipelineFactory, Req> + pub fn map_err( + self, + f: F, + ) -> PipelineFactory, 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, Req> PipelineFactory { } /// Map this factory's init error to a different error, returning a new service. - pub fn map_init_err(self, f: F) -> PipelineFactory, Req> + pub fn map_init_err(self, f: F) -> PipelineFactory, Req> where Self: Sized, - F: Fn(T::InitError) -> E + Clone, + F: Fn(SF::InitError) -> E + Clone, { PipelineFactory { factory: MapInitErr::new(self.factory, f),