use futures::{Future, FutureExt};
use crate::request::Request;
use crate::responder::{Responder, DynResponder};
use std::pin::Pin;
pub trait Handler<T> {
type Responder: Responder;
type Future: Future<Output=Self::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 Responder = R;
type Future = Box<dyn Future<Output=Self::Responder> + Unpin + Send>;
#[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>> + Unpin + Send>>;
}
impl<T, H, Fut, R> DynHandler<T> for H
where R: 'static + Responder,
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>> + Unpin + Send>> {
Box::pin(self.handle(req).map(|r| Box::new(Some(r)) as Box<dyn DynResponder>))
}
}