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> {
default() -> Self35     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 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>43     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
44         match self.project().inner.as_pin_mut() {
45             Some(x) => x.poll(cx).map(Some),
46             None => Poll::Ready(None),
47         }
48     }
49 }
50 
51 impl<F: FusedFuture> FusedFuture for OptionFuture<F> {
is_terminated(&self) -> bool52     fn is_terminated(&self) -> bool {
53         match &self.inner {
54             Some(x) => x.is_terminated(),
55             None => true,
56         }
57     }
58 }
59 
60 impl<T> From<Option<T>> for OptionFuture<T> {
from(option: Option<T>) -> Self61     fn from(option: Option<T>) -> Self {
62         Self { inner: option }
63     }
64 }
65