foxhole 0.4.0

A Blazingly-fast http framework
Documentation
use crate::{
    action::Action,
    action::RawResponse,
    resolve::{Resolve, ResolveGuard},
    tasks::{PathIter, RequestState},
};

#[doc(hidden)]
pub trait System<'a, T> {
    fn run(self, ctx: &'a RequestState, path_iter: &mut PathIter) -> Option<RawResponse>;
}

#[doc(hidden)]
pub struct DynSystem {
    inner: Box<dyn Fn(&RequestState, &mut PathIter) -> Option<RawResponse> + 'static + Send + Sync>,
}

impl DynSystem {
    pub fn new<A>(system: impl for<'a> System<'a, A> + 'static + Send + Sync + Copy) -> Self {
        DynSystem {
            inner: Box::new(move |ctx, path_iter| system.run(ctx, path_iter)),
        }
    }

    pub fn call(&self, ctx: &RequestState, path_iter: &mut PathIter) -> Option<RawResponse> {
        (self.inner)(ctx, path_iter)
    }
}

macro_rules! system {
    ($($x:ident),* $(,)?) => {
        impl<'a, RESPONSE, $($x,)* BASE> System<'a, (RESPONSE, $($x,)*)> for BASE
        where
            BASE: Fn($($x,)*) -> RESPONSE + Fn($($x::Output,)*) -> RESPONSE,
            $($x: Resolve<'a>,)*
            RESPONSE: Action,
        {
            #[allow(unused)]
            fn run(self, ctx: &'a RequestState, path_iter: &mut PathIter) -> Option<RawResponse> {


                $(
                #[allow(non_snake_case)]
                let $x = match $x::resolve(ctx, path_iter) {
                    ResolveGuard::Value(v) => v,
                    ResolveGuard::None => return None,
                    ResolveGuard::Respond(r) => return Some(r), };)*

                let r = self($($x,)*);

                r.action()
            }
        }
    }
}

macro_rules! all {
    () => {
        system! { }
    };

    ($first:ident, $($x:ident),*$(,)?)  => {
        system! { $first, $($x,)* }

        all! { $($x,)*}
    }
}

all! { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z }