Skip to main content

volter_core/
service.rs

1//! [`HandlerService`] — a [`tower::Service`] adapter that wraps a
2//! [`Handler`](crate::handler::Handler) together with its state.
3
4use std::convert::Infallible;
5use std::future::Future;
6use std::marker::PhantomData;
7use std::pin::Pin;
8use std::task::{Context, Poll};
9
10use tower::Service;
11
12use crate::body::Request;
13use crate::handler::Handler;
14
15/// A [`tower::Service`] adapter that wraps a [`Handler`] together with its
16/// state.
17///
18/// `H` is the handler type, `T` is the marker type for the handler's
19/// extractor arity (e.g. `()` for zero-arg handlers), and `S` is the
20/// application state type.
21pub struct HandlerService<H, T, S> {
22    handler: H,
23    state: S,
24    _marker: PhantomData<fn() -> T>,
25}
26
27impl<H, T, S> HandlerService<H, T, S> {
28    /// Create a new `HandlerService` from a handler and state.
29    pub fn new(handler: H, state: S) -> Self {
30        Self {
31            handler,
32            state,
33            _marker: PhantomData,
34        }
35    }
36}
37
38impl<H, T, S> Clone for HandlerService<H, T, S>
39where
40    H: Clone,
41    S: Clone,
42{
43    fn clone(&self) -> Self {
44        Self {
45            handler: self.handler.clone(),
46            state: self.state.clone(),
47            _marker: PhantomData,
48        }
49    }
50}
51
52impl<H, T, S> Service<Request> for HandlerService<H, T, S>
53where
54    H: Handler<T, S>,
55    S: Clone + Send + 'static,
56{
57    type Response = crate::body::Response;
58    type Error = Infallible;
59    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Infallible>> + Send>>;
60
61    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
62        Poll::Ready(Ok(()))
63    }
64
65    fn call(&mut self, req: Request) -> Self::Future {
66        let handler = self.handler.clone();
67        let state = self.state.clone();
68        Box::pin(async move { Ok(handler.call(req, state).await) })
69    }
70}