use std::sync::Arc;
use std::sync::atomic::{AtomicI64, Ordering};
pub type TimestampMs = i64;
pub trait Clock: Send + Sync {
fn now_ms(&self) -> TimestampMs;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct SystemClock;
impl Clock for SystemClock {
fn now_ms(&self) -> TimestampMs {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |d| d.as_millis() as TimestampMs)
}
}
#[derive(Debug, Default)]
pub struct ManualClock {
now: AtomicI64,
}
impl ManualClock {
pub fn new(now_ms: TimestampMs) -> Self {
Self {
now: AtomicI64::new(now_ms),
}
}
pub fn advance_ms(&self, delta_ms: i64) {
self.now.fetch_add(delta_ms, Ordering::SeqCst);
}
pub fn set_ms(&self, now_ms: TimestampMs) {
self.now.store(now_ms, Ordering::SeqCst);
}
}
impl Clock for ManualClock {
fn now_ms(&self) -> TimestampMs {
self.now.load(Ordering::SeqCst)
}
}
impl<C: Clock + ?Sized> Clock for Arc<C> {
fn now_ms(&self) -> TimestampMs {
(**self).now_ms()
}
}