1use futures::{Future, FutureExt};
4use std::{
5 pin::Pin,
6 task::{Context, Poll},
7 time::Duration,
8};
9use zduny_wasm_timer::Delay;
10pub use zduny_wasm_timer::Instant;
11
12#[must_use]
16pub fn sleep(duration: Duration) -> Sleep {
17 sleep_until(Instant::now() + duration)
18}
19
20#[must_use]
22pub fn sleep_until(deadline: Instant) -> Sleep {
23 Sleep {
24 deadline,
25 delay: Delay::new_at(deadline),
26 }
27}
28
29#[derive(Debug)]
31pub struct Sleep {
32 deadline: Instant,
33 delay: Delay,
34}
35
36impl Sleep {
37 pub fn deadline(&self) -> Instant {
39 self.deadline
40 }
41
42 pub fn is_elapsed(&self) -> bool {
46 Instant::now() > self.deadline
47 }
48
49 pub fn reset(&mut self, deadline: Instant) {
57 self.delay.reset_at(deadline);
58 }
59}
60
61impl Future for Sleep {
62 type Output = ();
63
64 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
65 match self.delay.poll_unpin(cx) {
66 Poll::Ready(_) => Poll::Ready(()),
67 Poll::Pending => Poll::Pending,
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use std::time::Duration;
75 use wasm_bindgen_test::wasm_bindgen_test;
76
77 use crate::{sleep, sleep::Instant};
78
79 #[wasm_bindgen_test]
80 async fn test_sleep() {
81 let current = Instant::now();
82 sleep(Duration::from_secs(1)).await;
83 let difference = Instant::now() - current;
84 assert!(difference.as_secs_f64() >= 1.0)
85 }
86}