micro-web 0.3.0

the async micro web framework
Documentation
use crate::handler::RequestHandler;

pub trait HandlerDecorator<In: RequestHandler> {
    type Output: RequestHandler;

    fn decorate(&self, handler: In) -> Self::Output;
}

#[allow(unused)]
pub trait HandlerDecoratorExt<In: RequestHandler>: HandlerDecorator<In> {
    fn and_then<D>(self, decorator: D) -> HandlerDecoratorComposer<Self, D>
    where
        Self: Sized,
    {
        HandlerDecoratorComposer::new(self, decorator)
    }

    fn compose<D>(self, decorator: D) -> HandlerDecoratorComposer<D, Self>
    where
        Self: Sized,
    {
        HandlerDecoratorComposer::new(decorator, self)
    }
}

impl<T: HandlerDecorator<In> + ?Sized, In: RequestHandler> HandlerDecoratorExt<In> for T {}

#[derive(Default, Copy, Clone, Debug)]
pub struct IdentityHandlerDecorator;

impl<In: RequestHandler> HandlerDecorator<In> for IdentityHandlerDecorator {
    type Output = In;

    fn decorate(&self, handler: In) -> Self::Output {
        handler
    }
}

#[derive(Debug)]
pub struct HandlerDecoratorComposer<D1, D2> {
    decorator_1: D1,
    decorator_2: D2,
}

impl<D1, D2> HandlerDecoratorComposer<D1, D2> {
    pub fn new(decorator_1: D1, decorator_2: D2) -> Self {
        HandlerDecoratorComposer { decorator_1, decorator_2 }
    }
}

impl<In, D1, D2> HandlerDecorator<In> for HandlerDecoratorComposer<D1, D2>
where
    In: RequestHandler,
    D1: HandlerDecorator<In>,
    D2: HandlerDecorator<D1::Output>,
{
    type Output = D2::Output;
    fn decorate(&self, handler: In) -> Self::Output {
        let output_1 = self.decorator_1.decorate(handler);
        self.decorator_2.decorate(output_1)
    }
}