use crate::SendSync;
use core::time::Duration;
pub trait Clock: SendSync {
fn now(&self) -> Duration;
}
#[cfg(feature = "std")]
mod standard {
use super::SendSync;
use core::time::Duration;
use std::time::SystemTime;
pub struct StandardClock();
impl SendSync for StandardClock {}
impl super::Clock for StandardClock {
fn now(&self) -> Duration {
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()
}
}
}
#[cfg(feature = "std")]
pub use standard::*;
mod manual {
use crate::prelude::*;
use alloc::sync::Arc;
use core::time::Duration;
pub struct ManualClock(Arc<Mutex<Duration>>);
impl SendSync for ManualClock {}
impl super::Clock for ManualClock {
fn now(&self) -> Duration {
self.0.lock().unwrap().clone()
}
}
impl ManualClock {
pub fn new(now: Duration) -> Self {
ManualClock(Arc::new(Mutex::new(now)))
}
pub fn set(&self, now: Duration) {
*self.0.lock().unwrap() = now;
}
}
}
pub use manual::*;
#[cfg(test)]
mod tests {
use super::*;
use std::thread::sleep;
use std::time::SystemTime;
#[test]
fn std_test() {
let clock = StandardClock();
clock.now();
}
#[test]
fn manual_test() {
let now1 = now();
let clock = ManualClock::new(now1);
let dur1 = clock.now();
sleep(Duration::from_millis(1));
let now2 = now();
assert_ne!(now1, now2);
clock.set(now2);
let dur2 = clock.now();
assert_ne!(dur1, dur2);
}
fn now() -> Duration {
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap()
}
}