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