use {
serde::{Deserialize, Serialize},
std::time::{Duration, SystemTime, UNIX_EPOCH},
};
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct Timer(pub u64);
pub fn get_timer(name: &str) -> Timer {
get!(Timer(0)).get_timer(name)
}
impl Timer {
pub fn once(self, initial: Duration) {
get!().program_timer(self, Some(initial), None);
}
pub fn repeated(self, initial: Duration, period: Duration) {
get!().program_timer(self, Some(initial), Some(period));
}
pub fn cancel(self) {
get!().program_timer(self, None, None);
}
pub fn remove(self) {
get!().remove_timer(self);
}
pub fn on_tick<F: FnMut() + 'static>(self, f: F) {
get!().on_timer_tick(self, f);
}
}
pub fn duration_until_wall_clock_is_multiple_of(duration: Duration) -> Duration {
let now = match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(n) => n,
_ => return Duration::from_secs(0),
};
let now = now.as_nanos();
let duration = duration.as_nanos();
if duration == 0 {
return Duration::from_secs(0);
}
let nanos = duration - now % duration;
if nanos == duration {
Duration::from_secs(0)
} else {
Duration::from_nanos(nanos as _)
}
}