use crate::handler::RequestHandler;
use crate::handler::handler_decorator::{HandlerDecorator, HandlerDecoratorComposer, IdentityHandlerDecorator};
pub trait HandlerDecoratorFactory: Sized {
type Output<In>: HandlerDecorator<In> + 'static
where
In: RequestHandler;
fn create_decorator<In>(&self) -> Self::Output<In>
where
In: RequestHandler;
}
pub trait HandlerDecoratorFactoryExt: HandlerDecoratorFactory {
fn and_then<F: HandlerDecoratorFactory>(self, factory: F) -> HandlerDecoratorFactoryComposer<Self, F> {
HandlerDecoratorFactoryComposer { factory_1: self, factory_2: factory }
}
#[allow(unused)]
fn compose<F: HandlerDecoratorFactory>(self, factory: F) -> HandlerDecoratorFactoryComposer<F, Self> {
HandlerDecoratorFactoryComposer { factory_1: factory, factory_2: self }
}
}
impl<T: HandlerDecoratorFactory> HandlerDecoratorFactoryExt for T {}
#[derive(Debug, Default, Copy, Clone)]
pub struct IdentityHandlerDecoratorFactory;
impl HandlerDecoratorFactory for IdentityHandlerDecoratorFactory {
type Output<In>
= IdentityHandlerDecorator
where
In: RequestHandler;
fn create_decorator<In>(&self) -> Self::Output<In>
where
In: RequestHandler,
{
IdentityHandlerDecorator
}
}
#[derive(Debug)]
pub struct HandlerDecoratorFactoryComposer<F1, F2> {
factory_1: F1,
factory_2: F2,
}
impl<F1, F2> HandlerDecoratorFactory for HandlerDecoratorFactoryComposer<F1, F2>
where
F1: HandlerDecoratorFactory,
F2: HandlerDecoratorFactory,
{
type Output<In>
= HandlerDecoratorComposer<F1::Output<In>, F2::Output<<F1::Output<In> as HandlerDecorator<In>>::Output>>
where
In: RequestHandler;
fn create_decorator<In>(&self) -> Self::Output<In>
where
In: RequestHandler,
{
let decorator_1 = self.factory_1.create_decorator();
let decorator_2 = self.factory_2.create_decorator();
HandlerDecoratorComposer::new(decorator_1, decorator_2)
}
}