1use typenum::{B1, Bit, Sub1, U0, UInt, Unsigned};
5
6use crate::list_traits::{
7 EmptyList, IntoList, List, ListIndex, ListTypeIterator, ListTypeIteratorAdvance,
8 ListTypeProperty,
9};
10use std::ops::{RangeFrom, Sub};
11
12pub trait IntoTupleList {
14 type Output: List;
16 fn into_tuple_list(self) -> Self::Output;
18}
19
20impl<T: IntoList> IntoTupleList for T {
21 type Output = T::Output<()>;
22 fn into_tuple_list(self) -> Self::Output {
23 self.into_list()
24 }
25}
26
27impl<P: ListTypeProperty> ListTypeIteratorAdvance<P> for () {
31 fn advancer<R: List>(_iter: &mut ListTypeIterator<R, P>) -> Option<P::Output> {
32 None
33 }
34}
35
36impl<P: ListTypeProperty, H: 'static, T: ListTypeIteratorAdvance<P>> ListTypeIteratorAdvance<P>
37 for (H, T)
38{
39 fn advancer<R: List>(iter: &mut ListTypeIterator<R, P>) -> Option<P::Output> {
40 iter.advance = T::advancer::<R>;
41 Some(P::property::<(H, T)>())
42 }
43}
44
45impl EmptyList for () {
49 type PushFirst<U: 'static> = (U, ());
50 fn push_first<U: 'static>(self, item: U) -> Self::PushFirst<U> {
51 (item, ())
52 }
53
54 type RootEmpty = Self;
55 fn root_empty() -> Self::RootEmpty {}
56}
57
58impl<H: 'static, T: List> List for (H, T) {
62 type Empty = ();
63 fn empty() -> Self::Empty {}
64
65 type Head = H;
66 fn head(&self) -> &Self::Head {
67 &self.0
68 }
69
70 type Tail = T;
71 fn tail(&self) -> &Self::Tail {
72 &self.1
73 }
74
75 type Push<U: 'static> = (U, Self);
76 fn push<U: 'static>(self, item: U) -> Self::Push<U> {
77 (item, self)
78 }
79
80 type Append<U: List> = <T::Append<U> as List>::Push<H>;
81 fn append<U: List>(self, other: U) -> Self::Append<U> {
82 self.1.append(other).push(self.0)
83 }
84
85 type ReverseOnto<U: List> = T::ReverseOnto<U::Push<H>>;
86 fn reverse_onto<U: List>(self, other: U) -> Self::ReverseOnto<U> {
87 self.1.reverse_onto(other.push(self.0))
88 }
89}
90
91impl ListIndex<RangeFrom<U0>> for () {
92 type Output = ();
93 fn index(&self, _index: RangeFrom<U0>) -> &Self::Output {
94 self
95 }
96}
97
98impl<H: 'static, T: List> ListIndex<RangeFrom<U0>> for (H, T) {
99 type Output = (H, T);
100 fn index(&self, _index: RangeFrom<U0>) -> &Self::Output {
101 self
102 }
103}
104
105impl<H: 'static, T: List, U: Unsigned, B: Bit> ListIndex<RangeFrom<UInt<U, B>>> for (H, T)
106where
107 T: ListIndex<RangeFrom<Sub1<UInt<U, B>>>>,
108 UInt<U, B>: Sub<B1>,
109{
110 type Output = <T as ListIndex<RangeFrom<Sub1<UInt<U, B>>>>>::Output;
111 fn index(&self, index: RangeFrom<UInt<U, B>>) -> &Self::Output {
112 self.tail().index((index.start - B1)..)
113 }
114}
115
116impl<H: 'static, T: List> ListIndex<U0> for (H, T) {
117 type Output = H;
118 fn index(&self, _index: U0) -> &Self::Output {
119 self.head()
120 }
121}
122
123impl<H: 'static, T: List, U: Unsigned, B: Bit> ListIndex<UInt<U, B>> for (H, T)
124where
125 T: ListIndex<Sub1<UInt<U, B>>>,
126 UInt<U, B>: Sub<B1>,
127{
128 type Output = <T as ListIndex<Sub1<UInt<U, B>>>>::Output;
129 fn index(&self, index: UInt<U, B>) -> &Self::Output {
130 self.tail().index(index - B1)
131 }
132}
133
134#[cfg(test)]
137mod tests {
138 use super::*;
139 use crate::list_traits::TypeIdIterator;
140 use std::any::TypeId;
141 use typenum::{U0, U1, U2, U3};
142
143 #[test]
144 fn type_id_iterator() {
145 let ids: [TypeId; 3] = [
146 TypeId::of::<u32>(),
147 TypeId::of::<f64>(),
148 TypeId::of::<&str>(),
149 ];
150 assert!(TypeIdIterator::<(u32, (f64, (&str, ())))>::new().eq(ids.iter().copied()));
151 }
152
153 #[test]
154 fn empty_list() {
155 let () = <()>::empty();
156 }
157
158 #[test]
159 fn into_list() {
160 let () = ().into_tuple_list();
161 assert_eq!((1, 2, 3).into_tuple_list(), (1, (2, (3, ()))));
162 assert_eq!(
163 (1, 2.5, "Hello").into_tuple_list(),
164 (1, (2.5, ("Hello", ())))
165 );
166 }
167
168 #[test]
169 fn push() {
170 assert_eq!(().push_first(1), (1, ()));
171 assert_eq!((1, 2, 3).into_tuple_list().push(4), (4, (1, (2, (3, ())))));
172 }
173
174 #[test]
175 fn append() {
176 assert_eq!(
177 (1, 2, 3)
178 .into_tuple_list()
179 .append((4, 5, 6).into_tuple_list()),
180 (1, (2, (3, (4, (5, (6, ()))))))
181 );
182 }
183
184 #[test]
185 fn reverse() {
186 assert_eq!((1, 2, 3).into_tuple_list().reverse(), (3, (2, (1, ()))));
187 }
188
189 #[test]
190 fn list_length() {
191 assert_eq!(<()>::LENGTH, 0);
192 assert_eq!(<(i32, ())>::LENGTH, 1);
193 assert_eq!(<(i32, (f64, ()))>::LENGTH, 2);
194 }
195
196 #[test]
197 fn tuple_list() {
198 let list = (1, 2.5, "Hello").into_tuple_list();
199 println!("{:?}", list);
200 }
201
202 #[test]
203 fn list_index() {
204 let list = (1, 2.5, "Hello").into_tuple_list();
205 assert_eq!(*list.index(U0::new()), 1);
206 assert_eq!(*list.index(U1::new()), 2.5);
207 assert_eq!(*list.index(U2::new()), "Hello");
208 }
209
210 #[test]
211 fn list_range_from_index() {
212 let list = (1, 2.5, "Hello").into_tuple_list();
213 assert_eq!(*list.index(U0::new()..), (1, (2.5, ("Hello", ()))));
214 assert_eq!(*list.index(U1::new()..), (2.5, ("Hello", ())));
215 assert_eq!(*list.index(U2::new()..), ("Hello", ()));
216 let () = *list.index(U3::new()..);
217 }
219}