rama_utils/
future.rs

1//! future utils
2//!
3//! usually because missing or out of scope from futures-lite
4
5use pin_project_lite::pin_project;
6use std::{
7    fmt,
8    pin::Pin,
9    task::{Context, Poll},
10};
11
12pin_project! {
13    /// Future for the [`fuse`](super::FutureExt::fuse) method.
14    #[must_use = "futures do nothing unless polled"]
15    pub struct Fuse<Fut: Future> {
16        #[pin]
17        future: Option<Fut>,
18    }
19}
20
21impl<Fut: Future + fmt::Debug> fmt::Debug for Fuse<Fut> {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        f.debug_struct("Fuse")
24            .field("future", &self.future)
25            .finish()
26    }
27}
28
29impl<Fut: Future> Fuse<Fut> {
30    /// Create a new [`Fuse`].
31    pub fn new(future: Fut) -> Self {
32        Self {
33            future: Some(future),
34        }
35    }
36}
37
38impl<Fut: Future> Future for Fuse<Fut> {
39    type Output = Fut::Output;
40
41    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Fut::Output> {
42        match self.as_mut().project().future.as_pin_mut() {
43            Some(fut) => fut.poll(cx).map(|output| {
44                self.project().future.set(None);
45                output
46            }),
47            None => Poll::Pending,
48        }
49    }
50}