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 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}