use std::sync::Mutex;
use time::{Duration, OffsetDateTime};
use super::Timestamp;
pub trait Clock: Send + Sync {
fn now(&self) -> Timestamp;
fn now_datetime(&self) -> OffsetDateTime {
self.now().into_offset_datetime()
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct SystemClock;
impl Clock for SystemClock {
fn now(&self) -> Timestamp {
Timestamp::now()
}
}
#[derive(Debug)]
pub struct FixedClock {
now: Mutex<Timestamp>,
}
impl FixedClock {
pub fn new(at: Timestamp) -> Self {
Self { now: Mutex::new(at) }
}
pub fn at_unix_millis(millis: i64) -> Self {
Self::new(Timestamp::from_unix_millis(millis))
}
pub fn set(&self, at: Timestamp) {
*self.now.lock().unwrap_or_else(std::sync::PoisonError::into_inner) = at;
}
#[allow(
clippy::expect_used,
reason = "advancing this fixed test clock past the representable range is a caller error"
)]
pub fn advance(&self, delta: Duration) {
let mut guard = self.now.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
*guard =
guard.checked_add(delta).expect("clock advance overflowed the representable range");
}
}
impl Clock for FixedClock {
fn now(&self) -> Timestamp {
*self.now.lock().unwrap_or_else(std::sync::PoisonError::into_inner)
}
}