use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
time::Duration,
};
#[derive(Debug)]
pub struct DurationSleep {
start_time: Option<Duration>,
duration: Duration,
time_fn: fn() -> Duration,
}
impl DurationSleep {
pub fn new(duration: Duration, time_fn: fn() -> Duration) -> Self {
DurationSleep {
start_time: None,
duration,
time_fn,
}
}
}
impl Future for DurationSleep {
type Output = ();
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
let current_time = (self.time_fn)();
let start_time = match self.start_time {
Some(time) => time,
None => {
self.as_mut().start_time = Some(current_time);
current_time
}
};
if self.duration == Duration::ZERO {
return Poll::Ready(());
}
let elapsed = current_time.saturating_sub(start_time);
if elapsed >= self.duration {
Poll::Ready(())
} else {
Poll::Pending
}
}
}
pub fn sleep(duration: Duration, time_fn: fn() -> Duration) -> DurationSleep {
DurationSleep::new(duration, time_fn)
}