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