use std::time::Duration;
use crate::{Clock, NodeState};
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub struct TimerOptions<'a> {
pub period: Duration,
pub clock: TimerClock<'a>,
}
impl TimerOptions<'_> {
pub fn new(period: Duration) -> Self {
Self {
period,
clock: TimerClock::default(),
}
}
}
pub trait IntoTimerOptions<'a>: Sized {
fn into_timer_options(self) -> TimerOptions<'a>;
fn steady_time(self) -> TimerOptions<'a> {
let mut options = self.into_timer_options();
options.clock = TimerClock::SteadyTime;
options
}
fn system_time(self) -> TimerOptions<'a> {
let mut options = self.into_timer_options();
options.clock = TimerClock::SystemTime;
options
}
fn node_time(self) -> TimerOptions<'a> {
let mut options = self.into_timer_options();
options.clock = TimerClock::NodeTime;
options
}
fn clock(self, clock: &'a Clock) -> TimerOptions<'a> {
let mut options = self.into_timer_options();
options.clock = TimerClock::Clock(clock);
options
}
}
#[derive(Debug, Default, Clone, Copy)]
pub enum TimerClock<'a> {
#[default]
SteadyTime,
SystemTime,
NodeTime,
Clock(&'a Clock),
}
impl TimerClock<'_> {
pub fn is_node_time(&self) -> bool {
matches!(self, Self::NodeTime)
}
pub(crate) fn as_clock(&self, node: &NodeState) -> Clock {
match self {
TimerClock::SteadyTime => Clock::steady(),
TimerClock::SystemTime => Clock::system(),
TimerClock::NodeTime => node.get_clock(),
TimerClock::Clock(clock) => (*clock).clone(),
}
}
}
impl<'a> IntoTimerOptions<'a> for TimerOptions<'a> {
fn into_timer_options(self) -> TimerOptions<'a> {
self
}
}
impl<'a> IntoTimerOptions<'a> for Duration {
fn into_timer_options(self) -> TimerOptions<'a> {
TimerOptions::new(self)
}
}