1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::future::Future;

use viz_utils::futures::future::BoxFuture;

use crate::{Context, Error, Extract, HandlerBase, HandlerCamp, Response, Result};

macro_rules! peel {
    ($T0:ident, $($T:ident,)*) => (tuple! { $($T,)* })
}

macro_rules! tuple {
    () => (
        #[doc(hidden)]
        impl Extract for () {
            type Error = Error;

            #[inline]
            fn extract<'a>(_: &'a mut Context) -> BoxFuture<'a, Result<Self, Self::Error>> {
                Box::pin(async { Ok(()) })
            }
        }

        #[doc(hidden)]
        impl<F, R> HandlerBase<()> for F
        where
            F: Fn() -> R + Clone + 'static,
            R: Future + Send + 'static,
            R::Output: Into<Response>,
        {
            type Output = R::Output;
            type Future = R;

            #[inline]
            fn call(&self, _: ()) -> R {
                (self)()
            }
        }

        #[doc(hidden)]
        impl<'h, F, R> HandlerCamp<'h, ()> for F
        where
            F: Fn(&'h mut Context) -> R + Clone + 'static,
            R: Future + Send + 'h,
            R::Output: Into<Response>,
        {
            type Output = R::Output;
            type Future = R;

            #[inline]
            fn call(&'h self, cx: &'h mut Context, _: ()) -> R {
                (self)(cx)
            }
        }
    );
    ($($T:ident,)+) => (
        impl<$($T),+> Extract for ($($T,)+)
        where
            $($T: Extract + Send,)+
            $($T::Error: Into<Response> + Send + 'static,)+
        {
            type Error = Response;

            #[inline]
            fn extract<'a>(cx: &'a mut Context) -> BoxFuture<'a, Result<Self, Self::Error>> {
                Box::pin(async move {
                    Ok((
                        $(
                            match $T::extract(cx).await {
                                Ok(v) => v,
                                Err(e) => return Err(Into::<Response>::into(e as $T::Error)),
                            },
                        )+
                    ))
                })
            }
        }

        impl<Func, $($T,)+ R> HandlerBase<($($T,)+)> for Func
        where
            Func: Fn($($T,)+) -> R + Clone + 'static,
            R: Future + Send + 'static,
            R::Output: Into<Response>,
        {
            type Output = R::Output;
            type Future = R;

            #[inline]
            fn call(&self, args: ($($T,)+)) -> R {
                #[allow(non_snake_case)]
                let ($($T,)+) = args;
                (self)($($T,)+)
            }
        }

        impl<'h, Func, $($T,)+ R> HandlerCamp<'h, ($($T,)+)> for Func
        where
            Func: Fn(&'h mut Context, $($T,)+) -> R + Clone + 'static,
            R: Future + Send + 'h,
            R::Output: Into<Response>,
        {
            type Output = R::Output;
            type Future = R;

            #[inline]
            fn call(&'h self, cx: &'h mut Context, args: ($($T,)+)) -> R {
                #[allow(non_snake_case)]
                let ($($T,)+) = args;
                (self)(cx, $($T,)+)
            }
        }

        peel! { $($T,)+ }
    )
}

tuple! { A, B, C, D, E, F, G, H, I, J, K, L, }