1use std::any::TypeId;
4
5pub trait List {
11 type Empty: EmptyList;
13 fn empty() -> Self::Empty;
15
16 type Head: 'static;
18 fn head(&self) -> &Self::Head;
20
21 type Tail: List;
23 fn tail(&self) -> &Self::Tail;
25
26 fn is_empty(&self) -> bool {
28 self.len() == 0
29 }
30
31 const LENGTH: usize = Self::Tail::LENGTH + 1;
33 fn len(&self) -> usize {
35 Self::LENGTH
36 }
37
38 type Push<U: 'static>: List;
40 fn push<U: 'static>(self, item: U) -> Self::Push<U>;
42
43 type Append<U: List>: List;
47
48 fn append<U: List>(self, other: U) -> Self::Append<U>;
61
62 type ReverseOnto<U: List>: List;
64 fn reverse_onto<U: List>(self, other: U) -> Self::ReverseOnto<U>;
66
67 fn reverse(self) -> Self::ReverseOnto<Self::Empty>
69 where
70 Self: Sized,
71 {
72 self.reverse_onto(Self::empty())
73 }
74}
75
76pub type ReverseList<T> = <T as List>::ReverseOnto<<T as List>::Empty>;
78
79pub trait ListTypeProperty {
82 type Output;
84 fn property<R: List>() -> Self::Output;
86}
87
88impl ListTypeProperty for TypeId {
89 type Output = Self;
90 fn property<R: List>() -> Self::Output {
91 TypeId::of::<R::Head>()
92 }
93}
94
95pub struct ListTypeIterator<T: List, P: ListTypeProperty> {
97 pub(crate) advance: fn(&mut Self) -> Option<P::Output>,
98}
99
100pub trait ListTypeIteratorAdvance<P: ListTypeProperty>: List + Sized {
102 fn advancer<R: List>(iter: &mut ListTypeIterator<R, P>) -> Option<P::Output>;
104}
105
106impl<T: ListTypeIteratorAdvance<P> + 'static, P: ListTypeProperty> ListTypeIterator<T, P> {
107 #[must_use]
109 pub fn new() -> Self {
110 ListTypeIterator {
111 advance: T::advancer::<T>,
112 }
113 }
114}
115
116impl<T: ListTypeIteratorAdvance<P> + 'static, P: ListTypeProperty> Default
117 for ListTypeIterator<T, P>
118{
119 fn default() -> Self {
120 Self::new()
121 }
122}
123
124impl<T: ListTypeIteratorAdvance<P> + 'static, P: ListTypeProperty> Iterator
125 for ListTypeIterator<T, P>
126{
127 type Item = P::Output;
128 fn next(&mut self) -> Option<Self::Item> {
129 (self.advance)(self)
130 }
131}
132
133pub type TypeIdIterator<T> = ListTypeIterator<T, TypeId>;
135
136pub struct Undefined;
138
139pub trait EmptyList {
141 type PushFirst<U: 'static>: List;
143 fn push_first<U: 'static>(self, item: U) -> Self::PushFirst<U>;
145
146 type RootEmpty: EmptyList;
148 fn root_empty() -> Self::RootEmpty;
150}
151
152impl<T: EmptyList> List for T {
154 type Empty = T::RootEmpty;
155 fn empty() -> Self::Empty {
156 T::root_empty()
157 }
158
159 type Head = Undefined;
160 fn head(&self) -> &Self::Head {
161 unreachable!("EmptyList has no head")
162 }
163
164 type Tail = T; fn tail(&self) -> &Self::Tail {
166 unreachable!("EmptyList has no tail")
167 }
168
169 type Push<U: 'static> = T::PushFirst<U>;
170 fn push<U>(self, item: U) -> Self::Push<U> {
171 self.push_first(item)
172 }
173
174 const LENGTH: usize = 0;
175
176 type Append<U: List> = U;
177 fn append<U: List>(self, other: U) -> Self::Append<U> {
178 other
179 }
180
181 type ReverseOnto<U: List> = U;
182 fn reverse_onto<U: List>(self, other: U) -> Self::ReverseOnto<U> {
183 other
184 }
185}
186
187pub trait ListIndex<Idx: ?Sized> {
189 type Output;
191 fn index(&self, index: Idx) -> &Self::Output;
193}
194
195pub type Item<L, N> = <L as ListIndex<N>>::Output;
198
199pub trait ToList {
201 type ToList<T: EmptyList>: List;
203 fn to_list<T: EmptyList>(&self) -> Self::ToList<T>;
205}
206
207pub trait IntoList {
209 type Output<T: EmptyList>: List;
211 fn into_list<T: EmptyList>(self) -> Self::Output<T>;
213}
214
215impl IntoList for () {
216 type Output<T: EmptyList> = <T as List>::Empty;
217 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
218 T::empty()
219 }
220}
221
222impl<A: 'static> IntoList for (A,) {
223 type Output<T: EmptyList> = <<T as List>::Empty as List>::Push<A>;
224 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
225 ().into_list::<T>().push(self.0)
226 }
227}
228
229impl<A: 'static, B: 'static> IntoList for (A, B) {
230 type Output<T: EmptyList> = <<(B,) as IntoList>::Output<T> as List>::Push<A>;
231 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
232 (self.1,).into_list::<T>().push(self.0)
233 }
234}
235
236impl<A: 'static, B: 'static, C: 'static> IntoList for (A, B, C) {
237 type Output<T: EmptyList> = <<(B, C) as IntoList>::Output<T> as List>::Push<A>;
238 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
239 (self.1, self.2).into_list::<T>().push(self.0)
240 }
241}
242impl<A: 'static, B: 'static, C: 'static, D: 'static> IntoList for (A, B, C, D) {
243 type Output<T: EmptyList> = <<(B, C, D) as IntoList>::Output<T> as List>::Push<A>;
244 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
245 (self.1, self.2, self.3).into_list::<T>().push(self.0)
246 }
247}
248
249impl<A: 'static, B: 'static, C: 'static, D: 'static, E: 'static> IntoList for (A, B, C, D, E) {
250 type Output<T: EmptyList> = <<(B, C, D, E) as IntoList>::Output<T> as List>::Push<A>;
251 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
252 (self.1, self.2, self.3, self.4)
253 .into_list::<T>()
254 .push(self.0)
255 }
256}
257
258impl<A: 'static, B: 'static, C: 'static, D: 'static, E: 'static, F: 'static> IntoList
259 for (A, B, C, D, E, F)
260{
261 type Output<T: EmptyList> = <<(B, C, D, E, F) as IntoList>::Output<T> as List>::Push<A>;
262 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
263 (self.1, self.2, self.3, self.4, self.5)
264 .into_list::<T>()
265 .push(self.0)
266 }
267}
268
269impl<A: 'static, B: 'static, C: 'static, D: 'static, E: 'static, F: 'static, G: 'static> IntoList
270 for (A, B, C, D, E, F, G)
271{
272 type Output<T: EmptyList> = <<(B, C, D, E, F, G) as IntoList>::Output<T> as List>::Push<A>;
273 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
274 (self.1, self.2, self.3, self.4, self.5, self.6)
275 .into_list::<T>()
276 .push(self.0)
277 }
278}
279
280impl<A: 'static, B: 'static, C: 'static, D: 'static, E: 'static, F: 'static, G: 'static, H: 'static>
281 IntoList for (A, B, C, D, E, F, G, H)
282{
283 type Output<T: EmptyList> = <<(B, C, D, E, F, G, H) as IntoList>::Output<T> as List>::Push<A>;
284 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
285 (self.1, self.2, self.3, self.4, self.5, self.6, self.7)
286 .into_list::<T>()
287 .push(self.0)
288 }
289}
290
291impl<
292 A: 'static,
293 B: 'static,
294 C: 'static,
295 D: 'static,
296 E: 'static,
297 F: 'static,
298 G: 'static,
299 H: 'static,
300 I: 'static,
301> IntoList for (A, B, C, D, E, F, G, H, I)
302{
303 type Output<T: EmptyList> =
304 <<(B, C, D, E, F, G, H, I) as IntoList>::Output<T> as List>::Push<A>;
305 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
306 (
307 self.1, self.2, self.3, self.4, self.5, self.6, self.7, self.8,
308 )
309 .into_list::<T>()
310 .push(self.0)
311 }
312}
313
314impl<
315 A: 'static,
316 B: 'static,
317 C: 'static,
318 D: 'static,
319 E: 'static,
320 F: 'static,
321 G: 'static,
322 H: 'static,
323 I: 'static,
324 J: 'static,
325> IntoList for (A, B, C, D, E, F, G, H, I, J)
326{
327 type Output<T: EmptyList> =
328 <<(B, C, D, E, F, G, H, I, J) as IntoList>::Output<T> as List>::Push<A>;
329 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
330 (
331 self.1, self.2, self.3, self.4, self.5, self.6, self.7, self.8, self.9,
332 )
333 .into_list::<T>()
334 .push(self.0)
335 }
336}
337
338impl<
339 A: 'static,
340 B: 'static,
341 C: 'static,
342 D: 'static,
343 E: 'static,
344 F: 'static,
345 G: 'static,
346 H: 'static,
347 I: 'static,
348 J: 'static,
349 K: 'static,
350> IntoList for (A, B, C, D, E, F, G, H, I, J, K)
351{
352 type Output<T: EmptyList> =
353 <<(B, C, D, E, F, G, H, I, J, K) as IntoList>::Output<T> as List>::Push<A>;
354 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
355 (
356 self.1, self.2, self.3, self.4, self.5, self.6, self.7, self.8, self.9, self.10,
357 )
358 .into_list::<T>()
359 .push(self.0)
360 }
361}
362
363impl<
364 A: 'static,
365 B: 'static,
366 C: 'static,
367 D: 'static,
368 E: 'static,
369 F: 'static,
370 G: 'static,
371 H: 'static,
372 I: 'static,
373 J: 'static,
374 K: 'static,
375 L: 'static,
376> IntoList for (A, B, C, D, E, F, G, H, I, J, K, L)
377{
378 type Output<T: EmptyList> =
379 <<(B, C, D, E, F, G, H, I, J, K, L) as IntoList>::Output<T> as List>::Push<A>;
380 fn into_list<T: EmptyList>(self) -> Self::Output<T> {
381 (
382 self.1, self.2, self.3, self.4, self.5, self.6, self.7, self.8, self.9, self.10,
383 self.11,
384 )
385 .into_list::<T>()
386 .push(self.0)
387 }
388}