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