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, }