1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use futures::{Future, FutureExt};

use crate::{
    request::Request,
    responder::{DynResponder, Responder},
};
use std::pin::Pin;

/// Define a Handler of a potential http request
///
/// Implementing this trait on any type will allow the router to route request
/// towards it. Implemented by default on Controllers and on any `async
/// fn(Request<Body>) -> impl Responder`
pub trait Handler<T> {
    /// Responder returned by the handler
    type Responder: Responder;
    /// Specific future returning the responder
    type Future: Future<Output = Self::Responder>;

    /// Handle the http request, returning a future of a responder
    fn handle(&self, req: Request<T>) -> Self::Future;
}

impl<T, Fun, Fut, R> Handler<T> for Fun
where
    Fun: Fn(Request<T>) -> Fut,
    Fut: 'static + Future<Output = R> + Send,
    R: Responder,
{
    type Future = Box<dyn Future<Output = Self::Responder> + Unpin + Send>;
    type Responder = R;

    #[inline]
    fn handle(&self, req: Request<T>) -> Self::Future {
        Box::new(Box::pin((*self)(req)))
    }
}

#[doc(hidden)]
pub trait DynHandler<T> {
    fn dyn_handle(&self, req: Request<T>) -> Pin<Box<dyn Future<Output = Box<dyn DynResponder + Send>> + Unpin + Send>>;
}

impl<T, H, Fut, R> DynHandler<T> for H
where
    R: 'static + Responder + Send,
    Fut: 'static + Future<Output = R> + Unpin + Send,
    H: Handler<T, Future = Fut, Responder = R>,
{
    #[inline]
    fn dyn_handle(&self, req: Request<T>) -> Pin<Box<dyn Future<Output = Box<dyn DynResponder + Send>> + Unpin + Send>> {
        Box::pin(self.handle(req).map(|r| Box::new(Some(r)) as Box<dyn DynResponder + Send>))
    }
}