Skip to main content

futures_time/task/
sleep.rs

1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
5use pin_project_lite::pin_project;
6
7use crate::future::Timer;
8use crate::time::{Duration, Instant};
9
10#[cfg(feature = "web")]
11use crate::task::web_timer::Timer as AsyncTimer;
12#[cfg(not(feature = "web"))]
13use async_io::Timer as AsyncTimer;
14
15/// Sleeps for the specified amount of time.
16///
17/// This future can be `push_deadline` to be moved
18pub fn sleep(dur: Duration) -> Sleep {
19    Sleep {
20        dur,
21        timer: AsyncTimer::after(dur.into()),
22        completed: false,
23    }
24}
25
26pin_project! {
27    /// Sleeps for the specified amount of time.
28    #[must_use = "futures do nothing unless polled or .awaited"]
29    pub struct Sleep {
30        #[pin]
31        timer: AsyncTimer,
32        completed: bool,
33        dur: Duration,
34    }
35}
36
37impl Future for Sleep {
38    type Output = Instant;
39
40    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
41        assert!(!self.completed, "future polled after completing");
42        let this = self.project();
43        match this.timer.poll(cx) {
44            Poll::Ready(instant) => {
45                *this.completed = true;
46                Poll::Ready(instant.into())
47            }
48            Poll::Pending => Poll::Pending,
49        }
50    }
51}
52
53impl Timer for Sleep {
54    /// Resets the timer to be `Instant::now()` + `Duration` into the future.
55    fn reset_timer(self: std::pin::Pin<&mut Self>) {
56        let mut this = self.project();
57        this.timer.set_after((*this.dur).into());
58        *this.completed = false;
59    }
60}