1use std::{
2 error::Error,
3 fmt,
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8use futures::Stream;
9
10#[derive(Debug, Clone, Copy, PartialEq)]
11pub enum Either<L, R = L> {
12 Left(L),
13 Right(R),
14}
15
16impl<L, R> Either<L, R> {
17 #[inline]
18 pub fn into_left(self) -> L {
19 match self {
20 Either::Left(left) => left,
21 Either::Right(_) => unreachable!(),
22 }
23 }
24
25 #[inline]
26 pub fn into_right(self) -> R {
27 match self {
28 Either::Left(_) => unreachable!(),
29 Either::Right(right) => right,
30 }
31 }
32}
33
34impl<T> Either<T, T> {
35 #[inline]
36 pub fn into_inner(self) -> T {
37 match self {
38 Either::Left(left) => left,
39 Either::Right(right) => right,
40 }
41 }
42}
43
44impl<L: fmt::Display, R: fmt::Display> fmt::Display for Either<L, R> {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 Either::Left(l) => write!(f, "{l}"),
48 Either::Right(r) => write!(f, "{r}"),
49 }
50 }
51}
52
53impl<L: Error, R: Error> Error for Either<L, R> {}
54impl<I, L: Iterator<Item = I>, R: Iterator<Item = I>> Iterator for Either<L, R> {
55 type Item = I;
56
57 fn next(&mut self) -> Option<Self::Item> {
58 match self {
59 Either::Left(l) => l.next(),
60 Either::Right(r) => r.next(),
61 }
62 }
63}
64
65impl<I, L: Future<Output = I>, R: Future<Output = I>> Future for Either<L, R> {
66 type Output = I;
67
68 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
69 match unsafe { self.get_unchecked_mut() } {
70 Either::Left(l) => unsafe { Pin::new_unchecked(l) }.poll(cx),
71 Either::Right(r) => unsafe { Pin::new_unchecked(r) }.poll(cx),
72 }
73 }
74}
75
76impl<I, L: Stream<Item = I>, R: Stream<Item = I>> Stream for Either<L, R> {
77 type Item = I;
78
79 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
80 match unsafe { self.get_unchecked_mut() } {
81 Either::Left(l) => unsafe { Pin::new_unchecked(l) }.poll_next(cx),
82 Either::Right(r) => unsafe { Pin::new_unchecked(r) }.poll_next(cx),
83 }
84 }
85}