| 1 | //! Definition of the `Option` (optional step) combinator |
| 2 | |
| 3 | use core::pin::Pin; |
| 4 | use futures_core::future::{FusedFuture, Future}; |
| 5 | use futures_core::task::{Context, Poll}; |
| 6 | use pin_project_lite::pin_project; |
| 7 | |
| 8 | pin_project! { |
| 9 | /// A future representing a value which may or may not be present. |
| 10 | /// |
| 11 | /// Created by the [`From`] implementation for [`Option`](std::option::Option). |
| 12 | /// |
| 13 | /// # Examples |
| 14 | /// |
| 15 | /// ``` |
| 16 | /// # futures::executor::block_on(async { |
| 17 | /// use futures::future::OptionFuture; |
| 18 | /// |
| 19 | /// let mut a: OptionFuture<_> = Some(async { 123 }).into(); |
| 20 | /// assert_eq!(a.await, Some(123)); |
| 21 | /// |
| 22 | /// a = None.into(); |
| 23 | /// assert_eq!(a.await, None); |
| 24 | /// # }); |
| 25 | /// ``` |
| 26 | #[derive (Debug, Clone)] |
| 27 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
| 28 | pub struct OptionFuture<F> { |
| 29 | #[pin] |
| 30 | inner: Option<F>, |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | impl<F> Default for OptionFuture<F> { |
| 35 | fn default() -> Self { |
| 36 | Self { inner: None } |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | impl<F: Future> Future for OptionFuture<F> { |
| 41 | type Output = Option<F::Output>; |
| 42 | |
| 43 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 44 | match self.project().inner.as_pin_mut() { |
| 45 | Some(x: Pin<&mut F>) => x.poll(cx).map(Some), |
| 46 | None => Poll::Ready(None), |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | impl<F: FusedFuture> FusedFuture for OptionFuture<F> { |
| 52 | fn is_terminated(&self) -> bool { |
| 53 | match &self.inner { |
| 54 | Some(x: &F) => x.is_terminated(), |
| 55 | None => true, |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | impl<T> From<Option<T>> for OptionFuture<T> { |
| 61 | fn from(option: Option<T>) -> Self { |
| 62 | Self { inner: option } |
| 63 | } |
| 64 | } |
| 65 | |