use crate::{
request::Request,
responder::{DynResponder, Responder},
};
use futures::{Future, FutureExt};
use std::pin::Pin;
pub trait Handler {
type Responder: Responder;
type Future: Future<Output = Self::Responder>;
fn handle(&self, req: Request) -> Self::Future;
}
impl<R, Fut, F> Handler for F
where
R: Responder,
Fut: Future<Output = R> + Send + 'static,
F: Fn(Request) -> Fut,
{
type Future = Box<dyn Future<Output = Self::Responder> + Unpin + Send>;
type Responder = R;
#[inline]
fn handle(&self, req: Request) -> Self::Future {
Box::new(Box::pin((*self)(req)))
}
}
#[doc(hidden)]
pub trait DynHandler {
fn handle(&self, req: Request) -> Pin<Box<dyn Future<Output = Box<dyn DynResponder + Send>> + Unpin + Send>>;
}
impl<R, Fut, F> DynHandler for F
where
R: 'static + Responder + Send,
Fut: 'static + Future<Output = R> + Send + Unpin,
F: Handler<Future = Fut, Responder = R>,
{
#[inline]
fn handle(&self, req: Request) -> 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>))
}
}