futures_time/task/
sleep.rs

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