1pub use paste;
2pub use seq_macro;
3
4#[macro_export]
5macro_rules! define_context {
6 ($ctx: ident {
7 $($field: ident : $type: ty),* $(,)?
8 }) => {
9 pub struct $ctx {
10 $(pub $field: $type),*
11 }
12
13 $crate::paste::paste! {
14
15 pub trait [< From $ctx >]<'a> {
16 fn from_context(ctx: &'a $ctx) -> Self;
17 }
18
19
20 $(
21 impl<'a> [< From $ctx >]<'a> for &'a $type {
22 fn from_context(ctx: &'a $ctx) -> Self {
23 &ctx.$field
24 }
25 }
26
27 impl [< From $ctx >]<'_> for $type where for<'a> $type: Clone {
28 fn from_context(ctx: &$ctx) -> Self {
29 ctx.$field.clone()
30 }
31 }
32 )*
33
34 }
35 };
36}
37
38#[macro_export]
39macro_rules! context_as_params {
40 (impl $ctx: ident, $max: expr) => {
41 $crate::seq_macro::seq!(N in 1..=$max {
42 $crate::paste::paste! {
43 impl<'a, F, #(T~N,)* O> [< $ctx Handler >]<'a, (#(T~N,)*), O> for F
44 where
45 F: Fn(#(T~N,)*) -> O,
46 #(T~N: [< From $ctx >]<'a>,)*
47 {
48 fn call(self, ctx: &'a $ctx) -> O {
49 (self)(#(T~N::from_context(&ctx),)*)
50 }
51 }
52 }
53 });
54
55 };
56
57 ($ctx: ident, $max: expr) => {
58 $crate::paste::paste! {
59 pub trait [< $ctx Handler >]<'a, T, O> {
60 fn call(self, ctx: &'a $ctx) -> O;
61 }
62 }
63 $crate::seq_macro::seq!(N in 1..=$max {
64 $crate::context_as_params!(impl $ctx, N);
65 });
66 };
67
68 ($ctx: ident) => {
69 $crate::context_as_params!($ctx, 6);
70 };
71}