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