1use std::{error::Error, future::Future, pin::Pin};
2
3use crate::{caller::Caller, extract::Extract};
4
5macro_rules! tuple {
6 ($($param:ident)*) => {
7 impl<Func, Fut, Pro, Err, $($param,)*> Caller<($($param,)*), Pro, Err> for Func
8 where
9 Func: Fn($($param),*) -> Fut + Clone + 'static,
10 Fut: Future,
11 Pro: $(Extract<$param, Err> +)*,
12 Err: Error,
13 {
14 type Output = Fut::Output;
15 type Future = Fut;
16
17 #[inline]
18 #[allow(non_snake_case)]
19 fn call(&self, ($($param,)*): ($($param,)*)) -> Self::Future {
20 (self)($($param),*)
21 }
22 }
23
24 impl<Pro, Err, $($param,)*> Extract<($($param,)*), Err> for Pro
25 where
26 Pro: $(Extract<$param, Err> +)*,
27 Err: Error,
28 {
29 #[inline]
30 #[allow(non_snake_case)]
31 fn extract<'a>(&'a self) -> Pin<Box<dyn Future<Output = Result<($($param,)*), Err>> + 'a>> {
32 let fut = async move {
33 $(
34 let $param = <Pro as Extract<$param, Err>>::extract(self).await?;
35 )*
36 Ok(($($param,)*))
37 };
38 Box::pin(fut)
39 }
40 }
41 };
42}
43
44tuple! { A }
46tuple! { A B }
47tuple! { A B C }
48tuple! { A B C D }
49tuple! { A B C D E }
50tuple! { A B C D E F }
51tuple! { A B C D E F G }
52tuple! { A B C D E F G H }
53tuple! { A B C D E F G H I }
54tuple! { A B C D E F G H I J }
55tuple! { A B C D E F G H I J K }
56tuple! { A B C D E F G H I J K L }
57tuple! { A B C D E F G H I J K L M }
58tuple! { A B C D E F G H I J K L M N }
59tuple! { A B C D E F G H I J K L M N O }
60tuple! { A B C D E F G H I J K L M N O P }
61tuple! { A B C D E F G H I J K L M N O P Q }
62tuple! { A B C D E F G H I J K L M N O P Q R }
63tuple! { A B C D E F G H I J K L M N O P Q R S }
64tuple! { A B C D E F G H I J K L M N O P Q R S T }
65tuple! { A B C D E F G H I J K L M N O P Q R S T U }
66tuple! { A B C D E F G H I J K L M N O P Q R S T U V }
67tuple! { A B C D E F G H I J K L M N O P Q R S T U V W }
68tuple! { A B C D E F G H I J K L M N O P Q R S T U V W X }
69tuple! { 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 }
70tuple! { 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 }