use std::{future::Future, pin::Pin};
use crate::utils::captures::Captures;
use super::handler::Handler;
pub type BoxFuture<'a, R> = Pin<Box<dyn Future<Output = R> + Send + 'a>>;
pub type DynErasedHandler<T, O, E> = dyn DynHandler<T, E, Output = O>;
pub type ErasedHandler<T, O, E> = Box<DynErasedHandler<T, O, E>>;
pub trait DynHandler<T, E>: Send + Sync {
type Output;
fn handle(&self, request: T) -> BoxFuture<'_, Result<Self::Output, E>>;
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct TypeErasedHandler<H>(pub H);
impl<T, E, H: Handler<T, E>> Handler<T, E> for TypeErasedHandler<H> {
type Output = H::Output;
fn handle<'a>(
&'a self,
request: T,
) -> impl Future<Output = Result<Self::Output, E>> + Send + Captures<(&'a Self, T)> {
self.0.handle(request)
}
}
impl<T, E, H> DynHandler<T, E> for TypeErasedHandler<H>
where
T: Send + 'static,
H: Handler<T, E>,
{
type Output = H::Output;
fn handle(&self, request: T) -> BoxFuture<'_, Result<Self::Output, E>> {
Box::pin(async move { self.0.handle(request).await })
}
}