duple/
lib.rs

1#![allow(clippy::type_complexity, clippy::many_single_char_names)]
2
3#[derive(Debug, Copy, Clone)]
4struct W<T>(T);
5
6pub trait TupleWrap {
7    type Wrapped;
8
9    fn wrap(self) -> Self::Wrapped;
10}
11
12pub trait TupleUnwrap {
13    type Unwrapped;
14
15    fn unwrap(self) -> Self::Unwrapped;
16}
17
18impl<A> TupleUnwrap for (A, ()) {
19    type Unwrapped = A;
20
21    fn unwrap(self) -> Self::Unwrapped {
22        let (a, ()) = self;
23
24        a
25    }
26}
27
28impl<A, B> TupleWrap for (A, B) {
29    type Wrapped = (A, (B, ()));
30
31    fn wrap(self) -> Self::Wrapped {
32        let (a, b) = self;
33
34        (a, (b, ()))
35    }
36}
37
38impl<A, B> TupleUnwrap for (A, (B, ())) {
39    type Unwrapped = (A, B);
40
41    fn unwrap(self) -> Self::Unwrapped {
42        let (a, (b, ())) = self;
43
44        (a, b)
45    }
46}
47
48impl<A, B, C> TupleWrap for (A, B, C) {
49    type Wrapped = (A, (B, (C, ())));
50
51    fn wrap(self) -> Self::Wrapped {
52        let (a, b, c) = self;
53
54        (a, (b, (c, ())))
55    }
56}
57
58impl<A, B, C> TupleUnwrap for (A, (B, (C, ()))) {
59    type Unwrapped = (A, B, C);
60
61    fn unwrap(self) -> Self::Unwrapped {
62        let (a, (b, (c, ()))) = self;
63
64        (a, b, c)
65    }
66}
67
68impl<A, B, C, D> TupleWrap for (A, B, C, D) {
69    type Wrapped = (A, (B, (C, (D, ()))));
70
71    fn wrap(self) -> Self::Wrapped {
72        let (a, b, c, d) = self;
73
74        (a, (b, (c, (d, ()))))
75    }
76}
77
78impl<A, B, C, D> TupleUnwrap for (A, (B, (C, (D, ())))) {
79    type Unwrapped = (A, B, C, D);
80
81    fn unwrap(self) -> Self::Unwrapped {
82        let (a, (b, (c, (d, ())))) = self;
83
84        (a, b, c, d)
85    }
86}
87
88impl<A, B, C, D, E> TupleWrap for (A, B, C, D, E) {
89    type Wrapped = (A, (B, (C, (D, (E, ())))));
90
91    fn wrap(self) -> Self::Wrapped {
92        let (a, b, c, d, e) = self;
93
94        (a, (b, (c, (d, (e, ())))))
95    }
96}
97
98impl<A, B, C, D, E> TupleUnwrap for (A, (B, (C, (D, (E, ()))))) {
99    type Unwrapped = (A, B, C, D, E);
100
101    fn unwrap(self) -> Self::Unwrapped {
102        let (a, (b, (c, (d, (e, ()))))) = self;
103
104        (a, b, c, d, e)
105    }
106}
107
108impl<A, B, C, D, E, F> TupleWrap for (A, B, C, D, E, F) {
109    type Wrapped = (A, (B, (C, (D, (E, (F, ()))))));
110
111    fn wrap(self) -> Self::Wrapped {
112        let (a, b, c, d, e, f) = self;
113
114        (a, (b, (c, (d, (e, (f, ()))))))
115    }
116}
117
118impl<A, B, C, D, E, F> TupleUnwrap for (A, (B, (C, (D, (E, (F, ())))))) {
119    type Unwrapped = (A, B, C, D, E, F);
120
121    fn unwrap(self) -> Self::Unwrapped {
122        let (a, (b, (c, (d, (e, (f, ())))))) = self;
123
124        (a, b, c, d, e, f)
125    }
126}
127
128impl<A, B, R> W<(A, (B, R))> {
129    fn rem0(self) -> (B, R) {
130        let (_a, rest) = self.0;
131
132        rest
133    }
134}
135
136impl<A, B, R> W<(A, (B, R))> {
137    fn rem1(self) -> (A, R) {
138        let (a, (_b, rest)) = self.0;
139
140        (a, rest)
141    }
142}
143
144impl<A, B, C, R> W<(A, (B, (C, R)))> {
145    fn rem2(self) -> (A, (B, R)) {
146        let (a, (b, (_c, rest))) = self.0;
147
148        (a, (b, rest))
149    }
150}
151
152impl<A, B, C, D, R> W<(A, (B, (C, (D, R))))> {
153    fn rem3(self) -> (A, (B, (C, R))) {
154        let (a, (b, (c, (_d, rest)))) = self.0;
155
156        (a, (b, (c, rest)))
157    }
158}
159
160impl<A, B, C, D, E, R> W<(A, (B, (C, (D, (E, R)))))> {
161    fn rem4(self) -> (A, (B, (C, (D, R)))) {
162        let (a, (b, (c, (d, (_e, rest))))) = self.0;
163
164        (a, (b, (c, (d, rest))))
165    }
166}
167
168impl<A, B, C, D, E, F, R> W<(A, (B, (C, (D, (E, (F, R))))))> {
169    fn rem5(self) -> (A, (B, (C, (D, (E, R))))) {
170        let (a, (b, (c, (d, (e, (_f, rest)))))) = self.0;
171
172        (a, (b, (c, (d, (e, rest)))))
173    }
174}
175
176pub mod prelude {
177	use super::*;
178
179    pub trait TupleRemove0: Sized {
180        type Removed;
181
182        fn rem0(self) -> Self::Removed;
183    }
184
185    impl<T, A, B, R> TupleRemove0 for T
186    where
187        T: TupleWrap<Wrapped = (A, (B, R))> + Sized,
188        (B, R): TupleUnwrap,
189    {
190        type Removed = <(B, R) as TupleUnwrap>::Unwrapped;
191
192        fn rem0(self) -> Self::Removed {
193            W(self.wrap()).rem0().unwrap()
194        }
195    }
196
197    pub trait TupleRemove1: Sized {
198        type Removed;
199
200        fn rem1(self) -> Self::Removed;
201    }
202
203    impl<T, A, B, R> TupleRemove1 for T
204    where
205        T: TupleWrap<Wrapped = (A, (B, R))> + Sized,
206        (A, R): TupleUnwrap,
207    {
208        type Removed = <(A, R) as TupleUnwrap>::Unwrapped;
209
210        fn rem1(self) -> Self::Removed {
211            W(self.wrap()).rem1().unwrap()
212        }
213    }
214
215    pub trait TupleRemove2: Sized {
216        type Removed;
217
218        fn rem2(self) -> Self::Removed;
219    }
220
221    impl<T, A, B, C, R> TupleRemove2 for T
222    where
223        T: TupleWrap<Wrapped = (A, (B, (C, R)))> + Sized,
224        (A, (B, R)): TupleUnwrap,
225    {
226        type Removed = <(A, (B, R)) as TupleUnwrap>::Unwrapped;
227
228        fn rem2(self) -> Self::Removed {
229            W(self.wrap()).rem2().unwrap()
230        }
231    }
232
233    pub trait TupleRemove3: Sized {
234        type Removed;
235
236        fn rem3(self) -> Self::Removed;
237    }
238
239    impl<T, A, B, C, D, R> TupleRemove3 for T
240    where
241        T: TupleWrap<Wrapped = (A, (B, (C, (D, R))))> + Sized,
242        (A, (B, (C, R))): TupleUnwrap,
243    {
244        type Removed = <(A, (B, (C, R))) as TupleUnwrap>::Unwrapped;
245
246        fn rem3(self) -> Self::Removed {
247            W(self.wrap()).rem3().unwrap()
248        }
249    }
250
251    pub trait TupleRemove4: Sized {
252        type Removed;
253
254        fn rem4(self) -> Self::Removed;
255    }
256
257    impl<T, A, B, C, D, E, R> TupleRemove4 for T
258    where
259        T: TupleWrap<Wrapped = (A, (B, (C, (D, (E, R)))))> + Sized,
260        (A, (B, (C, (D, R)))): TupleUnwrap,
261    {
262        type Removed = <(A, (B, (C, (D, R)))) as TupleUnwrap>::Unwrapped;
263
264        fn rem4(self) -> Self::Removed {
265            W(self.wrap()).rem4().unwrap()
266        }
267    }
268
269    pub trait TupleRemove5: Sized {
270        type Removed;
271
272        fn rem5(self) -> Self::Removed;
273    }
274
275    impl<T, A, B, C, D, E, F, R> TupleRemove5 for T
276    where
277        T: TupleWrap<Wrapped = (A, (B, (C, (D, (E, (F, R))))))> + Sized,
278        (A, (B, (C, (D, (E, R))))): TupleUnwrap,
279    {
280        type Removed = <(A, (B, (C, (D, (E, R))))) as TupleUnwrap>::Unwrapped;
281
282        fn rem5(self) -> Self::Removed {
283            W(self.wrap()).rem5().unwrap()
284        }
285    }
286}
287
288#[cfg(test)]
289mod test {
290    use super::prelude::*;
291
292    #[test]
293    fn test() {
294        // Special case — returns the last element, not a tuple!
295        assert_eq!(('a', 'b').rem0(), 'b');
296        assert_eq!(('a', 'b').rem1(), 'a');
297
298        assert_eq!(('a', 'b', 'c').rem0(), ('b', 'c'));
299        assert_eq!(('a', 'b', 'c').rem1(), ('a', 'c'));
300        assert_eq!(('a', 'b', 'c').rem2(), ('a', 'b'));
301
302        assert_eq!(('a', 'b', 'c', 'd').rem0(), ('b', 'c', 'd'));
303        assert_eq!(('a', 'b', 'c', 'd').rem1(), ('a', 'c', 'd'));
304        assert_eq!(('a', 'b', 'c', 'd').rem2(), ('a', 'b', 'd'));
305        assert_eq!(('a', 'b', 'c', 'd').rem3(), ('a', 'b', 'c'));
306
307        assert_eq!(('a', 'b', 'c', 'd', 'e').rem0(), ('b', 'c', 'd', 'e'));
308        assert_eq!(('a', 'b', 'c', 'd', 'e').rem1(), ('a', 'c', 'd', 'e'));
309        assert_eq!(('a', 'b', 'c', 'd', 'e').rem2(), ('a', 'b', 'd', 'e'));
310        assert_eq!(('a', 'b', 'c', 'd', 'e').rem3(), ('a', 'b', 'c', 'e'));
311        assert_eq!(('a', 'b', 'c', 'd', 'e').rem4(), ('a', 'b', 'c', 'd'));
312
313        assert_eq!(
314            ('a', 'b', 'c', 'd', 'e', 'f').rem0(),
315            ('b', 'c', 'd', 'e', 'f')
316        );
317        assert_eq!(
318            ('a', 'b', 'c', 'd', 'e', 'f').rem1(),
319            ('a', 'c', 'd', 'e', 'f')
320        );
321        assert_eq!(
322            ('a', 'b', 'c', 'd', 'e', 'f').rem2(),
323            ('a', 'b', 'd', 'e', 'f')
324        );
325        assert_eq!(
326            ('a', 'b', 'c', 'd', 'e', 'f').rem3(),
327            ('a', 'b', 'c', 'e', 'f')
328        );
329        assert_eq!(
330            ('a', 'b', 'c', 'd', 'e', 'f').rem4(),
331            ('a', 'b', 'c', 'd', 'f')
332        );
333        assert_eq!(
334            ('a', 'b', 'c', 'd', 'e', 'f').rem5(),
335            ('a', 'b', 'c', 'd', 'e')
336        );
337    }
338}