use std::sync::atomic::{AtomicU64, Ordering};
pub trait Clock: Send + Sync {
fn now_micros(&self) -> u64;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct SystemClock;
impl Clock for SystemClock {
fn now_micros(&self) -> u64 {
iggy::prelude::IggyTimestamp::now().as_micros()
}
}
#[derive(Debug, Default)]
pub struct TestClock {
now_micros: AtomicU64,
}
impl TestClock {
pub fn new(start_micros: u64) -> Self {
Self {
now_micros: AtomicU64::new(start_micros),
}
}
pub fn advance(&self, by_micros: u64) {
self.now_micros.fetch_add(by_micros, Ordering::Relaxed);
}
pub fn set(&self, now_micros: u64) {
self.now_micros.store(now_micros, Ordering::Relaxed);
}
}
impl Clock for TestClock {
fn now_micros(&self) -> u64 {
self.now_micros.load(Ordering::Relaxed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn given_a_test_clock_when_advanced_then_should_report_the_set_time() {
let clock = TestClock::new(1_000);
assert_eq!(clock.now_micros(), 1_000);
clock.advance(500);
assert_eq!(clock.now_micros(), 1_500);
clock.set(42);
assert_eq!(clock.now_micros(), 42);
}
}