mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-23 19:51:06 +01:00
remove service dev module and add transformext trait
also improve docs on transform and boxed mods
This commit is contained in:
parent
0a705b1023
commit
91ea8c5dad
@ -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<T> = Pin<Box<dyn Future<Output = T>>>;
|
||||
|
||||
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<S> {
|
||||
inner: S,
|
||||
}
|
||||
|
||||
impl<S> ServiceWrapper<S> {
|
||||
fn new(inner: S) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Req, Res, Err> Service<Req> for ServiceWrapper<S>
|
||||
where
|
||||
S: Service<Req, Response = Res, Error = Err>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
type Future = BoxFuture<Result<Res, Err>>;
|
||||
|
||||
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<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>);
|
||||
|
||||
/// 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>(S);
|
||||
|
||||
impl<S, Req, Res, Err> Service<Req> for ServiceWrapper<S>
|
||||
where
|
||||
S: Service<Req, Response = Res, Error = Err>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
type Future = BoxFuture<Result<Res, Err>>;
|
||||
|
||||
fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
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 _) })
|
||||
}
|
||||
}
|
||||
|
@ -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<Req>: Service<Req> {
|
||||
/// Map this service's output to a different type, returning a new service
|
||||
@ -10,12 +13,12 @@ pub trait ServiceExt<Req>: Service<Req> {
|
||||
/// Note that this function consumes the receiving service and returns a
|
||||
/// wrapped version of it, similar to the existing `map` methods in the
|
||||
/// standard library.
|
||||
fn map<F, R>(self, f: F) -> dev::Map<Self, F, Req, R>
|
||||
fn map<F, R>(self, f: F) -> Map<Self, F, Req, R>
|
||||
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<Req>: Service<Req> {
|
||||
///
|
||||
/// Note that this function consumes the receiving service and returns a
|
||||
/// wrapped version of it.
|
||||
fn map_err<F, E>(self, f: F) -> dev::MapErr<Self, Req, F, E>
|
||||
fn map_err<F, E>(self, f: F) -> MapErr<Self, Req, F, E>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(Self::Error) -> E,
|
||||
{
|
||||
dev::MapErr::new(self, f)
|
||||
MapErr::new(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,4 +70,17 @@ pub trait ServiceFactoryExt<Req>: ServiceFactory<Req> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Req> ServiceFactoryExt<Req> for S where S: ServiceFactory<Req> {}
|
||||
impl<SF, Req> ServiceFactoryExt<Req> for SF where SF: ServiceFactory<Req> {}
|
||||
|
||||
pub trait TransformExt<S, Req>: Transform<S, Req> {
|
||||
/// Return a new `Transform` whose init error is mapped to to a different type.
|
||||
fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, Req, F, E>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(Self::InitError) -> E + Clone,
|
||||
{
|
||||
TransformMapInitErr::new(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req> TransformExt<T, Req> for T where T: Transform<T, Req> {}
|
||||
|
@ -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<Output = Service>` could
|
||||
/// act as a `ServiceFactory`.
|
||||
///
|
||||
/// # Example
|
||||
/// Any function that has following form `Fn(Config) -> Future<Output = Service>` could act as
|
||||
/// a `ServiceFactory`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::io;
|
||||
/// use actix_service::{fn_factory_with_config, fn_service, Service, ServiceFactory};
|
||||
|
@ -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<S, Req> Service<Req> for RefCell<S>
|
||||
where
|
||||
S: Service<Req>,
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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, S, I, Req>(t: T, factory: I) -> ApplyTransform<T, S, Req>
|
||||
where
|
||||
I: IntoServiceFactory<S, Req>,
|
||||
@ -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<Result<Self::Transform, Self::InitError>>;
|
||||
///
|
||||
/// fn new_transform(&self, service: S) -> Self::Future {
|
||||
/// ok(TimeoutService {
|
||||
/// ready(Ok(TimeoutService {
|
||||
/// service,
|
||||
/// timeout: self.timeout,
|
||||
/// })
|
||||
/// }))
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub trait Transform<S, Req> {
|
||||
/// Responses given by the service.
|
||||
/// Responses produced by the service.
|
||||
type Response;
|
||||
|
||||
/// Errors produced by the service.
|
||||
@ -110,16 +107,6 @@ pub trait Transform<S, Req> {
|
||||
|
||||
/// 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<F, E>(self, f: F) -> TransformMapInitErr<Self, S, Req, F, E>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(Self::InitError) -> E + Clone,
|
||||
{
|
||||
TransformMapInitErr::new(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S, Req> Transform<S, Req> for Rc<T>
|
||||
@ -152,7 +139,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// `Apply` transform to new service
|
||||
/// Apply a [`Transform`] to a [`Service`].
|
||||
pub struct ApplyTransform<T, S, Req>(Rc<(T, S)>, PhantomData<Req>);
|
||||
|
||||
impl<T, S, Req> ApplyTransform<T, S, Req>
|
||||
|
@ -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<T, S, Req, F, E> {
|
||||
transform: T,
|
||||
mapper: F,
|
||||
|
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user