async_macros/
maybe_done.rs1use core::future::Future;
7use core::mem;
8use core::pin::Pin;
9
10use futures_core::ready;
11use futures_core::task::{Context, Poll};
12
13#[derive(Debug)]
15pub enum MaybeDone<Fut: Future> {
16 Future(Fut),
18 Done(Fut::Output),
20 Gone,
23}
24
25impl<Fut: Future> MaybeDone<Fut> {
26 pub fn new(future: Fut) -> MaybeDone<Fut> {
28 Self::Future(future)
29 }
30
31 #[inline]
36 pub fn output(self: Pin<&Self>) -> Option<&Fut::Output> {
37 let this = self.get_ref();
38 match this {
39 MaybeDone::Done(res) => Some(res),
40 _ => None,
41 }
42 }
43
44 #[inline]
49 pub fn output_mut(self: Pin<&mut Self>) -> Option<&mut Fut::Output> {
50 unsafe {
51 let this = self.get_unchecked_mut();
52 match this {
53 MaybeDone::Done(res) => Some(res),
54 _ => None,
55 }
56 }
57 }
58
59 #[inline]
62 pub fn take(self: Pin<&mut Self>) -> Option<Fut::Output> {
63 unsafe {
64 let this = self.get_unchecked_mut();
65 match this {
66 MaybeDone::Done(_) => {}
67 MaybeDone::Future(_) | MaybeDone::Gone => return None,
68 };
69 if let MaybeDone::Done(output) = mem::replace(this, MaybeDone::Gone) {
70 Some(output)
71 } else {
72 unreachable!()
73 }
74 }
75 }
76
77 }
79
80impl<Fut: Future> Future for MaybeDone<Fut> {
81 type Output = ();
82
83 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
84 let res = unsafe {
85 match Pin::as_mut(&mut self).get_unchecked_mut() {
86 MaybeDone::Future(a) => ready!(Pin::new_unchecked(a).poll(cx)),
87 MaybeDone::Done(_) => return Poll::Ready(()),
88 MaybeDone::Gone => panic!("MaybeDone polled after value taken"),
89 }
90 };
91 self.set(MaybeDone::Done(res));
92 Poll::Ready(())
93 }
94}