Trait Service

Source
pub trait Service<Request> {
    type Response;
    type Error;

    // Required method
    fn call(
        &self,
        req: Request,
    ) -> impl Future<Output = Result<Self::Response, Self::Error>>;
}
Expand description

This Service trait leverages impl Trait to offer a efficient and flexible approach to building asynchronous services in Rust. It addresses key challenges faced with Tower’s Service trait:

  1. Efficient Borrowing: Futures can capture &self or &mut self, eliminating unnecessary cloning.
  2. Simplified Implementation: Removes the need for manual state management and Box<Pin<...>>, allowing for more idiomatic async Rust code.

§Key Features

  • Functions as a request handler rather than a future factory.
  • Eliminates the need for a poll_ready function.
  • Allows for more inline code optimization using impl Trait.
  • Supports both shared immutable (&self) and exclusive mutable (&mut self) access.

§Resource Efficiency

This design maintains reference relationships, incurring costs only when mutability is required, unlike Tower’s shared ownership model where each share has an associated cost.

Required Associated Types§

Source

type Response

The type of response returned by this service.

Source

type Error

The type of error that this service can produce.

Required Methods§

Source

fn call( &self, req: Request, ) -> impl Future<Output = Result<Self::Response, Self::Error>>

Asynchronously process the request and return the response.

This method takes a shared reference to self, allowing for efficient use of a single Service instance across multiple calls. For mutable state, consider using synchronization primitives like Mutex or RefCell.

§Arguments
  • req - The request to be processed by the service.
§Returns

A Future that resolves to a Result containing either the service’s response or an error.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<A, B, R> Service<R> for Either<A, B>
where A: Service<R>, B: Service<R, Response = A::Response, Error = A::Error>,

Source§

type Response = <A as Service<R>>::Response

Source§

type Error = <A as Service<R>>::Error

Source§

impl<Request, Response, E> Service<Request> for BoxedService<Request, Response, E>

Source§

type Response = Response

Source§

type Error = E

Source§

impl<T, F, R> Service<R> for MapTargetService<T, F>
where F: MapTarget<R>, T: Service<F::Target>,

Source§

type Response = <T as Service<<F as MapTarget<R>>::Target>>::Response

Source§

type Error = <T as Service<<F as MapTarget<R>>::Target>>::Error