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<L: fmt::Display, R: fmt::Display> fmt::Display for Either<L, R> {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 Either::Left(l) => write!(f, "{l}"),
38 Either::Right(r) => write!(f, "{r}"),
39 }
40 }
41}
42
43impl<L: Error, R: Error> Error for Either<L, R> {}
44impl<I, L: Iterator<Item = I>, R: Iterator<Item = I>> Iterator for Either<L, R> {
45 type Item = I;
46
47 fn next(&mut self) -> Option<Self::Item> {
48 match self {
49 Either::Left(l) => l.next(),
50 Either::Right(r) => r.next(),
51 }
52 }
53}
54
55impl<I, L: Future<Output = I>, R: Future<Output = I>> Future for Either<L, R> {
56 type Output = I;
57
58 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
59 match unsafe { self.get_unchecked_mut() } {
60 Either::Left(l) => unsafe { Pin::new_unchecked(l) }.poll(cx),
61 Either::Right(r) => unsafe { Pin::new_unchecked(r) }.poll(cx),
62 }
63 }
64}
65
66impl<I, L: Stream<Item = I>, R: Stream<Item = I>> Stream for Either<L, R> {
67 type Item = I;
68
69 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
70 match unsafe { self.get_unchecked_mut() } {
71 Either::Left(l) => unsafe { Pin::new_unchecked(l) }.poll_next(cx),
72 Either::Right(r) => unsafe { Pin::new_unchecked(r) }.poll_next(cx),
73 }
74 }
75}