1 use core::pin::Pin;
2 use core::task::{Context, Poll};
3 use futures_core::future::{FusedFuture, Future};
4 use futures_core::stream::{FusedStream, Stream};
5 #[cfg(feature = "sink")]
6 use futures_sink::Sink;
7 
8 /// Combines two different futures, streams, or sinks having the same associated types into a single type.
9 ///
10 /// This is useful when conditionally choosing between two distinct future types:
11 ///
12 /// ```rust
13 /// use futures::future::Either;
14 ///
15 /// # futures::executor::block_on(async {
16 /// let cond = true;
17 ///
18 /// let fut = if cond {
19 ///     Either::Left(async move { 12 })
20 /// } else {
21 ///     Either::Right(async move { 44 })
22 /// };
23 ///
24 /// assert_eq!(fut.await, 12);
25 /// # })
26 /// ```
27 #[derive(Debug, Clone)]
28 pub enum Either<A, B> {
29     /// First branch of the type
30     Left(/* #[pin] */ A),
31     /// Second branch of the type
32     Right(/* #[pin] */ B),
33 }
34 
35 impl<A, B> Either<A, B> {
36     /// Convert `Pin<&Either<A, B>>` to `Either<Pin<&A>, Pin<&B>>`,
37     /// pinned projections of the inner variants.
as_pin_ref(self: Pin<&Self>) -> Either<Pin<&A>, Pin<&B>>38     pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&A>, Pin<&B>> {
39         // SAFETY: We can use `new_unchecked` because the `inner` parts are
40         // guaranteed to be pinned, as they come from `self` which is pinned.
41         unsafe {
42             match self.get_ref() {
43                 Self::Left(inner) => Either::Left(Pin::new_unchecked(inner)),
44                 Self::Right(inner) => Either::Right(Pin::new_unchecked(inner)),
45             }
46         }
47     }
48 
49     /// Convert `Pin<&mut Either<A, B>>` to `Either<Pin<&mut A>, Pin<&mut B>>`,
50     /// pinned projections of the inner variants.
as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut A>, Pin<&mut B>>51     pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut A>, Pin<&mut B>> {
52         // SAFETY: `get_unchecked_mut` is fine because we don't move anything.
53         // We can use `new_unchecked` because the `inner` parts are guaranteed
54         // to be pinned, as they come from `self` which is pinned, and we never
55         // offer an unpinned `&mut A` or `&mut B` through `Pin<&mut Self>`. We
56         // also don't have an implementation of `Drop`, nor manual `Unpin`.
57         unsafe {
58             match self.get_unchecked_mut() {
59                 Self::Left(inner) => Either::Left(Pin::new_unchecked(inner)),
60                 Self::Right(inner) => Either::Right(Pin::new_unchecked(inner)),
61             }
62         }
63     }
64 }
65 
66 impl<A, B, T> Either<(T, A), (T, B)> {
67     /// Factor out a homogeneous type from an either of pairs.
68     ///
69     /// Here, the homogeneous type is the first element of the pairs.
factor_first(self) -> (T, Either<A, B>)70     pub fn factor_first(self) -> (T, Either<A, B>) {
71         match self {
72             Self::Left((x, a)) => (x, Either::Left(a)),
73             Self::Right((x, b)) => (x, Either::Right(b)),
74         }
75     }
76 }
77 
78 impl<A, B, T> Either<(A, T), (B, T)> {
79     /// Factor out a homogeneous type from an either of pairs.
80     ///
81     /// Here, the homogeneous type is the second element of the pairs.
factor_second(self) -> (Either<A, B>, T)82     pub fn factor_second(self) -> (Either<A, B>, T) {
83         match self {
84             Self::Left((a, x)) => (Either::Left(a), x),
85             Self::Right((b, x)) => (Either::Right(b), x),
86         }
87     }
88 }
89 
90 impl<T> Either<T, T> {
91     /// Extract the value of an either over two equivalent types.
into_inner(self) -> T92     pub fn into_inner(self) -> T {
93         match self {
94             Self::Left(x) | Self::Right(x) => x,
95         }
96     }
97 }
98 
99 impl<A, B> Future for Either<A, B>
100 where
101     A: Future,
102     B: Future<Output = A::Output>,
103 {
104     type Output = A::Output;
105 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>106     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
107         match self.as_pin_mut() {
108             Either::Left(x) => x.poll(cx),
109             Either::Right(x) => x.poll(cx),
110         }
111     }
112 }
113 
114 impl<A, B> FusedFuture for Either<A, B>
115 where
116     A: FusedFuture,
117     B: FusedFuture<Output = A::Output>,
118 {
is_terminated(&self) -> bool119     fn is_terminated(&self) -> bool {
120         match self {
121             Self::Left(x) => x.is_terminated(),
122             Self::Right(x) => x.is_terminated(),
123         }
124     }
125 }
126 
127 impl<A, B> Stream for Either<A, B>
128 where
129     A: Stream,
130     B: Stream<Item = A::Item>,
131 {
132     type Item = A::Item;
133 
poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>134     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
135         match self.as_pin_mut() {
136             Either::Left(x) => x.poll_next(cx),
137             Either::Right(x) => x.poll_next(cx),
138         }
139     }
140 
size_hint(&self) -> (usize, Option<usize>)141     fn size_hint(&self) -> (usize, Option<usize>) {
142         match self {
143             Self::Left(x) => x.size_hint(),
144             Self::Right(x) => x.size_hint(),
145         }
146     }
147 }
148 
149 impl<A, B> FusedStream for Either<A, B>
150 where
151     A: FusedStream,
152     B: FusedStream<Item = A::Item>,
153 {
is_terminated(&self) -> bool154     fn is_terminated(&self) -> bool {
155         match self {
156             Self::Left(x) => x.is_terminated(),
157             Self::Right(x) => x.is_terminated(),
158         }
159     }
160 }
161 
162 #[cfg(feature = "sink")]
163 impl<A, B, Item> Sink<Item> for Either<A, B>
164 where
165     A: Sink<Item>,
166     B: Sink<Item, Error = A::Error>,
167 {
168     type Error = A::Error;
169 
poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>170     fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
171         match self.as_pin_mut() {
172             Either::Left(x) => x.poll_ready(cx),
173             Either::Right(x) => x.poll_ready(cx),
174         }
175     }
176 
start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error>177     fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
178         match self.as_pin_mut() {
179             Either::Left(x) => x.start_send(item),
180             Either::Right(x) => x.start_send(item),
181         }
182     }
183 
poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>184     fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
185         match self.as_pin_mut() {
186             Either::Left(x) => x.poll_flush(cx),
187             Either::Right(x) => x.poll_flush(cx),
188         }
189     }
190 
poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>191     fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
192         match self.as_pin_mut() {
193             Either::Left(x) => x.poll_close(cx),
194             Either::Right(x) => x.poll_close(cx),
195         }
196     }
197 }
198 
199 #[cfg(feature = "io")]
200 #[cfg(feature = "std")]
201 mod if_std {
202     use super::*;
203 
204     use futures_io::{
205         AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom,
206     };
207 
208     impl<A, B> AsyncRead for Either<A, B>
209     where
210         A: AsyncRead,
211         B: AsyncRead,
212     {
poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize>>213         fn poll_read(
214             self: Pin<&mut Self>,
215             cx: &mut Context<'_>,
216             buf: &mut [u8],
217         ) -> Poll<Result<usize>> {
218             match self.as_pin_mut() {
219                 Either::Left(x) => x.poll_read(cx, buf),
220                 Either::Right(x) => x.poll_read(cx, buf),
221             }
222         }
223 
poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll<Result<usize>>224         fn poll_read_vectored(
225             self: Pin<&mut Self>,
226             cx: &mut Context<'_>,
227             bufs: &mut [IoSliceMut<'_>],
228         ) -> Poll<Result<usize>> {
229             match self.as_pin_mut() {
230                 Either::Left(x) => x.poll_read_vectored(cx, bufs),
231                 Either::Right(x) => x.poll_read_vectored(cx, bufs),
232             }
233         }
234     }
235 
236     impl<A, B> AsyncWrite for Either<A, B>
237     where
238         A: AsyncWrite,
239         B: AsyncWrite,
240     {
poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>241         fn poll_write(
242             self: Pin<&mut Self>,
243             cx: &mut Context<'_>,
244             buf: &[u8],
245         ) -> Poll<Result<usize>> {
246             match self.as_pin_mut() {
247                 Either::Left(x) => x.poll_write(cx, buf),
248                 Either::Right(x) => x.poll_write(cx, buf),
249             }
250         }
251 
poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize>>252         fn poll_write_vectored(
253             self: Pin<&mut Self>,
254             cx: &mut Context<'_>,
255             bufs: &[IoSlice<'_>],
256         ) -> Poll<Result<usize>> {
257             match self.as_pin_mut() {
258                 Either::Left(x) => x.poll_write_vectored(cx, bufs),
259                 Either::Right(x) => x.poll_write_vectored(cx, bufs),
260             }
261         }
262 
poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>263         fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
264             match self.as_pin_mut() {
265                 Either::Left(x) => x.poll_flush(cx),
266                 Either::Right(x) => x.poll_flush(cx),
267             }
268         }
269 
poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>270         fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
271             match self.as_pin_mut() {
272                 Either::Left(x) => x.poll_close(cx),
273                 Either::Right(x) => x.poll_close(cx),
274             }
275         }
276     }
277 
278     impl<A, B> AsyncSeek for Either<A, B>
279     where
280         A: AsyncSeek,
281         B: AsyncSeek,
282     {
poll_seek( self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom, ) -> Poll<Result<u64>>283         fn poll_seek(
284             self: Pin<&mut Self>,
285             cx: &mut Context<'_>,
286             pos: SeekFrom,
287         ) -> Poll<Result<u64>> {
288             match self.as_pin_mut() {
289                 Either::Left(x) => x.poll_seek(cx, pos),
290                 Either::Right(x) => x.poll_seek(cx, pos),
291             }
292         }
293     }
294 
295     impl<A, B> AsyncBufRead for Either<A, B>
296     where
297         A: AsyncBufRead,
298         B: AsyncBufRead,
299     {
poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>>300         fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
301             match self.as_pin_mut() {
302                 Either::Left(x) => x.poll_fill_buf(cx),
303                 Either::Right(x) => x.poll_fill_buf(cx),
304             }
305         }
306 
consume(self: Pin<&mut Self>, amt: usize)307         fn consume(self: Pin<&mut Self>, amt: usize) {
308             match self.as_pin_mut() {
309                 Either::Left(x) => x.consume(amt),
310                 Either::Right(x) => x.consume(amt),
311             }
312         }
313     }
314 }
315