Trait Transform

Source
pub trait Transform<S> {
    type Request;
    type Response;
    type Error;
    type Transform: Service<Request = Self::Request, Response = Self::Response, Error = Self::Error>;
    type InitError;
    type Future: Future<Output = Result<Self::Transform, Self::InitError>>;

    // Required method
    fn new_transform(&self, service: S) -> Self::Future;

    // Provided method
    fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, F, E>
       where Self: Sized,
             F: Fn(Self::InitError) -> E + Clone { ... }
}
Expand description

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.

For example, timeout transform:

pub struct Timeout<S> {
    service: S,
    timeout: Duration,
}

impl<S> Service for Timeout<S>
where
    S: Service,
{
    type Request = S::Request;
    type Response = S::Response;
    type Error = TimeoutError<S::Error>;
    type Future = TimeoutServiceResponse<S>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        ready!(self.service.poll_ready(cx)).map_err(TimeoutError::Service)
    }

    fn call(&mut self, req: S::Request) -> Self::Future {
        TimeoutServiceResponse {
            fut: self.service.call(req),
            sleep: Delay::new(clock::now() + self.timeout),
        }
    }
}

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.

Factory for Timeout middleware from the above example could look like this:

pub struct TimeoutTransform {
    timeout: Duration,
}

impl<S> Transform<S> for TimeoutTransform<E>
where
    S: Service,
{
    type Request = S::Request;
    type Response = S::Response;
    type Error = TimeoutError<S::Error>;
    type InitError = S::Error;
    type Transform = Timeout<S>;
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ok(TimeoutService {
            service,
            timeout: self.timeout,
        })
    }
}

Required Associated Types§

Source

type Request

Requests handled by the service.

Source

type Response

Responses given by the service.

Source

type Error

Errors produced by the service.

Source

type Transform: Service<Request = Self::Request, Response = Self::Response, Error = Self::Error>

The TransformService value created by this factory

Source

type InitError

Errors produced while building a transform service.

Source

type Future: Future<Output = Result<Self::Transform, Self::InitError>>

The future response value.

Required Methods§

Source

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Provided Methods§

Source

fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, F, E>
where Self: Sized, F: Fn(Self::InitError) -> E + Clone,

Map this transforms’s factory error to a different error, returning a new transform service factory.

Implementations on Foreign Types§

Source§

impl<T, S> Transform<S> for Rc<T>
where T: Transform<S>,

Source§

type Request = <T as Transform<S>>::Request

Source§

type Response = <T as Transform<S>>::Response

Source§

type Error = <T as Transform<S>>::Error

Source§

type InitError = <T as Transform<S>>::InitError

Source§

type Transform = <T as Transform<S>>::Transform

Source§

type Future = <T as Transform<S>>::Future

Source§

fn new_transform(&self, service: S) -> T::Future

Source§

impl<T, S> Transform<S> for Arc<T>
where T: Transform<S>,

Source§

type Request = <T as Transform<S>>::Request

Source§

type Response = <T as Transform<S>>::Response

Source§

type Error = <T as Transform<S>>::Error

Source§

type InitError = <T as Transform<S>>::InitError

Source§

type Transform = <T as Transform<S>>::Transform

Source§

type Future = <T as Transform<S>>::Future

Source§

fn new_transform(&self, service: S) -> T::Future

Implementors§

Source§

impl<T, S, F, E> Transform<S> for TransformMapInitErr<T, S, F, E>
where T: Transform<S>, F: Fn(T::InitError) -> E + Clone,

Source§

type Request = <T as Transform<S>>::Request

Source§

type Response = <T as Transform<S>>::Response

Source§

type Error = <T as Transform<S>>::Error

Source§

type Transform = <T as Transform<S>>::Transform

Source§

type InitError = E

Source§

type Future = TransformMapInitErrFuture<T, S, F, E>