From 87bca22cc71717ff3514b996a12e530c6b2cc14c Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 27 Dec 2020 03:55:33 +0000 Subject: [PATCH] migrate over to pin-project-lite --- actix-service/Cargo.toml | 5 +- actix-service/src/and_then.rs | 82 +++--- actix-service/src/and_then_apply_fn.rs | 334 ------------------------- actix-service/src/apply.rs | 27 +- actix-service/src/apply_cfg.rs | 71 +++--- actix-service/src/lib.rs | 1 - actix-service/src/map.rs | 40 +-- actix-service/src/map_err.rs | 40 +-- actix-service/src/map_init_err.rs | 21 +- actix-service/src/pipeline.rs | 57 ----- actix-service/src/then.rs | 85 ++++--- actix-service/src/transform.rs | 49 ++-- actix-service/src/transform_err.rs | 17 +- 13 files changed, 247 insertions(+), 582 deletions(-) delete mode 100644 actix-service/src/and_then_apply_fn.rs diff --git a/actix-service/Cargo.toml b/actix-service/Cargo.toml index df3087ef..60818968 100644 --- a/actix-service/Cargo.toml +++ b/actix-service/Cargo.toml @@ -17,8 +17,9 @@ name = "actix_service" path = "src/lib.rs" [dependencies] -futures-util = "0.3.1" -pin-project = "1.0.0" +pin-project-lite = "0.2" +futures-util = { version = "0.3.7", default-features = false } +futures-core = { version = "0.3.7", default-features = false } [dev-dependencies] actix-rt = "1.0.0" diff --git a/actix-service/src/and_then.rs b/actix-service/src/and_then.rs index 863c8dd1..17d62e8f 100644 --- a/actix-service/src/and_then.rs +++ b/actix-service/src/and_then.rs @@ -7,6 +7,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use super::{Service, ServiceFactory}; /// Service for the `and_then` combinator, chaining a computation onto the end @@ -53,30 +55,43 @@ where fn call(&mut self, req: Req) -> Self::Future { AndThenServiceResponse { - state: State::A(self.0.borrow_mut().0.call(req), Some(self.0.clone())), + state: State::A { + fut: self.0.borrow_mut().0.call(req), + b: Some(self.0.clone()), + }, } } } -#[pin_project::pin_project] -pub(crate) struct AndThenServiceResponse -where - A: Service, - B: Service, -{ - #[pin] - state: State, +pin_project! { + pub(crate) struct AndThenServiceResponse + where + A: Service, + B: Service, + { + #[pin] + state: State, + } } -#[pin_project::pin_project(project = StateProj)] -enum State -where - A: Service, - B: Service, -{ - A(#[pin] A::Future, Option>>), - B(#[pin] B::Future), - Empty, +pin_project! { + #[project = StateProj] + enum State + where + A: Service, + B: Service, + { + A { + #[pin] + fut: A::Future, + b: Option>>, + }, + B { + #[pin] + fut: B::Future, + }, + Empty, + } } impl Future for AndThenServiceResponse @@ -90,17 +105,17 @@ where let mut this = self.as_mut().project(); match this.state.as_mut().project() { - StateProj::A(fut, b) => match fut.poll(cx)? { + StateProj::A { fut, b } => match fut.poll(cx)? { Poll::Ready(res) => { let b = b.take().unwrap(); this.state.set(State::Empty); // drop fut A let fut = b.borrow_mut().1.call(res); - this.state.set(State::B(fut)); + this.state.set(State::B { fut }); self.poll(cx) } Poll::Pending => Poll::Pending, }, - StateProj::B(fut) => fut.poll(cx).map(|r| { + StateProj::B { fut } => fut.poll(cx).map(|r| { this.state.set(State::Empty); r }), @@ -194,19 +209,20 @@ where } } -#[pin_project::pin_project] -pub(crate) struct AndThenServiceFactoryResponse -where - A: ServiceFactory, - B: ServiceFactory, -{ - #[pin] - fut_a: A::Future, - #[pin] - fut_b: B::Future, +pin_project! { + pub(crate) struct AndThenServiceFactoryResponse + where + A: ServiceFactory, + B: ServiceFactory, + { + #[pin] + fut_a: A::Future, + #[pin] + fut_b: B::Future, - a: Option, - b: Option, + a: Option, + b: Option, + } } impl AndThenServiceFactoryResponse diff --git a/actix-service/src/and_then_apply_fn.rs b/actix-service/src/and_then_apply_fn.rs deleted file mode 100644 index 5638bc8c..00000000 --- a/actix-service/src/and_then_apply_fn.rs +++ /dev/null @@ -1,334 +0,0 @@ -use alloc::rc::Rc; -use core::{ - cell::RefCell, - future::Future, - marker::PhantomData, - pin::Pin, - task::{Context, Poll}, -}; - -use crate::{Service, ServiceFactory}; - -/// `Apply` service combinator -pub(crate) struct AndThenApplyFn -where - S1: Service, - S2: Service, - F: FnMut(S1::Response, &mut S2) -> Fut, - Fut: Future>, - Err: From + From, -{ - svc: Rc>, - _phantom: PhantomData<(Fut, Req, In, Res, Err)>, -} - -impl AndThenApplyFn -where - S1: Service, - S2: Service, - F: FnMut(S1::Response, &mut S2) -> Fut, - Fut: Future>, - Err: From + From, -{ - /// Create new `Apply` combinator - pub(crate) fn new(a: S1, b: S2, wrap_fn: F) -> Self { - Self { - svc: Rc::new(RefCell::new((a, b, wrap_fn))), - _phantom: PhantomData, - } - } -} - -impl Clone - for AndThenApplyFn -where - S1: Service, - S2: Service, - F: FnMut(S1::Response, &mut S2) -> Fut, - Fut: Future>, - Err: From + From, -{ - fn clone(&self) -> Self { - AndThenApplyFn { - svc: self.svc.clone(), - _phantom: PhantomData, - } - } -} - -impl Service - for AndThenApplyFn -where - S1: Service, - S2: Service, - F: FnMut(S1::Response, &mut S2) -> Fut, - Fut: Future>, - Err: From + From, -{ - type Response = Res; - type Error = Err; - type Future = AndThenApplyFnFuture; - - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - 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 - } else { - Poll::Ready(Ok(())) - } - } - - fn call(&mut self, req: Req) -> Self::Future { - let fut = self.svc.borrow_mut().0.call(req); - AndThenApplyFnFuture { - state: State::A(fut, Some(self.svc.clone())), - } - } -} - -#[pin_project::pin_project] -pub(crate) struct AndThenApplyFnFuture -where - S1: Service, - S2: Service, - F: FnMut(S1::Response, &mut S2) -> Fut, - Fut: Future>, - Err: From + From, -{ - #[pin] - state: State, -} - -#[pin_project::pin_project(project = StateProj)] -enum State -where - S1: Service, - S2: Service, - F: FnMut(S1::Response, &mut S2) -> Fut, - Fut: Future>, - Err: From + From, -{ - A(#[pin] S1::Future, Option>>), - B(#[pin] Fut), - Empty(PhantomData), -} - -impl Future - for AndThenApplyFnFuture -where - S1: Service, - S2: Service, - F: FnMut(S1::Response, &mut S2) -> Fut, - Fut: Future>, - Err: From + From, -{ - type Output = Result; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let mut this = self.as_mut().project(); - - match this.state.as_mut().project() { - StateProj::A(fut, b) => match fut.poll(cx)? { - Poll::Ready(res) => { - 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)); - self.poll(cx) - } - Poll::Pending => Poll::Pending, - }, - StateProj::B(fut) => fut.poll(cx).map(|r| { - this.state.set(State::Empty(PhantomData)); - r - }), - StateProj::Empty(_) => { - panic!("future must not be polled after it returned `Poll::Ready`") - } - } - } -} - -/// `AndThenApplyFn` service factory -pub(crate) struct AndThenApplyFnFactory { - srv: Rc<(SF1, SF2, F)>, - _phantom: PhantomData<(Fut, Req, In, Res, Err)>, -} - -impl - AndThenApplyFnFactory -where - SF1: ServiceFactory, - SF2: ServiceFactory, - F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, - Fut: Future>, - Err: From + From, -{ - /// Create new `ApplyNewService` new service instance - pub(crate) fn new(a: SF1, b: SF2, wrap_fn: F) -> Self { - Self { - srv: Rc::new((a, b, wrap_fn)), - _phantom: PhantomData, - } - } -} - -impl Clone - for AndThenApplyFnFactory -{ - fn clone(&self) -> Self { - Self { - srv: self.srv.clone(), - _phantom: PhantomData, - } - } -} - -impl ServiceFactory - for AndThenApplyFnFactory -where - SF1: ServiceFactory, - SF1::Config: Clone, - SF2: ServiceFactory, - F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, - Fut: Future>, - Err: From + From, -{ - type Response = Res; - type Error = Err; - type Service = AndThenApplyFn; - type Config = SF1::Config; - type InitError = SF1::InitError; - type Future = AndThenApplyFnFactoryResponse; - - fn new_service(&self, cfg: SF1::Config) -> Self::Future { - let srv = &*self.srv; - AndThenApplyFnFactoryResponse { - 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 -where - SF1: ServiceFactory, - SF2: ServiceFactory, - F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, - Fut: Future>, - Err: From, - Err: From, -{ - #[pin] - fut_s1: SF1::Future, - #[pin] - fut_s2: SF2::Future, - wrap_fn: F, - s1: Option, - s2: Option, - _phantom: PhantomData, -} - -impl Future - for AndThenApplyFnFactoryResponse -where - SF1: ServiceFactory, - SF2: ServiceFactory, - F: FnMut(SF1::Response, &mut SF2::Service) -> Fut + Clone, - Fut: Future>, - Err: From + From, -{ - type Output = Result< - AndThenApplyFn, - SF1::InitError, - >; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); - - if this.s1.is_none() { - if let Poll::Ready(service) = this.fut_s1.poll(cx)? { - *this.s1 = Some(service); - } - } - - if this.s2.is_none() { - if let Poll::Ready(service) = this.fut_s2.poll(cx)? { - *this.s2 = Some(service); - } - } - - if this.s1.is_some() && this.s2.is_some() { - Poll::Ready(Ok(AndThenApplyFn { - svc: Rc::new(RefCell::new(( - Option::take(this.s1).unwrap(), - Option::take(this.s2).unwrap(), - this.wrap_fn.clone(), - ))), - _phantom: PhantomData, - })) - } else { - Poll::Pending - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use futures_util::future::{lazy, ok, Ready, TryFutureExt}; - - use crate::{fn_service, pipeline, pipeline_factory, Service, ServiceFactory}; - - #[derive(Clone)] - struct Srv; - - impl Service for Srv { - type Response = (); - type Error = (); - type Future = Ready>; - - crate::always_ready!(); - - fn call(&mut self, req: u8) -> Self::Future { - let _ = req; - ok(()) - } - } - - #[actix_rt::test] - async fn test_service() { - 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!(res.is_ready()); - - let res = srv.call("srv").await; - assert!(res.is_ok()); - assert_eq!(res.unwrap(), ("srv", ())); - } - - #[actix_rt::test] - 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(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!(res.is_ready()); - - let res = srv.call("srv").await; - assert!(res.is_ok()); - assert_eq!(res.unwrap(), ("srv", ())); - } -} diff --git a/actix-service/src/apply.rs b/actix-service/src/apply.rs index 9bf97bb4..7b8d6bee 100644 --- a/actix-service/src/apply.rs +++ b/actix-service/src/apply.rs @@ -5,7 +5,9 @@ use core::{ task::{Context, Poll}, }; -use futures_util::ready; + +use pin_project_lite::pin_project; +use futures_core::ready; use super::{IntoService, IntoServiceFactory, Service, ServiceFactory}; @@ -160,17 +162,18 @@ where } } -#[pin_project::pin_project] -pub struct ApplyServiceFactoryResponse -where - SF: ServiceFactory, - F: FnMut(Req, &mut SF::Service) -> Fut, - Fut: Future>, -{ - #[pin] - fut: SF::Future, - wrap_fn: Option, - _phantom: PhantomData<(Req, Res)>, +pin_project! { + pub struct ApplyServiceFactoryResponse + where + SF: ServiceFactory, + F: FnMut(Req, &mut SF::Service) -> Fut, + Fut: Future>, + { + #[pin] + fut: SF::Future, + wrap_fn: Option, + _phantom: PhantomData<(Req, Res)>, + } } impl ApplyServiceFactoryResponse diff --git a/actix-service/src/apply_cfg.rs b/actix-service/src/apply_cfg.rs index 882bb3c5..3e111231 100644 --- a/actix-service/src/apply_cfg.rs +++ b/actix-service/src/apply_cfg.rs @@ -7,6 +7,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use crate::{Service, ServiceFactory}; /// Convert `Fn(Config, &mut Service1) -> Future` fn to a service factory. @@ -158,37 +160,42 @@ where ApplyConfigServiceFactoryResponse { cfg: Some(cfg), store: self.srv.clone(), - state: State::A(self.srv.borrow().0.new_service(())), + state: State::A { + fut: self.srv.borrow().0.new_service(()), + }, } } } -#[pin_project::pin_project] -struct ApplyConfigServiceFactoryResponse -where - SF: ServiceFactory, - SF::InitError: From, - F: FnMut(Cfg, &mut SF::Service) -> Fut, - Fut: Future>, - S: Service, -{ - cfg: Option, - store: Rc>, - #[pin] - state: State, +pin_project! { + struct ApplyConfigServiceFactoryResponse + where + SF: ServiceFactory, + SF::InitError: From, + F: FnMut(Cfg, &mut SF::Service) -> Fut, + Fut: Future>, + S: Service, + { + cfg: Option, + store: Rc>, + #[pin] + state: State, + } } -#[pin_project::pin_project(project = StateProj)] -enum State -where - SF: ServiceFactory, - SF::InitError: From, - Fut: Future>, - S: Service, -{ - A(#[pin] SF::Future), - B(SF::Service), - C(#[pin] Fut), +pin_project! { + #[project = StateProj] + enum State + where + SF: ServiceFactory, + SF::InitError: From, + Fut: Future>, + S: Service, + { + A { #[pin] fut: SF::Future }, + B { svc: SF::Service }, + C { #[pin] fut: Fut }, + } } impl Future @@ -206,25 +213,25 @@ where let mut this = self.as_mut().project(); match this.state.as_mut().project() { - StateProj::A(fut) => match fut.poll(cx)? { + StateProj::A { fut } => match fut.poll(cx)? { Poll::Pending => Poll::Pending, - Poll::Ready(srv) => { - this.state.set(State::B(srv)); + Poll::Ready(svc) => { + this.state.set(State::B { svc }); self.poll(cx) } }, - StateProj::B(srv) => match srv.poll_ready(cx)? { + StateProj::B { svc } => match svc.poll_ready(cx)? { Poll::Ready(_) => { { let (_, f) = &mut *this.store.borrow_mut(); - let fut = f(this.cfg.take().unwrap(), srv); - this.state.set(State::C(fut)); + let fut = f(this.cfg.take().unwrap(), svc); + this.state.set(State::C { fut }); } self.poll(cx) } Poll::Pending => Poll::Pending, }, - StateProj::C(fut) => fut.poll(cx), + StateProj::C { fut } => fut.poll(cx), } } } diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs index 38f1f167..d66d5221 100644 --- a/actix-service/src/lib.rs +++ b/actix-service/src/lib.rs @@ -16,7 +16,6 @@ use core::{ }; mod and_then; -mod and_then_apply_fn; mod apply; mod apply_cfg; pub mod boxed; diff --git a/actix-service/src/map.rs b/actix-service/src/map.rs index 0c815298..a8afa25f 100644 --- a/actix-service/src/map.rs +++ b/actix-service/src/map.rs @@ -5,6 +5,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use super::{Service, ServiceFactory}; /// Service for the `map` combinator, changing the type of a service's response. @@ -61,15 +63,16 @@ where } } -#[pin_project::pin_project] -pub struct MapFuture -where - A: Service, - F: FnMut(A::Response) -> Res, -{ - f: F, - #[pin] - fut: A::Future, +pin_project! { + pub struct MapFuture + where + A: Service, + F: FnMut(A::Response) -> Res, + { + f: F, + #[pin] + fut: A::Future, + } } impl MapFuture @@ -154,15 +157,16 @@ where } } -#[pin_project::pin_project] -pub struct MapServiceFuture -where - A: ServiceFactory, - F: FnMut(A::Response) -> Res, -{ - #[pin] - fut: A::Future, - f: Option, +pin_project! { + pub struct MapServiceFuture + where + A: ServiceFactory, + F: FnMut(A::Response) -> Res, + { + #[pin] + fut: A::Future, + f: Option, + } } impl MapServiceFuture diff --git a/actix-service/src/map_err.rs b/actix-service/src/map_err.rs index d4e94a8d..f0bf134b 100644 --- a/actix-service/src/map_err.rs +++ b/actix-service/src/map_err.rs @@ -5,6 +5,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use super::{Service, ServiceFactory}; /// Service for the `map_err` combinator, changing the type of a service's @@ -64,15 +66,16 @@ where } } -#[pin_project::pin_project] -pub struct MapErrFuture -where - A: Service, - F: Fn(A::Error) -> E, -{ - f: F, - #[pin] - fut: A::Future, +pin_project! { + pub struct MapErrFuture + where + A: Service, + F: Fn(A::Error) -> E, + { + f: F, + #[pin] + fut: A::Future, + } } impl MapErrFuture @@ -159,15 +162,16 @@ where } } -#[pin_project::pin_project] -pub struct MapErrServiceFuture -where - A: ServiceFactory, - F: Fn(A::Error) -> E, -{ - #[pin] - fut: A::Future, - f: F, +pin_project! { + pub struct MapErrServiceFuture + where + A: ServiceFactory, + F: Fn(A::Error) -> E, + { + #[pin] + fut: A::Future, + f: F, + } } impl MapErrServiceFuture diff --git a/actix-service/src/map_init_err.rs b/actix-service/src/map_init_err.rs index b8ab5c42..9fc383aa 100644 --- a/actix-service/src/map_init_err.rs +++ b/actix-service/src/map_init_err.rs @@ -5,6 +5,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use super::ServiceFactory; /// `MapInitErr` service combinator @@ -61,15 +63,16 @@ where } } -#[pin_project::pin_project] -pub struct MapInitErrFuture -where - A: ServiceFactory, - F: Fn(A::InitError) -> E, -{ - f: F, - #[pin] - fut: A::Future, +pin_project! { + pub struct MapInitErrFuture + where + A: ServiceFactory, + F: Fn(A::InitError) -> E, + { + f: F, + #[pin] + fut: A::Future, + } } impl MapInitErrFuture diff --git a/actix-service/src/pipeline.rs b/actix-service/src/pipeline.rs index a09039b7..580d7b4c 100644 --- a/actix-service/src/pipeline.rs +++ b/actix-service/src/pipeline.rs @@ -1,11 +1,9 @@ use core::{ - future::Future, marker::PhantomData, task::{Context, Poll}, }; use crate::and_then::{AndThenService, AndThenServiceFactory}; -use crate::and_then_apply_fn::{AndThenApplyFn, AndThenApplyFnFactory}; use crate::map::{Map, MapServiceFactory}; use crate::map_err::{MapErr, MapErrServiceFactory}; use crate::map_init_err::MapInitErr; @@ -70,28 +68,6 @@ where } } - /// Apply function to specified service and use it as a next service in chain. - /// - /// Short version of `pipeline_factory(...).and_then(apply_fn(...))` - pub fn and_then_apply_fn( - self, - service: I, - wrap_fn: F, - ) -> Pipeline + Clone, Req> - where - Self: Sized, - I: IntoService, - S1: Service, - F: FnMut(S::Response, &mut S1) -> Fut, - Fut: Future>, - Err: From + From, - { - Pipeline { - service: AndThenApplyFn::new(self.service, service.into_service(), wrap_fn), - _phantom: PhantomData, - } - } - /// Chain on a computation for when a call to the service finished, /// passing the result of the call to the next service `U`. /// @@ -222,39 +198,6 @@ where } } - /// 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( - self, - factory: I, - wrap_fn: F, - ) -> PipelineFactory< - impl ServiceFactory< - Req, - Response = Res, - Error = Err, - Config = SF::Config, - InitError = SF::InitError, - Service = impl Service + Clone, - > + Clone, - Req, - > - where - Self: Sized, - SF::Config: Clone, - I: IntoServiceFactory, - SF1: ServiceFactory, - F: FnMut(SF::Response, &mut SF1::Service) -> Fut + Clone, - Fut: Future>, - Err: From + From, - { - PipelineFactory { - factory: AndThenApplyFnFactory::new(self.factory, factory.into_factory(), wrap_fn), - _phantom: PhantomData, - } - } - /// Create `NewService` to chain on a computation for when a call to the /// service finished, passing the result of the call to the next /// service `U`. diff --git a/actix-service/src/then.rs b/actix-service/src/then.rs index 2de5a60d..179713ac 100644 --- a/actix-service/src/then.rs +++ b/actix-service/src/then.rs @@ -7,6 +7,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use super::{Service, ServiceFactory}; /// Service for the `then` combinator, chaining a computation onto the end of @@ -53,30 +55,36 @@ where fn call(&mut self, req: Req) -> Self::Future { ThenServiceResponse { - state: State::A(self.0.borrow_mut().0.call(req), Some(self.0.clone())), + state: State::A { + fut: self.0.borrow_mut().0.call(req), + b: Some(self.0.clone()), + }, } } } -#[pin_project::pin_project] -pub(crate) struct ThenServiceResponse -where - A: Service, - B: Service>, -{ - #[pin] - state: State, +pin_project! { + pub(crate) struct ThenServiceResponse + where + A: Service, + B: Service>, + { + #[pin] + state: State, + } } -#[pin_project::pin_project(project = StateProj)] -enum State -where - A: Service, - B: Service>, -{ - A(#[pin] A::Future, Option>>), - B(#[pin] B::Future), - Empty, +pin_project! { + #[project = StateProj] + enum State + where + A: Service, + B: Service>, + { + A { #[pin] fut: A::Future, b: Option>> }, + B { #[pin] fut: B::Future }, + Empty, + } } impl Future for ThenServiceResponse @@ -90,17 +98,17 @@ where let mut this = self.as_mut().project(); match this.state.as_mut().project() { - StateProj::A(fut, b) => match fut.poll(cx) { + StateProj::A { fut, b } => match fut.poll(cx) { Poll::Ready(res) => { let b = b.take().unwrap(); this.state.set(State::Empty); // drop fut A let fut = b.borrow_mut().1.call(res); - this.state.set(State::B(fut)); + this.state.set(State::B { fut }); self.poll(cx) } Poll::Pending => Poll::Pending, }, - StateProj::B(fut) => fut.poll(cx).map(|r| { + StateProj::B { fut } => fut.poll(cx).map(|r| { this.state.set(State::Empty); r }), @@ -162,23 +170,24 @@ impl Clone for ThenServiceFactory { } } -#[pin_project::pin_project] -pub(crate) struct ThenServiceFactoryResponse -where - A: ServiceFactory, - B: ServiceFactory< - Result, - Config = A::Config, - Error = A::Error, - InitError = A::InitError, - >, -{ - #[pin] - fut_b: B::Future, - #[pin] - fut_a: A::Future, - a: Option, - b: Option, +pin_project! { + pub(crate) struct ThenServiceFactoryResponse + where + A: ServiceFactory, + B: ServiceFactory< + Result, + Config = A::Config, + Error = A::Error, + InitError = A::InitError, + >, + { + #[pin] + fut_b: B::Future, + #[pin] + fut_a: A::Future, + a: Option, + b: Option, + } } impl ThenServiceFactoryResponse diff --git a/actix-service/src/transform.rs b/actix-service/src/transform.rs index 602e7f54..76e4547a 100644 --- a/actix-service/src/transform.rs +++ b/actix-service/src/transform.rs @@ -6,6 +6,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use crate::transform_err::TransformMapInitErr; use crate::{IntoServiceFactory, Service, ServiceFactory}; @@ -187,30 +189,35 @@ where fn new_service(&self, cfg: S::Config) -> Self::Future { ApplyTransformFuture { store: self.0.clone(), - state: ApplyTransformFutureState::A(self.0.as_ref().1.new_service(cfg)), + state: ApplyTransformFutureState::A { + fut: self.0.as_ref().1.new_service(cfg), + }, } } } -#[pin_project::pin_project] -pub struct ApplyTransformFuture -where - S: ServiceFactory, - T: Transform, -{ - store: Rc<(T, S)>, - #[pin] - state: ApplyTransformFutureState, +pin_project! { + pub struct ApplyTransformFuture + where + S: ServiceFactory, + T: Transform, + { + store: Rc<(T, S)>, + #[pin] + state: ApplyTransformFutureState, + } } -#[pin_project::pin_project(project = ApplyTransformFutureStateProj)] -pub enum ApplyTransformFutureState -where - S: ServiceFactory, - T: Transform, -{ - A(#[pin] S::Future), - B(#[pin] T::Future), +pin_project! { + #[project = ApplyTransformFutureStateProj] + pub enum ApplyTransformFutureState + where + S: ServiceFactory, + T: Transform, + { + A { #[pin] fut: S::Future }, + B { #[pin] fut: T::Future }, + } } impl Future for ApplyTransformFuture @@ -224,15 +231,15 @@ where let mut this = self.as_mut().project(); match this.state.as_mut().project() { - ApplyTransformFutureStateProj::A(fut) => match fut.poll(cx)? { + ApplyTransformFutureStateProj::A { fut } => match fut.poll(cx)? { Poll::Ready(srv) => { let fut = this.store.0.new_transform(srv); - this.state.set(ApplyTransformFutureState::B(fut)); + this.state.set(ApplyTransformFutureState::B { fut }); self.poll(cx) } Poll::Pending => Poll::Pending, }, - ApplyTransformFutureStateProj::B(fut) => fut.poll(cx), + ApplyTransformFutureStateProj::B { fut } => fut.poll(cx), } } } diff --git a/actix-service/src/transform_err.rs b/actix-service/src/transform_err.rs index 355f2720..cbf5fe3b 100644 --- a/actix-service/src/transform_err.rs +++ b/actix-service/src/transform_err.rs @@ -5,6 +5,8 @@ use core::{ task::{Context, Poll}, }; +use pin_project_lite::pin_project; + use super::Transform; /// Transform for the `map_init_err` combinator, changing the type of a new @@ -65,15 +67,16 @@ where } } -#[pin_project::pin_project] -pub struct TransformMapInitErrFuture -where +pin_project! { + pub struct TransformMapInitErrFuture + where T: Transform, F: Fn(T::InitError) -> E, -{ - #[pin] - fut: T::Future, - f: F, + { + #[pin] + fut: T::Future, + f: F, + } } impl Future for TransformMapInitErrFuture