1#![cfg_attr(feature = "no_std", no_std)]
2#![forbid(unsafe_code)]
3
4use core::{
7 cmp::Ordering,
8 fmt::Display,
9 future::Future,
10 iter::{Product, Sum},
11 pin::Pin,
12 task::{Context, Poll},
13};
14use paste::paste;
15use pin_project_lite::pin_project;
16#[cfg(not(feature = "no_std"))]
17use std::error::Error; macro_rules! tuples {
20 ($name:ident + $fut_name:ident + $fut_proj:ident {
21 $($ty:ident => ($($rest_variant:ident),*) + <$($mapped_ty:ident),+>),+$(,)?
22 }) => {
23 tuples!($name + $fut_name + $fut_proj {
24 $($ty($ty) => ($($rest_variant),*) + <$($mapped_ty),+>),+
25 });
26 };
27 ($name:ident + $fut_name:ident + $fut_proj:ident {
28 $($variant:ident($ty:ident) => ($($rest_variant:ident),*) + <$($mapped_ty:ident),+>),+$(,)?
29 }) => {
30 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
31 pub enum $name<$($ty),+> {
32 $($variant ($ty),)+
33 }
34
35 impl<$($ty),+> $name<$($ty),+> {
36 paste! {
37 #[allow(clippy::too_many_arguments)]
38 pub fn map<$([<F $ty>]),+, $([<$ty 1>]),+>(self, $([<$variant:lower>]: [<F $ty>]),+) -> $name<$([<$ty 1>]),+>
39 where
40 $([<F $ty>]: FnOnce($ty) -> [<$ty 1>],)+
41 {
42 match self {
43 $($name::$variant(inner) => $name::$variant([<$variant:lower>](inner)),)+
44 }
45 }
46
47 $(
48 pub fn [<map_ $variant:lower>]<Fun, [<$ty 1>]>(self, f: Fun) -> $name<$($mapped_ty),+>
49 where
50 Fun: FnOnce($ty) -> [<$ty 1>],
51 {
52 match self {
53 $name::$variant(inner) => $name::$variant(f(inner)),
54 $($name::$rest_variant(inner) => $name::$rest_variant(inner),)*
55 }
56 }
57
58 pub fn [<inspect_ $variant:lower>]<Fun, [<$ty 1>]>(self, f: Fun) -> Self
59 where
60 Fun: FnOnce(&$ty),
61 {
62 if let $name::$variant(inner) = &self {
63 f(inner);
64 }
65 self
66 }
67
68 pub fn [<is_ $variant:lower>](&self) -> bool {
69 matches!(self, $name::$variant(_))
70 }
71
72 pub fn [<as_ $variant:lower>](&self) -> Option<&$ty> {
73 match self {
74 $name::$variant(inner) => Some(inner),
75 _ => None,
76 }
77 }
78
79 pub fn [<as_ $variant:lower _mut>](&mut self) -> Option<&mut $ty> {
80 match self {
81 $name::$variant(inner) => Some(inner),
82 _ => None,
83 }
84 }
85
86 pub fn [<unwrap_ $variant:lower>](self) -> $ty {
87 match self {
88 $name::$variant(inner) => inner,
89 _ => panic!(concat!(
90 "called `unwrap_", stringify!([<$variant:lower>]), "()` on a non-`", stringify!($variant), "` variant of `", stringify!($name), "`"
91 )),
92 }
93 }
94
95 pub fn [<into_ $variant:lower>](self) -> Result<$ty, Self> {
96 match self {
97 $name::$variant(inner) => Ok(inner),
98 _ => Err(self),
99 }
100 }
101 )+
102 }
103 }
104
105 impl<$($ty),+> Display for $name<$($ty),+>
106 where
107 $($ty: Display,)+
108 {
109 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
110 match self {
111 $($name::$variant(this) => this.fmt(f),)+
112 }
113 }
114 }
115
116 #[cfg(not(feature = "no_std"))]
117 impl<$($ty),+> Error for $name<$($ty),+>
118 where
119 $($ty: Error,)+
120 {
121 fn source(&self) -> Option<&(dyn Error + 'static)> {
122 match self {
123 $($name::$variant(this) => this.source(),)+
124 }
125 }
126 }
127
128 impl<Item, $($ty),+> Iterator for $name<$($ty),+>
129 where
130 $($ty: Iterator<Item = Item>,)+
131 {
132 type Item = Item;
133
134 fn next(&mut self) -> Option<Self::Item> {
135 match self {
136 $($name::$variant(i) => i.next(),)+
137 }
138 }
139
140 fn size_hint(&self) -> (usize, Option<usize>) {
141 match self {
142 $($name::$variant(i) => i.size_hint(),)+
143 }
144 }
145
146 fn count(self) -> usize
147 where
148 Self: Sized,
149 {
150 match self {
151 $($name::$variant(i) => i.count(),)+
152 }
153 }
154
155 fn last(self) -> Option<Self::Item>
156 where
157 Self: Sized,
158 {
159 match self {
160 $($name::$variant(i) => i.last(),)+
161 }
162 }
163
164 fn nth(&mut self, n: usize) -> Option<Self::Item> {
165 match self {
166 $($name::$variant(i) => i.nth(n),)+
167 }
168 }
169
170 fn for_each<Fun>(self, f: Fun)
171 where
172 Self: Sized,
173 Fun: FnMut(Self::Item),
174 {
175 match self {
176 $($name::$variant(i) => i.for_each(f),)+
177 }
178 }
179
180 fn collect<Col: FromIterator<Self::Item>>(self) -> Col
181 where
182 Self: Sized,
183 {
184 match self {
185 $($name::$variant(i) => i.collect(),)+
186 }
187 }
188
189 fn partition<Col, Fun>(self, f: Fun) -> (Col, Col)
190 where
191 Self: Sized,
192 Col: Default + Extend<Self::Item>,
193 Fun: FnMut(&Self::Item) -> bool,
194 {
195 match self {
196 $($name::$variant(i) => i.partition(f),)+
197 }
198 }
199
200 fn fold<Acc, Fun>(self, init: Acc, f: Fun) -> Acc
201 where
202 Self: Sized,
203 Fun: FnMut(Acc, Self::Item) -> Acc,
204 {
205 match self {
206 $($name::$variant(i) => i.fold(init, f),)+
207 }
208 }
209
210 fn reduce<Fun>(self, f: Fun) -> Option<Self::Item>
211 where
212 Self: Sized,
213 Fun: FnMut(Self::Item, Self::Item) -> Self::Item,
214 {
215 match self {
216 $($name::$variant(i) => i.reduce(f),)+
217 }
218 }
219
220 fn all<Fun>(&mut self, f: Fun) -> bool
221 where
222 Self: Sized,
223 Fun: FnMut(Self::Item) -> bool,
224 {
225 match self {
226 $($name::$variant(i) => i.all(f),)+
227 }
228 }
229
230 fn any<Fun>(&mut self, f: Fun) -> bool
231 where
232 Self: Sized,
233 Fun: FnMut(Self::Item) -> bool,
234 {
235 match self {
236 $($name::$variant(i) => i.any(f),)+
237 }
238 }
239
240 fn find<Pre>(&mut self, predicate: Pre) -> Option<Self::Item>
241 where
242 Self: Sized,
243 Pre: FnMut(&Self::Item) -> bool,
244 {
245 match self {
246 $($name::$variant(i) => i.find(predicate),)+
247 }
248 }
249
250 fn find_map<Out, Fun>(&mut self, f: Fun) -> Option<Out>
251 where
252 Self: Sized,
253 Fun: FnMut(Self::Item) -> Option<Out>,
254 {
255 match self {
256 $($name::$variant(i) => i.find_map(f),)+
257 }
258 }
259
260 fn position<Pre>(&mut self, predicate: Pre) -> Option<usize>
261 where
262 Self: Sized,
263 Pre: FnMut(Self::Item) -> bool,
264 {
265 match self {
266 $($name::$variant(i) => i.position(predicate),)+
267 }
268 }
269
270 fn max(self) -> Option<Self::Item>
271 where
272 Self: Sized,
273 Self::Item: Ord,
274 {
275 match self {
276 $($name::$variant(i) => i.max(),)+
277 }
278 }
279
280 fn min(self) -> Option<Self::Item>
281 where
282 Self: Sized,
283 Self::Item: Ord,
284 {
285 match self {
286 $($name::$variant(i) => i.min(),)+
287 }
288 }
289
290 fn max_by_key<Key: Ord, Fun>(self, f: Fun) -> Option<Self::Item>
291 where
292 Self: Sized,
293 Fun: FnMut(&Self::Item) -> Key,
294 {
295 match self {
296 $($name::$variant(i) => i.max_by_key(f),)+
297 }
298 }
299
300 fn max_by<Cmp>(self, compare: Cmp) -> Option<Self::Item>
301 where
302 Self: Sized,
303 Cmp: FnMut(&Self::Item, &Self::Item) -> Ordering,
304 {
305 match self {
306 $($name::$variant(i) => i.max_by(compare),)+
307 }
308 }
309
310 fn min_by_key<Key: Ord, Fun>(self, f: Fun) -> Option<Self::Item>
311 where
312 Self: Sized,
313 Fun: FnMut(&Self::Item) -> Key,
314 {
315 match self {
316 $($name::$variant(i) => i.min_by_key(f),)+
317 }
318 }
319
320 fn min_by<Cmp>(self, compare: Cmp) -> Option<Self::Item>
321 where
322 Self: Sized,
323 Cmp: FnMut(&Self::Item, &Self::Item) -> Ordering,
324 {
325 match self {
326 $($name::$variant(i) => i.min_by(compare),)+
327 }
328 }
329
330 fn sum<Out>(self) -> Out
331 where
332 Self: Sized,
333 Out: Sum<Self::Item>,
334 {
335 match self {
336 $($name::$variant(i) => i.sum(),)+
337 }
338 }
339
340 fn product<Out>(self) -> Out
341 where
342 Self: Sized,
343 Out: Product<Self::Item>,
344 {
345 match self {
346 $($name::$variant(i) => i.product(),)+
347 }
348 }
349
350 fn cmp<Other>(self, other: Other) -> Ordering
351 where
352 Other: IntoIterator<Item = Self::Item>,
353 Self::Item: Ord,
354 Self: Sized,
355 {
356 match self {
357 $($name::$variant(i) => i.cmp(other),)+
358 }
359 }
360
361 fn partial_cmp<Other>(self, other: Other) -> Option<Ordering>
362 where
363 Other: IntoIterator,
364 Self::Item: PartialOrd<Other::Item>,
365 Self: Sized,
366 {
367 match self {
368 $($name::$variant(i) => i.partial_cmp(other),)+
369 }
370 }
371
372 }
404
405 impl<Item, $($ty),+> ExactSizeIterator for $name<$($ty),+>
406 where
407 $($ty: ExactSizeIterator<Item = Item>,)+
408 {
409 fn len(&self) -> usize {
410 match self {
411 $($name::$variant(i) => i.len(),)+
412 }
413 }
414 }
415
416 impl<Item, $($ty),+> DoubleEndedIterator for $name<$($ty),+>
417 where
418 $($ty: DoubleEndedIterator<Item = Item>,)+
419 {
420 fn next_back(&mut self) -> Option<Self::Item> {
421 match self {
422 $($name::$variant(i) => i.next_back(),)+
423 }
424 }
425
426 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
427 match self {
428 $($name::$variant(i) => i.nth_back(n),)+
429 }
430 }
431
432 fn rfind<Pre>(&mut self, predicate: Pre) -> Option<Self::Item>
433 where
434 Pre: FnMut(&Self::Item) -> bool,
435 {
436 match self {
437 $($name::$variant(i) => i.rfind(predicate),)+
438 }
439 }
440 }
441
442 pin_project! {
443 #[project = $fut_proj]
444 pub enum $fut_name<$($ty),+> {
445 $($variant { #[pin] inner: $ty },)+
446 }
447 }
448
449 impl<$($ty),+> Future for $fut_name<$($ty),+>
450 where
451 $($ty: Future,)+
452 {
453 type Output = $name<$($ty::Output),+>;
454
455 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
456 let this = self.project();
457 match this {
458 $($fut_proj::$variant { inner } => match inner.poll(cx) {
459 Poll::Pending => Poll::Pending,
460 Poll::Ready(inner) => Poll::Ready($name::$variant(inner)),
461 },)+
462 }
463 }
464 }
465 }
466}
467
468tuples!(Either + EitherFuture + EitherFutureProj {
469 Left(A) => (Right) + <A1, B>,
470 Right(B) => (Left) + <A, B1>,
471});
472
473impl<A, B> Either<A, B> {
474 pub fn swap(self) -> Either<B, A> {
475 match self {
476 Either::Left(a) => Either::Right(a),
477 Either::Right(b) => Either::Left(b),
478 }
479 }
480}
481
482impl<A, B> From<Result<A, B>> for Either<A, B> {
483 fn from(value: Result<A, B>) -> Self {
484 match value {
485 Ok(left) => Either::Left(left),
486 Err(right) => Either::Right(right),
487 }
488 }
489}
490
491pub trait EitherOr {
492 type Left;
493 type Right;
494 fn either_or<FA, A, FB, B>(self, a: FA, b: FB) -> Either<A, B>
495 where
496 FA: FnOnce(Self::Left) -> A,
497 FB: FnOnce(Self::Right) -> B;
498}
499
500impl EitherOr for bool {
501 type Left = ();
502 type Right = ();
503
504 fn either_or<FA, A, FB, B>(self, a: FA, b: FB) -> Either<A, B>
505 where
506 FA: FnOnce(Self::Left) -> A,
507 FB: FnOnce(Self::Right) -> B,
508 {
509 if self {
510 Either::Left(a(()))
511 } else {
512 Either::Right(b(()))
513 }
514 }
515}
516
517impl<T> EitherOr for Option<T> {
518 type Left = T;
519 type Right = ();
520
521 fn either_or<FA, A, FB, B>(self, a: FA, b: FB) -> Either<A, B>
522 where
523 FA: FnOnce(Self::Left) -> A,
524 FB: FnOnce(Self::Right) -> B,
525 {
526 match self {
527 Some(t) => Either::Left(a(t)),
528 None => Either::Right(b(())),
529 }
530 }
531}
532
533impl<T, E> EitherOr for Result<T, E> {
534 type Left = T;
535 type Right = E;
536
537 fn either_or<FA, A, FB, B>(self, a: FA, b: FB) -> Either<A, B>
538 where
539 FA: FnOnce(Self::Left) -> A,
540 FB: FnOnce(Self::Right) -> B,
541 {
542 match self {
543 Ok(t) => Either::Left(a(t)),
544 Err(err) => Either::Right(b(err)),
545 }
546 }
547}
548
549impl<A, B> EitherOr for Either<A, B> {
550 type Left = A;
551 type Right = B;
552
553 #[inline]
554 fn either_or<FA, A1, FB, B1>(self, a: FA, b: FB) -> Either<A1, B1>
555 where
556 FA: FnOnce(<Self as EitherOr>::Left) -> A1,
557 FB: FnOnce(<Self as EitherOr>::Right) -> B1,
558 {
559 self.map(a, b)
560 }
561}
562
563#[test]
564fn test_either_or() {
565 let right = false.either_or(|_| 'a', |_| 12);
566 assert!(matches!(right, Either::Right(12)));
567
568 let left = true.either_or(|_| 'a', |_| 12);
569 assert!(matches!(left, Either::Left('a')));
570
571 let left = Some(12).either_or(|a| a, |_| 'a');
572 assert!(matches!(left, Either::Left(12)));
573 let right = None.either_or(|a: i32| a, |_| 'a');
574 assert!(matches!(right, Either::Right('a')));
575
576 let result: Result<_, ()> = Ok(1.2f32);
577 let left = result.either_or(|a| a * 2f32, |b| b);
578 assert!(matches!(left, Either::Left(2.4f32)));
579
580 let result: Result<i32, _> = Err("12");
581 let right = result.either_or(|a| a, |b| b.chars().next());
582 assert!(matches!(right, Either::Right(Some('1'))));
583
584 let either = Either::<i32, char>::Left(12);
585 let left = either.either_or(|a| a, |b| b);
586 assert!(matches!(left, Either::Left(12)));
587
588 let either = Either::<i32, char>::Right('a');
589 let right = either.either_or(|a| a, |b| b);
590 assert!(matches!(right, Either::Right('a')));
591}
592
593tuples!(EitherOf3 + EitherOf3Future + EitherOf3FutureProj {
594 A => (B, C) + <A1, B, C>,
595 B => (A, C) + <A, B1, C>,
596 C => (A, B) + <A, B, C1>,
597});
598tuples!(EitherOf4 + EitherOf4Future + EitherOf4FutureProj {
599 A => (B, C, D) + <A1, B, C, D>,
600 B => (A, C, D) + <A, B1, C, D>,
601 C => (A, B, D) + <A, B, C1, D>,
602 D => (A, B, C) + <A, B, C, D1>,
603});
604tuples!(EitherOf5 + EitherOf5Future + EitherOf5FutureProj {
605 A => (B, C, D, E) + <A1, B, C, D, E>,
606 B => (A, C, D, E) + <A, B1, C, D, E>,
607 C => (A, B, D, E) + <A, B, C1, D, E>,
608 D => (A, B, C, E) + <A, B, C, D1, E>,
609 E => (A, B, C, D) + <A, B, C, D, E1>,
610});
611tuples!(EitherOf6 + EitherOf6Future + EitherOf6FutureProj {
612 A => (B, C, D, E, F) + <A1, B, C, D, E, F>,
613 B => (A, C, D, E, F) + <A, B1, C, D, E, F>,
614 C => (A, B, D, E, F) + <A, B, C1, D, E, F>,
615 D => (A, B, C, E, F) + <A, B, C, D1, E, F>,
616 E => (A, B, C, D, F) + <A, B, C, D, E1, F>,
617 F => (A, B, C, D, E) + <A, B, C, D, E, F1>,
618});
619tuples!(EitherOf7 + EitherOf7Future + EitherOf7FutureProj {
620 A => (B, C, D, E, F, G) + <A1, B, C, D, E, F, G>,
621 B => (A, C, D, E, F, G) + <A, B1, C, D, E, F, G>,
622 C => (A, B, D, E, F, G) + <A, B, C1, D, E, F, G>,
623 D => (A, B, C, E, F, G) + <A, B, C, D1, E, F, G>,
624 E => (A, B, C, D, F, G) + <A, B, C, D, E1, F, G>,
625 F => (A, B, C, D, E, G) + <A, B, C, D, E, F1, G>,
626 G => (A, B, C, D, E, F) + <A, B, C, D, E, F, G1>,
627});
628tuples!(EitherOf8 + EitherOf8Future + EitherOf8FutureProj {
629 A => (B, C, D, E, F, G, H) + <A1, B, C, D, E, F, G, H>,
630 B => (A, C, D, E, F, G, H) + <A, B1, C, D, E, F, G, H>,
631 C => (A, B, D, E, F, G, H) + <A, B, C1, D, E, F, G, H>,
632 D => (A, B, C, E, F, G, H) + <A, B, C, D1, E, F, G, H>,
633 E => (A, B, C, D, F, G, H) + <A, B, C, D, E1, F, G, H>,
634 F => (A, B, C, D, E, G, H) + <A, B, C, D, E, F1, G, H>,
635 G => (A, B, C, D, E, F, H) + <A, B, C, D, E, F, G1, H>,
636 H => (A, B, C, D, E, F, G) + <A, B, C, D, E, F, G, H1>,
637});
638tuples!(EitherOf9 + EitherOf9Future + EitherOf9FutureProj {
639 A => (B, C, D, E, F, G, H, I) + <A1, B, C, D, E, F, G, H, I>,
640 B => (A, C, D, E, F, G, H, I) + <A, B1, C, D, E, F, G, H, I>,
641 C => (A, B, D, E, F, G, H, I) + <A, B, C1, D, E, F, G, H, I>,
642 D => (A, B, C, E, F, G, H, I) + <A, B, C, D1, E, F, G, H, I>,
643 E => (A, B, C, D, F, G, H, I) + <A, B, C, D, E1, F, G, H, I>,
644 F => (A, B, C, D, E, G, H, I) + <A, B, C, D, E, F1, G, H, I>,
645 G => (A, B, C, D, E, F, H, I) + <A, B, C, D, E, F, G1, H, I>,
646 H => (A, B, C, D, E, F, G, I) + <A, B, C, D, E, F, G, H1, I>,
647 I => (A, B, C, D, E, F, G, H) + <A, B, C, D, E, F, G, H, I1>,
648});
649tuples!(EitherOf10 + EitherOf10Future + EitherOf10FutureProj {
650 A => (B, C, D, E, F, G, H, I, J) + <A1, B, C, D, E, F, G, H, I, J>,
651 B => (A, C, D, E, F, G, H, I, J) + <A, B1, C, D, E, F, G, H, I, J>,
652 C => (A, B, D, E, F, G, H, I, J) + <A, B, C1, D, E, F, G, H, I, J>,
653 D => (A, B, C, E, F, G, H, I, J) + <A, B, C, D1, E, F, G, H, I, J>,
654 E => (A, B, C, D, F, G, H, I, J) + <A, B, C, D, E1, F, G, H, I, J>,
655 F => (A, B, C, D, E, G, H, I, J) + <A, B, C, D, E, F1, G, H, I, J>,
656 G => (A, B, C, D, E, F, H, I, J) + <A, B, C, D, E, F, G1, H, I, J>,
657 H => (A, B, C, D, E, F, G, I, J) + <A, B, C, D, E, F, G, H1, I, J>,
658 I => (A, B, C, D, E, F, G, H, J) + <A, B, C, D, E, F, G, H, I1, J>,
659 J => (A, B, C, D, E, F, G, H, I) + <A, B, C, D, E, F, G, H, I, J1>,
660});
661tuples!(EitherOf11 + EitherOf11Future + EitherOf11FutureProj {
662 A => (B, C, D, E, F, G, H, I, J, K) + <A1, B, C, D, E, F, G, H, I, J, K>,
663 B => (A, C, D, E, F, G, H, I, J, K) + <A, B1, C, D, E, F, G, H, I, J, K>,
664 C => (A, B, D, E, F, G, H, I, J, K) + <A, B, C1, D, E, F, G, H, I, J, K>,
665 D => (A, B, C, E, F, G, H, I, J, K) + <A, B, C, D1, E, F, G, H, I, J, K>,
666 E => (A, B, C, D, F, G, H, I, J, K) + <A, B, C, D, E1, F, G, H, I, J, K>,
667 F => (A, B, C, D, E, G, H, I, J, K) + <A, B, C, D, E, F1, G, H, I, J, K>,
668 G => (A, B, C, D, E, F, H, I, J, K) + <A, B, C, D, E, F, G1, H, I, J, K>,
669 H => (A, B, C, D, E, F, G, I, J, K) + <A, B, C, D, E, F, G, H1, I, J, K>,
670 I => (A, B, C, D, E, F, G, H, J, K) + <A, B, C, D, E, F, G, H, I1, J, K>,
671 J => (A, B, C, D, E, F, G, H, I, K) + <A, B, C, D, E, F, G, H, I, J1, K>,
672 K => (A, B, C, D, E, F, G, H, I, J) + <A, B, C, D, E, F, G, H, I, J, K1>,
673});
674tuples!(EitherOf12 + EitherOf12Future + EitherOf12FutureProj {
675 A => (B, C, D, E, F, G, H, I, J, K, L) + <A1, B, C, D, E, F, G, H, I, J, K, L>,
676 B => (A, C, D, E, F, G, H, I, J, K, L) + <A, B1, C, D, E, F, G, H, I, J, K, L>,
677 C => (A, B, D, E, F, G, H, I, J, K, L) + <A, B, C1, D, E, F, G, H, I, J, K, L>,
678 D => (A, B, C, E, F, G, H, I, J, K, L) + <A, B, C, D1, E, F, G, H, I, J, K, L>,
679 E => (A, B, C, D, F, G, H, I, J, K, L) + <A, B, C, D, E1, F, G, H, I, J, K, L>,
680 F => (A, B, C, D, E, G, H, I, J, K, L) + <A, B, C, D, E, F1, G, H, I, J, K, L>,
681 G => (A, B, C, D, E, F, H, I, J, K, L) + <A, B, C, D, E, F, G1, H, I, J, K, L>,
682 H => (A, B, C, D, E, F, G, I, J, K, L) + <A, B, C, D, E, F, G, H1, I, J, K, L>,
683 I => (A, B, C, D, E, F, G, H, J, K, L) + <A, B, C, D, E, F, G, H, I1, J, K, L>,
684 J => (A, B, C, D, E, F, G, H, I, K, L) + <A, B, C, D, E, F, G, H, I, J1, K, L>,
685 K => (A, B, C, D, E, F, G, H, I, J, L) + <A, B, C, D, E, F, G, H, I, J, K1, L>,
686 L => (A, B, C, D, E, F, G, H, I, J, K) + <A, B, C, D, E, F, G, H, I, J, K, L1>,
687});
688tuples!(EitherOf13 + EitherOf13Future + EitherOf13FutureProj {
689 A => (B, C, D, E, F, G, H, I, J, K, L, M) + <A1, B, C, D, E, F, G, H, I, J, K, L, M>,
690 B => (A, C, D, E, F, G, H, I, J, K, L, M) + <A, B1, C, D, E, F, G, H, I, J, K, L, M>,
691 C => (A, B, D, E, F, G, H, I, J, K, L, M) + <A, B, C1, D, E, F, G, H, I, J, K, L, M>,
692 D => (A, B, C, E, F, G, H, I, J, K, L, M) + <A, B, C, D1, E, F, G, H, I, J, K, L, M>,
693 E => (A, B, C, D, F, G, H, I, J, K, L, M) + <A, B, C, D, E1, F, G, H, I, J, K, L, M>,
694 F => (A, B, C, D, E, G, H, I, J, K, L, M) + <A, B, C, D, E, F1, G, H, I, J, K, L, M>,
695 G => (A, B, C, D, E, F, H, I, J, K, L, M) + <A, B, C, D, E, F, G1, H, I, J, K, L, M>,
696 H => (A, B, C, D, E, F, G, I, J, K, L, M) + <A, B, C, D, E, F, G, H1, I, J, K, L, M>,
697 I => (A, B, C, D, E, F, G, H, J, K, L, M) + <A, B, C, D, E, F, G, H, I1, J, K, L, M>,
698 J => (A, B, C, D, E, F, G, H, I, K, L, M) + <A, B, C, D, E, F, G, H, I, J1, K, L, M>,
699 K => (A, B, C, D, E, F, G, H, I, J, L, M) + <A, B, C, D, E, F, G, H, I, J, K1, L, M>,
700 L => (A, B, C, D, E, F, G, H, I, J, K, M) + <A, B, C, D, E, F, G, H, I, J, K, L1, M>,
701 M => (A, B, C, D, E, F, G, H, I, J, K, L) + <A, B, C, D, E, F, G, H, I, J, K, L, M1>,
702});
703tuples!(EitherOf14 + EitherOf14Future + EitherOf14FutureProj {
704 A => (B, C, D, E, F, G, H, I, J, K, L, M, N) + <A1, B, C, D, E, F, G, H, I, J, K, L, M, N>,
705 B => (A, C, D, E, F, G, H, I, J, K, L, M, N) + <A, B1, C, D, E, F, G, H, I, J, K, L, M, N>,
706 C => (A, B, D, E, F, G, H, I, J, K, L, M, N) + <A, B, C1, D, E, F, G, H, I, J, K, L, M, N>,
707 D => (A, B, C, E, F, G, H, I, J, K, L, M, N) + <A, B, C, D1, E, F, G, H, I, J, K, L, M, N>,
708 E => (A, B, C, D, F, G, H, I, J, K, L, M, N) + <A, B, C, D, E1, F, G, H, I, J, K, L, M, N>,
709 F => (A, B, C, D, E, G, H, I, J, K, L, M, N) + <A, B, C, D, E, F1, G, H, I, J, K, L, M, N>,
710 G => (A, B, C, D, E, F, H, I, J, K, L, M, N) + <A, B, C, D, E, F, G1, H, I, J, K, L, M, N>,
711 H => (A, B, C, D, E, F, G, I, J, K, L, M, N) + <A, B, C, D, E, F, G, H1, I, J, K, L, M, N>,
712 I => (A, B, C, D, E, F, G, H, J, K, L, M, N) + <A, B, C, D, E, F, G, H, I1, J, K, L, M, N>,
713 J => (A, B, C, D, E, F, G, H, I, K, L, M, N) + <A, B, C, D, E, F, G, H, I, J1, K, L, M, N>,
714 K => (A, B, C, D, E, F, G, H, I, J, L, M, N) + <A, B, C, D, E, F, G, H, I, J, K1, L, M, N>,
715 L => (A, B, C, D, E, F, G, H, I, J, K, M, N) + <A, B, C, D, E, F, G, H, I, J, K, L1, M, N>,
716 M => (A, B, C, D, E, F, G, H, I, J, K, L, N) + <A, B, C, D, E, F, G, H, I, J, K, L, M1, N>,
717 N => (A, B, C, D, E, F, G, H, I, J, K, L, M) + <A, B, C, D, E, F, G, H, I, J, K, L, M, N1>,
718});
719tuples!(EitherOf15 + EitherOf15Future + EitherOf15FutureProj {
720 A => (B, C, D, E, F, G, H, I, J, K, L, M, N, O) + <A1, B, C, D, E, F, G, H, I, J, K, L, M, N, O>,
721 B => (A, C, D, E, F, G, H, I, J, K, L, M, N, O) + <A, B1, C, D, E, F, G, H, I, J, K, L, M, N, O>,
722 C => (A, B, D, E, F, G, H, I, J, K, L, M, N, O) + <A, B, C1, D, E, F, G, H, I, J, K, L, M, N, O>,
723 D => (A, B, C, E, F, G, H, I, J, K, L, M, N, O) + <A, B, C, D1, E, F, G, H, I, J, K, L, M, N, O>,
724 E => (A, B, C, D, F, G, H, I, J, K, L, M, N, O) + <A, B, C, D, E1, F, G, H, I, J, K, L, M, N, O>,
725 F => (A, B, C, D, E, G, H, I, J, K, L, M, N, O) + <A, B, C, D, E, F1, G, H, I, J, K, L, M, N, O>,
726 G => (A, B, C, D, E, F, H, I, J, K, L, M, N, O) + <A, B, C, D, E, F, G1, H, I, J, K, L, M, N, O>,
727 H => (A, B, C, D, E, F, G, I, J, K, L, M, N, O) + <A, B, C, D, E, F, G, H1, I, J, K, L, M, N, O>,
728 I => (A, B, C, D, E, F, G, H, J, K, L, M, N, O) + <A, B, C, D, E, F, G, H, I1, J, K, L, M, N, O>,
729 J => (A, B, C, D, E, F, G, H, I, K, L, M, N, O) + <A, B, C, D, E, F, G, H, I, J1, K, L, M, N, O>,
730 K => (A, B, C, D, E, F, G, H, I, J, L, M, N, O) + <A, B, C, D, E, F, G, H, I, J, K1, L, M, N, O>,
731 L => (A, B, C, D, E, F, G, H, I, J, K, M, N, O) + <A, B, C, D, E, F, G, H, I, J, K, L1, M, N, O>,
732 M => (A, B, C, D, E, F, G, H, I, J, K, L, N, O) + <A, B, C, D, E, F, G, H, I, J, K, L, M1, N, O>,
733 N => (A, B, C, D, E, F, G, H, I, J, K, L, M, O) + <A, B, C, D, E, F, G, H, I, J, K, L, M, N1, O>,
734 O => (A, B, C, D, E, F, G, H, I, J, K, L, M, N) + <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O1>,
735});
736tuples!(EitherOf16 + EitherOf16Future + EitherOf16FutureProj {
737 A => (B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) + <A1, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>,
738 B => (A, C, D, E, F, G, H, I, J, K, L, M, N, O, P) + <A, B1, C, D, E, F, G, H, I, J, K, L, M, N, O, P>,
739 C => (A, B, D, E, F, G, H, I, J, K, L, M, N, O, P) + <A, B, C1, D, E, F, G, H, I, J, K, L, M, N, O, P>,
740 D => (A, B, C, E, F, G, H, I, J, K, L, M, N, O, P) + <A, B, C, D1, E, F, G, H, I, J, K, L, M, N, O, P>,
741 E => (A, B, C, D, F, G, H, I, J, K, L, M, N, O, P) + <A, B, C, D, E1, F, G, H, I, J, K, L, M, N, O, P>,
742 F => (A, B, C, D, E, G, H, I, J, K, L, M, N, O, P) + <A, B, C, D, E, F1, G, H, I, J, K, L, M, N, O, P>,
743 G => (A, B, C, D, E, F, H, I, J, K, L, M, N, O, P) + <A, B, C, D, E, F, G1, H, I, J, K, L, M, N, O, P>,
744 H => (A, B, C, D, E, F, G, I, J, K, L, M, N, O, P) + <A, B, C, D, E, F, G, H1, I, J, K, L, M, N, O, P>,
745 I => (A, B, C, D, E, F, G, H, J, K, L, M, N, O, P) + <A, B, C, D, E, F, G, H, I1, J, K, L, M, N, O, P>,
746 J => (A, B, C, D, E, F, G, H, I, K, L, M, N, O, P) + <A, B, C, D, E, F, G, H, I, J1, K, L, M, N, O, P>,
747 K => (A, B, C, D, E, F, G, H, I, J, L, M, N, O, P) + <A, B, C, D, E, F, G, H, I, J, K1, L, M, N, O, P>,
748 L => (A, B, C, D, E, F, G, H, I, J, K, M, N, O, P) + <A, B, C, D, E, F, G, H, I, J, K, L1, M, N, O, P>,
749 M => (A, B, C, D, E, F, G, H, I, J, K, L, N, O, P) + <A, B, C, D, E, F, G, H, I, J, K, L, M1, N, O, P>,
750 N => (A, B, C, D, E, F, G, H, I, J, K, L, M, O, P) + <A, B, C, D, E, F, G, H, I, J, K, L, M, N1, O, P>,
751 O => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, P) + <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O1, P>,
752 P => (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) + <A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P1>,
753});
754
755#[macro_export]
778macro_rules! either {
779 ($match:expr, $left_pattern:pat => $left_expression:expr, $right_pattern:pat => $right_expression:expr$(,)?) => {
780 match $match {
781 $left_pattern => $crate::Either::Left($left_expression),
782 $right_pattern => $crate::Either::Right($right_expression),
783 }
784 };
785 ($match:expr, $a_pattern:pat => $a_expression:expr, $b_pattern:pat => $b_expression:expr, $c_pattern:pat => $c_expression:expr$(,)?) => {
786 match $match {
787 $a_pattern => $crate::EitherOf3::A($a_expression),
788 $b_pattern => $crate::EitherOf3::B($b_expression),
789 $c_pattern => $crate::EitherOf3::C($c_expression),
790 }
791 };
792 ($match:expr, $a_pattern:pat => $a_expression:expr, $b_pattern:pat => $b_expression:expr, $c_pattern:pat => $c_expression:expr, $d_pattern:pat => $d_expression:expr$(,)?) => {
793 match $match {
794 $a_pattern => $crate::EitherOf4::A($a_expression),
795 $b_pattern => $crate::EitherOf4::B($b_expression),
796 $c_pattern => $crate::EitherOf4::C($c_expression),
797 $d_pattern => $crate::EitherOf4::D($d_expression),
798 }
799 };
800 ($match:expr, $a_pattern:pat => $a_expression:expr, $b_pattern:pat => $b_expression:expr, $c_pattern:pat => $c_expression:expr, $d_pattern:pat => $d_expression:expr, $e_pattern:pat => $e_expression:expr$(,)?) => {
801 match $match {
802 $a_pattern => $crate::EitherOf5::A($a_expression),
803 $b_pattern => $crate::EitherOf5::B($b_expression),
804 $c_pattern => $crate::EitherOf5::C($c_expression),
805 $d_pattern => $crate::EitherOf5::D($d_expression),
806 $e_pattern => $crate::EitherOf5::E($e_expression),
807 }
808 };
809 ($match:expr, $a_pattern:pat => $a_expression:expr, $b_pattern:pat => $b_expression:expr, $c_pattern:pat => $c_expression:expr, $d_pattern:pat => $d_expression:expr, $e_pattern:pat => $e_expression:expr, $f_pattern:pat => $f_expression:expr$(,)?) => {
810 match $match {
811 $a_pattern => $crate::EitherOf6::A($a_expression),
812 $b_pattern => $crate::EitherOf6::B($b_expression),
813 $c_pattern => $crate::EitherOf6::C($c_expression),
814 $d_pattern => $crate::EitherOf6::D($d_expression),
815 $e_pattern => $crate::EitherOf6::E($e_expression),
816 $f_pattern => $crate::EitherOf6::F($f_expression),
817 }
818 };
819 ($match:expr, $a_pattern:pat => $a_expression:expr, $b_pattern:pat => $b_expression:expr, $c_pattern:pat => $c_expression:expr, $d_pattern:pat => $d_expression:expr, $e_pattern:pat => $e_expression:expr, $f_pattern:pat => $f_expression:expr, $g_pattern:pat => $g_expression:expr$(,)?) => {
820 match $match {
821 $a_pattern => $crate::EitherOf7::A($a_expression),
822 $b_pattern => $crate::EitherOf7::B($b_expression),
823 $c_pattern => $crate::EitherOf7::C($c_expression),
824 $d_pattern => $crate::EitherOf7::D($d_expression),
825 $e_pattern => $crate::EitherOf7::E($e_expression),
826 $f_pattern => $crate::EitherOf7::F($f_expression),
827 $g_pattern => $crate::EitherOf7::G($g_expression),
828 }
829 };
830 ($match:expr, $a_pattern:pat => $a_expression:expr, $b_pattern:pat => $b_expression:expr, $c_pattern:pat => $c_expression:expr, $d_pattern:pat => $d_expression:expr, $e_pattern:pat => $e_expression:expr, $f_pattern:pat => $f_expression:expr, $g_pattern:pat => $g_expression:expr, $h_pattern:pat => $h_expression:expr$(,)?) => {
831 match $match {
832 $a_pattern => $crate::EitherOf8::A($a_expression),
833 $b_pattern => $crate::EitherOf8::B($b_expression),
834 $c_pattern => $crate::EitherOf8::C($c_expression),
835 $d_pattern => $crate::EitherOf8::D($d_expression),
836 $e_pattern => $crate::EitherOf8::E($e_expression),
837 $f_pattern => $crate::EitherOf8::F($f_expression),
838 $g_pattern => $crate::EitherOf8::G($g_expression),
839 $h_pattern => $crate::EitherOf8::H($h_expression),
840 }
841 }; }
843
844#[cfg(test)]
845mod tests {
846 use super::*;
847
848 #[test]
850 fn either_macro() {
851 let _: Either<&str, f64> = either!(12,
852 12 => "12",
853 _ => 0.0,
854 );
855 let _: EitherOf3<&str, f64, i32> = either!(12,
856 12 => "12",
857 13 => 0.0,
858 _ => 12,
859 );
860 let _: EitherOf4<&str, f64, char, i32> = either!(12,
861 12 => "12",
862 13 => 0.0,
863 14 => ' ',
864 _ => 12,
865 );
866 let _: EitherOf5<&str, f64, char, f32, i32> = either!(12,
867 12 => "12",
868 13 => 0.0,
869 14 => ' ',
870 15 => 0.0f32,
871 _ => 12,
872 );
873 let _: EitherOf6<&str, f64, char, f32, u8, i32> = either!(12,
874 12 => "12",
875 13 => 0.0,
876 14 => ' ',
877 15 => 0.0f32,
878 16 => 24u8,
879 _ => 12,
880 );
881 let _: EitherOf7<&str, f64, char, f32, u8, i8, i32> = either!(12,
882 12 => "12",
883 13 => 0.0,
884 14 => ' ',
885 15 => 0.0f32,
886 16 => 24u8,
887 17 => 2i8,
888 _ => 12,
889 );
890 let _: EitherOf8<&str, f64, char, f32, u8, i8, u32, i32> = either!(12,
891 12 => "12",
892 13 => 0.0,
893 14 => ' ',
894 15 => 0.0f32,
895 16 => 24u8,
896 17 => 2i8,
897 18 => 42u32,
898 _ => 12,
899 );
900 }
901
902 #[test]
903 #[should_panic]
904 fn unwrap_wrong_either() {
905 Either::<i32, &str>::Left(0).unwrap_right();
906 }
907}