futures_time/future/
delay.rs

1use futures_core::ready;
2use std::future::Future;
3use std::pin::Pin;
4use std::task::{Context, Poll};
5
6use pin_project_lite::pin_project;
7
8pin_project! {
9    /// Suspends a future until the specified deadline.
10    ///
11    /// This `struct` is created by the [`delay`] method on [`FutureExt`]. See its
12    /// documentation for more.
13    ///
14    /// [`delay`]: crate::future::FutureExt::delay
15    /// [`FutureExt`]: crate::future::futureExt
16    #[must_use = "futures do nothing unless polled or .awaited"]
17    pub struct Delay<F, D> {
18        #[pin]
19        future: F,
20        #[pin]
21        deadline: D,
22        state: State,
23    }
24}
25
26/// The internal state
27#[derive(Debug)]
28enum State {
29    Started,
30    PollFuture,
31    Completed,
32}
33
34impl<F, D> Delay<F, D> {
35    pub(super) fn new(future: F, deadline: D) -> Self {
36        Self {
37            future,
38            deadline,
39            state: State::Started,
40        }
41    }
42}
43
44impl<F: Future, D: Future> Future for Delay<F, D> {
45    type Output = F::Output;
46
47    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
48        let mut this = self.project();
49        loop {
50            match this.state {
51                State::Started => {
52                    ready!(this.deadline.as_mut().poll(cx));
53                    *this.state = State::PollFuture;
54                }
55                State::PollFuture => {
56                    let value = ready!(this.future.as_mut().poll(cx));
57                    *this.state = State::Completed;
58                    return Poll::Ready(value);
59                }
60                State::Completed => panic!("future polled after completing"),
61            }
62        }
63    }
64}