use std::fmt::Debug;
use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
pub trait TimeSource: Debug + Send + Sync {
fn now(&self) -> SystemTime;
}
#[non_exhaustive]
#[derive(Debug, Default)]
pub struct SystemTimeSource;
impl SystemTimeSource {
pub fn new() -> Self {
SystemTimeSource
}
}
impl TimeSource for SystemTimeSource {
fn now(&self) -> SystemTime {
#[allow(clippy::disallowed_methods)]
SystemTime::now()
}
}
impl Default for SharedTimeSource {
fn default() -> Self {
SharedTimeSource(Arc::new(SystemTimeSource))
}
}
#[derive(Debug)]
pub struct StaticTimeSource {
time: SystemTime,
}
impl StaticTimeSource {
pub fn new(time: SystemTime) -> Self {
Self { time }
}
pub fn from_secs(epoch_secs: u64) -> Self {
Self::new(UNIX_EPOCH + Duration::from_secs(epoch_secs))
}
}
impl TimeSource for StaticTimeSource {
fn now(&self) -> SystemTime {
self.time
}
}
impl From<StaticTimeSource> for SharedTimeSource {
fn from(value: StaticTimeSource) -> Self {
SharedTimeSource::new(value)
}
}
#[derive(Debug, Clone)]
pub struct SharedTimeSource(Arc<dyn TimeSource>);
impl SharedTimeSource {
pub fn now(&self) -> SystemTime {
self.0.now()
}
pub fn new(source: impl TimeSource + 'static) -> Self {
Self(Arc::new(source))
}
}
impl TimeSource for SharedTimeSource {
fn now(&self) -> SystemTime {
self.0.now()
}
}