1use std::{
2 future::Future,
3 mem,
4 ops::{Deref, DerefMut},
5 pin::Pin,
6 task::{Context, Poll},
7};
8
9use futures_core::FusedFuture;
10use pin_project_lite::pin_project;
11
12pub type BoxOptionalFuture<T> = OptionalFuture<Pin<Box<dyn Future<Output = T> + Send + 'static>>>;
14
15pin_project! {
16 #[derive(Debug)]
19 #[must_use = "futures do nothing unless you `.await` or poll them"]
20 pub struct OptionalFuture<Fut> {
21 #[pin]
22 inner: Option<Fut>,
23 }
24}
25
26impl<Fut> OptionalFuture<Fut> {
27 pub fn replace(&mut self, value: Fut) -> Option<Fut> {
30 mem::replace(&mut self.inner, Some(value))
31 }
32
33 pub fn take(&mut self) -> Option<Fut> {
35 mem::take(&mut self.inner)
36 }
37
38 pub fn is_none(&self) -> bool {
40 self.inner.is_none()
41 }
42
43 pub fn is_some(&self) -> bool {
45 self.inner.is_some()
46 }
47
48 pub fn as_ref(&self) -> Option<&Fut> {
50 self.inner.as_ref()
51 }
52}
53
54impl<Fut> Default for OptionalFuture<Fut> {
56 fn default() -> Self {
57 Self { inner: None }
58 }
59}
60
61pub fn optional_future<Fut>(option: Option<Fut>) -> OptionalFuture<Fut>
63where
64 Fut: Future,
65{
66 OptionalFuture { inner: option }
67}
68
69impl<Fut> Future for OptionalFuture<Fut>
70where
71 Fut: Future,
72{
73 type Output = Fut::Output;
74
75 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
76 match self.project().inner.as_pin_mut() {
77 Some(inner) => inner.poll(cx),
78 None => Poll::Pending,
79 }
80 }
81}
82
83impl<Fut> FusedFuture for OptionalFuture<Fut>
84where
85 Fut: FusedFuture,
86{
87 fn is_terminated(&self) -> bool {
88 match &self.inner {
89 Some(inner) => inner.is_terminated(),
90 None => true, }
92 }
93}
94
95impl<Fut> From<Option<Fut>> for OptionalFuture<Fut> {
96 fn from(value: Option<Fut>) -> Self {
97 Self { inner: value }
98 }
99}
100
101impl<Fut> Clone for OptionalFuture<Fut>
102where
103 Fut: Clone,
104{
105 fn clone(&self) -> Self {
106 Self {
107 inner: self.inner.clone(),
108 }
109 }
110}
111
112impl<Fut> Deref for OptionalFuture<Fut> {
113 type Target = Option<Fut>;
114
115 fn deref(&self) -> &Self::Target {
116 &self.inner
117 }
118}
119
120impl<Fut> DerefMut for OptionalFuture<Fut> {
121 fn deref_mut(&mut self) -> &mut Self::Target {
122 &mut self.inner
123 }
124}