1use crate::{Context, FromContext};
2use std::future::Future;
3
4
5
6pub trait Handler<I, O, Args>: Send + Sync + 'static {
8 fn call(&self, ctx: Context<I>) -> impl Future<Output = O> + Send;
9}
10
11macro_rules! impl_handler_for_fn {
12 ($($P:ident),+ $(,)?) => {
13 impl<F, I, O, Fut, $($P),+> Handler<I, O, ($($P,)+)> for F
14 where
15 I: Clone + Send + Sync + 'static,
16 O: Send + 'static,
17 F: Fn($($P),+) -> Fut + Send + Sync + 'static,
18 Fut: Future<Output = O> + Send,
19 $(
20 $P: FromContext<I>
21 ),+
22 {
23 fn call(&self, ctx: Context<I>) -> impl Future<Output = O> + Send {
24 async move {
25 let args = {
26 let c = ctx;
27 (
28 $($P::from(c.clone()).await,)+
30 )
31 };
32 #[allow(non_snake_case)]
33 let ($($P,)+) = args;
34 self($($P),+).await
35 }
36 }
37 }
38 };
39}
40
41impl_handler_for_fn!(I1);
42impl_handler_for_fn!(I1, I2);
43impl_handler_for_fn!(I1, I2, I3);
44impl_handler_for_fn!(I1, I2, I3, I4);
45impl_handler_for_fn!(I1, I2, I3, I4, I5);
46impl_handler_for_fn!(I1, I2, I3, I4, I5, I6);
47impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7);
48impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8);
49impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9);
50impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9, I10);
51impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11);
52impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12);
53impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13);
54impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14);
55impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15);
56impl_handler_for_fn!(I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16);
57