From 91ea8c5dad612e5b6745522330ff25cc75a31b3a Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 10 Mar 2021 03:18:09 +0000 Subject: [PATCH] remove service dev module and add transformext trait also improve docs on transform and boxed mods --- actix-service/src/boxed.rs | 63 ++++++++++++++++-------------- actix-service/src/ext.rs | 28 ++++++++++--- actix-service/src/fn_service.rs | 10 ++--- actix-service/src/lib.rs | 18 ++------- actix-service/src/transform.rs | 41 +++++++------------ actix-service/src/transform_err.rs | 6 +-- actix-tracing/src/lib.rs | 2 +- 7 files changed, 79 insertions(+), 89 deletions(-) diff --git a/actix-service/src/boxed.rs b/actix-service/src/boxed.rs index 4afaa6c3..a872ca9f 100644 --- a/actix-service/src/boxed.rs +++ b/actix-service/src/boxed.rs @@ -1,12 +1,11 @@ +//! Trait object forms of services and service factories. + use alloc::{boxed::Box, rc::Rc}; -use core::{ - future::Future, - pin::Pin, - task::{Context, Poll}, -}; +use core::{future::Future, pin::Pin}; use crate::{Service, ServiceFactory}; +/// A boxed future without a Send bound or lifetime parameters. pub type BoxFuture = Pin>>; macro_rules! service_object { @@ -23,17 +22,41 @@ macro_rules! service_object { Req: 'static, S::Future: 'static, { - $type::new(ServiceWrapper(service)) + $type::new(ServiceWrapper::new(service)) } }; } service_object!(BoxService, Box, service); - service_object!(RcService, Rc, rc_service); -/// Type alias for service factory trait object that would produce a trait object service -/// (`BoxService`, `RcService`, etc.) +struct ServiceWrapper { + inner: S, +} + +impl ServiceWrapper { + fn new(inner: S) -> Self { + Self { inner } + } +} + +impl Service for ServiceWrapper +where + S: Service, + S::Future: 'static, +{ + type Response = Res; + type Error = Err; + type Future = BoxFuture>; + + crate::forward_ready!(inner); + + fn call(&self, req: Req) -> Self::Future { + Box::pin(self.inner.call(req)) + } +} + +/// Wrapper for a service factory trait object that will produce a boxed trait object service. pub struct BoxServiceFactory(Inner); /// Create service factory trait object. @@ -107,26 +130,6 @@ where fn new_service(&self, cfg: Cfg) -> Self::Future { let f = self.0.new_service(cfg); - Box::pin(async { f.await.map(|s| Box::new(ServiceWrapper(s)) as _) }) - } -} - -struct ServiceWrapper(S); - -impl Service for ServiceWrapper -where - S: Service, - S::Future: 'static, -{ - type Response = Res; - type Error = Err; - type Future = BoxFuture>; - - fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll> { - self.0.poll_ready(ctx) - } - - fn call(&self, req: Req) -> Self::Future { - Box::pin(self.0.call(req)) + Box::pin(async { f.await.map(|s| Box::new(ServiceWrapper::new(s)) as _) }) } } diff --git a/actix-service/src/ext.rs b/actix-service/src/ext.rs index e778d11e..d931596b 100644 --- a/actix-service/src/ext.rs +++ b/actix-service/src/ext.rs @@ -1,4 +1,7 @@ -use crate::{dev, Service, ServiceFactory}; +use crate::{ + map::Map, map_err::MapErr, transform_err::TransformMapInitErr, Service, ServiceFactory, + Transform, +}; pub trait ServiceExt: Service { /// Map this service's output to a different type, returning a new service @@ -10,12 +13,12 @@ pub trait ServiceExt: 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) -> dev::Map + fn map(self, f: F) -> Map where Self: Sized, F: FnMut(Self::Response) -> R, { - dev::Map::new(self, f) + Map::new(self, f) } /// Map this service's error to a different error, returning a new service. @@ -26,12 +29,12 @@ pub trait ServiceExt: Service { /// /// Note that this function consumes the receiving service and returns a /// wrapped version of it. - fn map_err(self, f: F) -> dev::MapErr + fn map_err(self, f: F) -> MapErr where Self: Sized, F: Fn(Self::Error) -> E, { - dev::MapErr::new(self, f) + MapErr::new(self, f) } } @@ -67,4 +70,17 @@ pub trait ServiceFactoryExt: ServiceFactory { } } -impl ServiceFactoryExt for S where S: ServiceFactory {} +impl ServiceFactoryExt for SF where SF: ServiceFactory {} + +pub trait TransformExt: Transform { + /// Return a new `Transform` whose init error is mapped to to a different type. + fn map_init_err(self, f: F) -> TransformMapInitErr + where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone, + { + TransformMapInitErr::new(self, f) + } +} + +impl TransformExt for T where T: Transform {} diff --git a/actix-service/src/fn_service.rs b/actix-service/src/fn_service.rs index 19151eed..8c1a6f51 100644 --- a/actix-service/src/fn_service.rs +++ b/actix-service/src/fn_service.rs @@ -15,8 +15,7 @@ where /// Create `ServiceFactory` for function that can produce services /// -/// # Example -/// +/// # Examples /// ``` /// use std::io; /// use actix_service::{fn_factory, fn_service, Service, ServiceFactory}; @@ -62,11 +61,10 @@ where /// Create `ServiceFactory` for function that accepts config argument and can produce services /// -/// Any function that has following form `Fn(Config) -> Future` could -/// act as a `ServiceFactory`. -/// -/// # Example +/// Any function that has following form `Fn(Config) -> Future` could act as +/// a `ServiceFactory`. /// +/// # Examples /// ``` /// use std::io; /// use actix_service::{fn_factory_with_config, fn_service, Service, ServiceFactory}; diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs index b690553f..cc82bfa6 100644 --- a/actix-service/src/lib.rs +++ b/actix-service/src/lib.rs @@ -34,11 +34,11 @@ mod transform_err; pub use self::apply::{apply_fn, apply_fn_factory}; pub use self::apply_cfg::{apply_cfg, apply_cfg_factory}; -pub use self::ext::{ServiceExt, ServiceFactoryExt}; +pub use self::ext::{ServiceExt, ServiceFactoryExt, TransformExt}; pub use self::fn_service::{fn_factory, fn_factory_with_config, fn_service}; pub use self::map_config::{map_config, unit_config}; pub use self::pipeline::{pipeline, pipeline_factory, Pipeline, PipelineFactory}; -pub use self::transform::{apply, Transform}; +pub use self::transform::{apply, ApplyTransform, Transform}; #[allow(unused_imports)] use self::ready::{err, ok, ready, Ready}; @@ -220,6 +220,7 @@ where } } +/// This impl is deprecated since v2 because the `Service` trait now receives shared reference. impl Service for RefCell where S: Service, @@ -313,16 +314,3 @@ where { tp.into_service() } - -pub mod dev { - pub use crate::apply::{Apply, ApplyFactory}; - pub use crate::fn_service::{ - FnService, FnServiceConfig, FnServiceFactory, FnServiceNoConfig, - }; - pub use crate::map::{Map, MapServiceFactory}; - pub use crate::map_config::{MapConfig, UnitConfig}; - pub use crate::map_err::{MapErr, MapErrServiceFactory}; - pub use crate::map_init_err::MapInitErr; - pub use crate::transform::ApplyTransform; - pub use crate::transform_err::TransformMapInitErr; -} diff --git a/actix-service/src/transform.rs b/actix-service/src/transform.rs index 7f477e54..b0abe72b 100644 --- a/actix-service/src/transform.rs +++ b/actix-service/src/transform.rs @@ -9,10 +9,9 @@ use core::{ use futures_core::ready; use pin_project_lite::pin_project; -use crate::transform_err::TransformMapInitErr; use crate::{IntoServiceFactory, Service, ServiceFactory}; -/// Apply transform to a service. +/// Apply a [`Transform`] to a [`Service`]. pub fn apply(t: T, factory: I) -> ApplyTransform where I: IntoServiceFactory, @@ -25,9 +24,8 @@ where /// The `Transform` trait defines the interface of a service factory that wraps inner service /// during construction. /// -/// Transform(middleware) wraps inner service and runs during -/// inbound and/or outbound processing in the request/response lifecycle. -/// It may modify request and/or response. +/// Transform(middleware) wraps inner service and runs during inbound and/or outbound processing in +/// the request/response lifecycle. It may modify request and/or response. /// /// For example, timeout transform: /// @@ -51,20 +49,19 @@ where /// fn call(&self, req: S::Request) -> Self::Future { /// TimeoutServiceResponse { /// fut: self.service.call(req), -/// sleep: Delay::new(clock::now() + self.timeout), +/// sleep: Sleep::new(clock::now() + self.timeout), /// } /// } /// } /// ``` /// -/// Timeout service in above example is decoupled from underlying service implementation -/// and could be applied to any service. +/// Timeout service in above example is decoupled from underlying service implementation and could +/// be applied to any service. /// -/// The `Transform` trait defines the interface of a Service factory. `Transform` -/// is often implemented for middleware, defining how to construct a -/// middleware Service. A Service that is constructed by the factory takes -/// the Service that follows it during execution as a parameter, assuming -/// ownership of the next Service. +/// The `Transform` trait defines the interface of a Service factory. `Transform` is often +/// implemented for middleware, defining how to construct a middleware Service. A Service that is +/// constructed by the factory takes the Service that follows it during execution as a parameter, +/// assuming ownership of the next Service. /// /// Factory for `Timeout` middleware from the above example could look like this: /// @@ -85,15 +82,15 @@ where /// type Future = Ready>; /// /// fn new_transform(&self, service: S) -> Self::Future { -/// ok(TimeoutService { +/// ready(Ok(TimeoutService { /// service, /// timeout: self.timeout, -/// }) +/// })) /// } /// } /// ``` pub trait Transform { - /// Responses given by the service. + /// Responses produced by the service. type Response; /// Errors produced by the service. @@ -110,16 +107,6 @@ pub trait Transform { /// Creates and returns a new Transform component, asynchronously fn new_transform(&self, service: S) -> Self::Future; - - /// Map this transform's factory error to a different error, - /// returning a new transform service factory. - fn map_init_err(self, f: F) -> TransformMapInitErr - where - Self: Sized, - F: Fn(Self::InitError) -> E + Clone, - { - TransformMapInitErr::new(self, f) - } } impl Transform for Rc @@ -152,7 +139,7 @@ where } } -/// `Apply` transform to new service +/// Apply a [`Transform`] to a [`Service`]. pub struct ApplyTransform(Rc<(T, S)>, PhantomData); impl ApplyTransform diff --git a/actix-service/src/transform_err.rs b/actix-service/src/transform_err.rs index cbf5fe3b..b4695d5c 100644 --- a/actix-service/src/transform_err.rs +++ b/actix-service/src/transform_err.rs @@ -9,10 +9,8 @@ use pin_project_lite::pin_project; use super::Transform; -/// Transform for the `map_init_err` combinator, changing the type of a new -/// transform's init error. -/// -/// This is created by the `Transform::map_init_err` method. +/// Transform for the [`TransformExt::map_init_err`] combinator, changing the type of a new +/// [`Transform`]'s initialization error. pub struct TransformMapInitErr { transform: T, mapper: F, diff --git a/actix-tracing/src/lib.rs b/actix-tracing/src/lib.rs index b34f40d6..89e93be1 100644 --- a/actix-tracing/src/lib.rs +++ b/actix-tracing/src/lib.rs @@ -7,7 +7,7 @@ use core::marker::PhantomData; use actix_service::{ - apply, dev::ApplyTransform, IntoServiceFactory, Service, ServiceFactory, Transform, + apply, ApplyTransform, IntoServiceFactory, Service, ServiceFactory, Transform, }; use futures_util::future::{ok, Either, Ready}; use tracing_futures::{Instrument, Instrumented};