use crate::{routes::HandlerArgs, Handler, Route};
use tower::Service;
use super::HandlerInternal;
pub(crate) trait ErasedIntoRoute<S>: Send + Sync {
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S>>;
fn into_route(self: Box<Self>, state: S) -> Route;
#[allow(dead_code)]
fn call_with_state(
self: Box<Self>,
args: HandlerArgs,
state: S,
) -> <Route as Service<HandlerArgs>>::Future;
}
pub(crate) struct BoxedIntoRoute<S>(pub(crate) Box<dyn ErasedIntoRoute<S>>);
#[allow(dead_code)]
impl<S> BoxedIntoRoute<S> {
pub(crate) fn into_route(self, state: S) -> Route {
self.0.into_route(state)
}
}
impl<S> Clone for BoxedIntoRoute<S> {
fn clone(&self) -> Self {
Self(self.0.clone_box())
}
}
#[allow(dead_code)]
impl<S> BoxedIntoRoute<S> {
pub(crate) fn from_handler<H, T>(handler: H) -> Self
where
H: Handler<T, S>,
T: Send + 'static,
S: Clone + Send + Sync + 'static,
{
Self(Box::new(MakeErasedHandler::from_handler(handler)))
}
}
pub(crate) struct MakeErasedHandler<H, S> {
pub(crate) handler: H,
pub(crate) into_route: fn(H, S) -> Route,
}
impl<H, S> Clone for MakeErasedHandler<H, S>
where
H: Clone,
{
fn clone(&self) -> Self {
Self {
handler: self.handler.clone(),
into_route: self.into_route,
}
}
}
impl<H, S> MakeErasedHandler<H, S> {
pub(crate) fn from_handler<T>(handler: H) -> Self
where
H: Handler<T, S>,
T: Send + 'static,
S: Clone + Send + Sync + 'static,
{
MakeErasedHandler {
handler,
into_route: |handler, state| HandlerInternal::into_route(handler, state),
}
}
}
impl<H, S> ErasedIntoRoute<S> for MakeErasedHandler<H, S>
where
H: Clone + Send + Sync + 'static,
S: 'static,
{
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S>> {
Box::new(self.clone())
}
fn into_route(self: Box<Self>, state: S) -> Route {
(self.into_route)(self.handler, state)
}
fn call_with_state(
self: Box<Self>,
args: HandlerArgs,
state: S,
) -> <Route as Service<HandlerArgs>>::Future {
self.into_route(state).call(args)
}
}