use std::{
future::Future,
pin::Pin,
sync::Arc,
time::{Duration, Instant},
};
pub trait Timer {
fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>>;
fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>>;
fn now(&self) -> Instant {
Instant::now()
}
fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
*sleep = self.sleep_until(new_deadline);
}
}
pub trait Sleep: Send + Sync + Future<Output = ()> {
fn reset(self: Pin<&mut Self>, new_deadline: Instant);
}
#[derive(Clone)]
pub enum Time {
Timer(Arc<dyn Timer + Send + Sync>),
Empty,
}
impl Timer for Time {
fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
match *self {
Time::Empty => {
panic!("You must supply a timer.")
}
Time::Timer(ref t) => t.sleep(duration),
}
}
fn now(&self) -> Instant {
match *self {
Time::Empty => Instant::now(),
Time::Timer(ref t) => t.now(),
}
}
fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
match *self {
Time::Empty => {
panic!("You must supply a timer.")
}
Time::Timer(ref t) => t.sleep_until(deadline),
}
}
fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
match *self {
Time::Empty => {
panic!("You must supply a timer.")
}
Time::Timer(ref t) => t.reset(sleep, new_deadline),
}
}
}