1 #[derive(Debug)]
2 pub struct Product<H, T: HList>(pub(crate) H, pub(crate) T);
3 
4 pub type One<T> = (T,);
5 
6 #[inline]
one<T>(val: T) -> One<T>7 pub(crate) fn one<T>(val: T) -> One<T> {
8     (val,)
9 }
10 
11 #[derive(Debug)]
12 pub enum Either<T, U> {
13     A(T),
14     B(U),
15 }
16 
17 // Converts Product (and ()) into tuples.
18 pub trait HList: Sized {
19     type Tuple: Tuple<HList = Self>;
20 
flatten(self) -> Self::Tuple21     fn flatten(self) -> Self::Tuple;
22 }
23 
24 // Typeclass that tuples can be converted into a Product (or unit ()).
25 pub trait Tuple: Sized {
26     type HList: HList<Tuple = Self>;
27 
hlist(self) -> Self::HList28     fn hlist(self) -> Self::HList;
29 }
30 
31 // Combines Product together.
32 pub trait Combine<T: HList> {
33     type Output: HList;
34 
combine(self, other: T) -> Self::Output35     fn combine(self, other: T) -> Self::Output;
36 }
37 
38 pub trait Func<Args> {
39     type Output;
40 
call(&self, args: Args) -> Self::Output41     fn call(&self, args: Args) -> Self::Output;
42 }
43 
44 // ===== impl Combine =====
45 
46 impl<T: HList> Combine<T> for () {
47     type Output = T;
48     #[inline]
combine(self, other: T) -> Self::Output49     fn combine(self, other: T) -> Self::Output {
50         other
51     }
52 }
53 
54 impl<H, T: HList, U: HList> Combine<U> for Product<H, T>
55 where
56     T: Combine<U>,
57     Product<H, <T as Combine<U>>::Output>: HList,
58 {
59     type Output = Product<H, <T as Combine<U>>::Output>;
60 
61     #[inline]
combine(self, other: U) -> Self::Output62     fn combine(self, other: U) -> Self::Output {
63         Product(self.0, self.1.combine(other))
64     }
65 }
66 
67 impl HList for () {
68     type Tuple = ();
69     #[inline]
flatten(self) -> Self::Tuple70     fn flatten(self) -> Self::Tuple {}
71 }
72 
73 impl Tuple for () {
74     type HList = ();
75 
76     #[inline]
hlist(self) -> Self::HList77     fn hlist(self) -> Self::HList {}
78 }
79 
80 impl<F, R> Func<()> for F
81 where
82     F: Fn() -> R,
83 {
84     type Output = R;
85 
86     #[inline]
call(&self, _args: ()) -> Self::Output87     fn call(&self, _args: ()) -> Self::Output {
88         (*self)()
89     }
90 }
91 
92 impl<F, R> Func<crate::Rejection> for F
93 where
94     F: Fn(crate::Rejection) -> R,
95 {
96     type Output = R;
97 
98     #[inline]
call(&self, arg: crate::Rejection) -> Self::Output99     fn call(&self, arg: crate::Rejection) -> Self::Output {
100         (*self)(arg)
101     }
102 }
103 
104 macro_rules! product {
105     ($H:expr) => { Product($H, ()) };
106     ($H:expr, $($T:expr),*) => { Product($H, product!($($T),*)) };
107 }
108 
109 macro_rules! Product {
110     ($H:ty) => { Product<$H, ()> };
111     ($H:ty, $($T:ty),*) => { Product<$H, Product!($($T),*)> };
112 }
113 
114 macro_rules! product_pat {
115     ($H:pat) => { Product($H, ()) };
116     ($H:pat, $($T:pat),*) => { Product($H, product_pat!($($T),*)) };
117 }
118 
119 macro_rules! generics {
120     ($type:ident) => {
121         impl<$type> HList for Product!($type) {
122             type Tuple = ($type,);
123 
124             #[inline]
125             fn flatten(self) -> Self::Tuple {
126                 (self.0,)
127             }
128         }
129 
130         impl<$type> Tuple for ($type,) {
131             type HList = Product!($type);
132             #[inline]
133             fn hlist(self) -> Self::HList {
134                 product!(self.0)
135             }
136         }
137 
138         impl<F, R, $type> Func<Product!($type)> for F
139         where
140             F: Fn($type) -> R,
141         {
142             type Output = R;
143 
144             #[inline]
145             fn call(&self, args: Product!($type)) -> Self::Output {
146                 (*self)(args.0)
147             }
148 
149         }
150 
151         impl<F, R, $type> Func<($type,)> for F
152         where
153             F: Fn($type) -> R,
154         {
155             type Output = R;
156 
157             #[inline]
158             fn call(&self, args: ($type,)) -> Self::Output {
159                 (*self)(args.0)
160             }
161         }
162 
163     };
164 
165     ($type1:ident, $( $type:ident ),*) => {
166         generics!($( $type ),*);
167 
168         impl<$type1, $( $type ),*> HList for Product!($type1, $($type),*) {
169             type Tuple = ($type1, $( $type ),*);
170 
171             #[inline]
172             fn flatten(self) -> Self::Tuple {
173                 #[allow(non_snake_case)]
174                 let product_pat!($type1, $( $type ),*) = self;
175                 ($type1, $( $type ),*)
176             }
177         }
178 
179         impl<$type1, $( $type ),*> Tuple for ($type1, $($type),*) {
180             type HList = Product!($type1, $( $type ),*);
181 
182             #[inline]
183             fn hlist(self) -> Self::HList {
184                 #[allow(non_snake_case)]
185                 let ($type1, $( $type ),*) = self;
186                 product!($type1, $( $type ),*)
187             }
188         }
189 
190         impl<F, R, $type1, $( $type ),*> Func<Product!($type1, $($type),*)> for F
191         where
192             F: Fn($type1, $( $type ),*) -> R,
193         {
194             type Output = R;
195 
196             #[inline]
197             fn call(&self, args: Product!($type1, $($type),*)) -> Self::Output {
198                 #[allow(non_snake_case)]
199                 let product_pat!($type1, $( $type ),*) = args;
200                 (*self)($type1, $( $type ),*)
201             }
202         }
203 
204         impl<F, R, $type1, $( $type ),*> Func<($type1, $($type),*)> for F
205         where
206             F: Fn($type1, $( $type ),*) -> R,
207         {
208             type Output = R;
209 
210             #[inline]
211             fn call(&self, args: ($type1, $($type),*)) -> Self::Output {
212                 #[allow(non_snake_case)]
213                 let ($type1, $( $type ),*) = args;
214                 (*self)($type1, $( $type ),*)
215             }
216         }
217     };
218 }
219 
220 generics! {
221     T1,
222     T2,
223     T3,
224     T4,
225     T5,
226     T6,
227     T7,
228     T8,
229     T9,
230     T10,
231     T11,
232     T12,
233     T13,
234     T14,
235     T15,
236     T16
237 }
238