async_svc/
lib.rs

1//! WIP Modern Service Trait
2
3#![deny(rust_2018_idioms, nonstandard_style)]
4// #![warn(missing_docs)]
5
6use std::{
7    future::Future,
8    pin::Pin,
9    task::{Context, Poll},
10};
11
12mod boxed;
13mod ext;
14mod factory;
15mod fn_service;
16mod map;
17mod then;
18
19pub use boxed::{box_svc, BoxFut, BoxSvc};
20pub use ext::SvcExt;
21pub use fn_service::FnSvc;
22pub use map::MapSvc;
23pub use then::ThenSvc;
24
25/// Service trait representing an asynchronous request/response operation.
26pub trait Svc<Req> {
27    /// Output type.
28    type Res;
29
30    /// Response future.
31    type Fut: Future<Output = Self::Res>;
32
33    /// To be called before `exec` to signal wether the service is ready to process requests.
34    /// As such, the check should be inexpensive. Returning `Poll::Pending` acts as back-pressure.
35    /// The default implementation unconditionally indicates the service is ready.
36    #[allow(unused_variables)]
37    fn poll_ready(self: Pin<&mut Self>, cx: Context<'_>) -> Poll<()> {
38        Poll::Ready(())
39    }
40
41    /// Processes request, producing a future that outputs the response type.
42    fn exec(self: Pin<&mut Self>, req: Req) -> Self::Fut;
43}
44
45impl<S, Req> Svc<Req> for Box<S>
46where
47    S: Svc<Req>,
48{
49    type Res = S::Res;
50    type Fut = S::Fut;
51
52    fn poll_ready(mut self: Pin<&mut Self>, cx: Context<'_>) -> Poll<()> {
53        self.as_mut().poll_ready(cx)
54    }
55
56    fn exec(mut self: Pin<&mut Self>, req: Req) -> Self::Fut {
57        self.as_mut().exec(req)
58    }
59}