use std::time::{SystemTime, UNIX_EPOCH};
use sim_kernel::{Error, Result};
pub trait GatewayClock {
fn now_ms(&mut self) -> Result<u64>;
}
#[derive(Clone, Copy, Debug, Default)]
pub struct SystemGatewayClock;
impl GatewayClock for SystemGatewayClock {
fn now_ms(&mut self) -> Result<u64> {
let duration = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|err| Error::Eval(format!("system clock is before UNIX_EPOCH: {err}")))?;
u64::try_from(duration.as_millis())
.map_err(|_| Error::Eval("system timestamp exceeds u64 milliseconds".to_owned()))
}
}
#[derive(Clone, Debug)]
pub struct DeterministicGatewayClock {
next_ms: u64,
step_ms: u64,
}
impl DeterministicGatewayClock {
pub fn new(start_ms: u64, step_ms: u64) -> Self {
Self {
next_ms: start_ms,
step_ms,
}
}
}
impl GatewayClock for DeterministicGatewayClock {
fn now_ms(&mut self) -> Result<u64> {
let now = self.next_ms;
self.next_ms = self
.next_ms
.checked_add(self.step_ms)
.ok_or_else(|| Error::Eval("deterministic gateway clock overflow".to_owned()))?;
Ok(now)
}
}