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 *Pin::get_ref(self) { 43 Either::Left(ref inner) => Either::Left(Pin::new_unchecked(inner)), 44 Either::Right(ref 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 *Pin::get_unchecked_mut(self) { 59 Either::Left(ref mut inner) => Either::Left(Pin::new_unchecked(inner)), 60 Either::Right(ref mut 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 Either::Left((x, a)) => (x, Either::Left(a)), 73 Either::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 Either::Left((a, x)) => (Either::Left(a), x), 85 Either::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 Either::Left(x) => x, 95 Either::Right(x) => x, 96 } 97 } 98 } 99 100 impl<A, B> Future for Either<A, B> 101 where 102 A: Future, 103 B: Future<Output = A::Output>, 104 { 105 type Output = A::Output; 106 poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>107 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 108 match self.as_pin_mut() { 109 Either::Left(x) => x.poll(cx), 110 Either::Right(x) => x.poll(cx), 111 } 112 } 113 } 114 115 impl<A, B> FusedFuture for Either<A, B> 116 where 117 A: FusedFuture, 118 B: FusedFuture<Output = A::Output>, 119 { is_terminated(&self) -> bool120 fn is_terminated(&self) -> bool { 121 match self { 122 Either::Left(x) => x.is_terminated(), 123 Either::Right(x) => x.is_terminated(), 124 } 125 } 126 } 127 128 impl<A, B> Stream for Either<A, B> 129 where 130 A: Stream, 131 B: Stream<Item = A::Item>, 132 { 133 type Item = A::Item; 134 poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>135 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { 136 match self.as_pin_mut() { 137 Either::Left(x) => x.poll_next(cx), 138 Either::Right(x) => x.poll_next(cx), 139 } 140 } 141 size_hint(&self) -> (usize, Option<usize>)142 fn size_hint(&self) -> (usize, Option<usize>) { 143 match self { 144 Either::Left(x) => x.size_hint(), 145 Either::Right(x) => x.size_hint(), 146 } 147 } 148 } 149 150 impl<A, B> FusedStream for Either<A, B> 151 where 152 A: FusedStream, 153 B: FusedStream<Item = A::Item>, 154 { is_terminated(&self) -> bool155 fn is_terminated(&self) -> bool { 156 match self { 157 Either::Left(x) => x.is_terminated(), 158 Either::Right(x) => x.is_terminated(), 159 } 160 } 161 } 162 163 #[cfg(feature = "sink")] 164 impl<A, B, Item> Sink<Item> for Either<A, B> 165 where 166 A: Sink<Item>, 167 B: Sink<Item, Error = A::Error>, 168 { 169 type Error = A::Error; 170 poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>171 fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 172 match self.as_pin_mut() { 173 Either::Left(x) => x.poll_ready(cx), 174 Either::Right(x) => x.poll_ready(cx), 175 } 176 } 177 start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error>178 fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { 179 match self.as_pin_mut() { 180 Either::Left(x) => x.start_send(item), 181 Either::Right(x) => x.start_send(item), 182 } 183 } 184 poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>185 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 186 match self.as_pin_mut() { 187 Either::Left(x) => x.poll_flush(cx), 188 Either::Right(x) => x.poll_flush(cx), 189 } 190 } 191 poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>192 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 193 match self.as_pin_mut() { 194 Either::Left(x) => x.poll_close(cx), 195 Either::Right(x) => x.poll_close(cx), 196 } 197 } 198 } 199 200 #[cfg(feature = "io")] 201 #[cfg(feature = "std")] 202 mod if_std { 203 use super::*; 204 205 use core::pin::Pin; 206 use core::task::{Context, Poll}; 207 use futures_io::{ 208 AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom, 209 }; 210 211 impl<A, B> AsyncRead for Either<A, B> 212 where 213 A: AsyncRead, 214 B: AsyncRead, 215 { poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize>>216 fn poll_read( 217 self: Pin<&mut Self>, 218 cx: &mut Context<'_>, 219 buf: &mut [u8], 220 ) -> Poll<Result<usize>> { 221 match self.as_pin_mut() { 222 Either::Left(x) => x.poll_read(cx, buf), 223 Either::Right(x) => x.poll_read(cx, buf), 224 } 225 } 226 poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll<Result<usize>>227 fn poll_read_vectored( 228 self: Pin<&mut Self>, 229 cx: &mut Context<'_>, 230 bufs: &mut [IoSliceMut<'_>], 231 ) -> Poll<Result<usize>> { 232 match self.as_pin_mut() { 233 Either::Left(x) => x.poll_read_vectored(cx, bufs), 234 Either::Right(x) => x.poll_read_vectored(cx, bufs), 235 } 236 } 237 } 238 239 impl<A, B> AsyncWrite for Either<A, B> 240 where 241 A: AsyncWrite, 242 B: AsyncWrite, 243 { poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>244 fn poll_write( 245 self: Pin<&mut Self>, 246 cx: &mut Context<'_>, 247 buf: &[u8], 248 ) -> Poll<Result<usize>> { 249 match self.as_pin_mut() { 250 Either::Left(x) => x.poll_write(cx, buf), 251 Either::Right(x) => x.poll_write(cx, buf), 252 } 253 } 254 poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize>>255 fn poll_write_vectored( 256 self: Pin<&mut Self>, 257 cx: &mut Context<'_>, 258 bufs: &[IoSlice<'_>], 259 ) -> Poll<Result<usize>> { 260 match self.as_pin_mut() { 261 Either::Left(x) => x.poll_write_vectored(cx, bufs), 262 Either::Right(x) => x.poll_write_vectored(cx, bufs), 263 } 264 } 265 poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>266 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> { 267 match self.as_pin_mut() { 268 Either::Left(x) => x.poll_flush(cx), 269 Either::Right(x) => x.poll_flush(cx), 270 } 271 } 272 poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>273 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> { 274 match self.as_pin_mut() { 275 Either::Left(x) => x.poll_close(cx), 276 Either::Right(x) => x.poll_close(cx), 277 } 278 } 279 } 280 281 impl<A, B> AsyncSeek for Either<A, B> 282 where 283 A: AsyncSeek, 284 B: AsyncSeek, 285 { poll_seek( self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom, ) -> Poll<Result<u64>>286 fn poll_seek( 287 self: Pin<&mut Self>, 288 cx: &mut Context<'_>, 289 pos: SeekFrom, 290 ) -> Poll<Result<u64>> { 291 match self.as_pin_mut() { 292 Either::Left(x) => x.poll_seek(cx, pos), 293 Either::Right(x) => x.poll_seek(cx, pos), 294 } 295 } 296 } 297 298 impl<A, B> AsyncBufRead for Either<A, B> 299 where 300 A: AsyncBufRead, 301 B: AsyncBufRead, 302 { poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>>303 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { 304 match self.as_pin_mut() { 305 Either::Left(x) => x.poll_fill_buf(cx), 306 Either::Right(x) => x.poll_fill_buf(cx), 307 } 308 } 309 consume(self: Pin<&mut Self>, amt: usize)310 fn consume(self: Pin<&mut Self>, amt: usize) { 311 match self.as_pin_mut() { 312 Either::Left(x) => x.consume(amt), 313 Either::Right(x) => x.consume(amt), 314 } 315 } 316 } 317 } 318