use std::fmt;
use std::sync::Arc;
use chrono::DateTime;
use chrono::Utc;
pub trait Clock: Send + Sync {
fn now(&self) -> DateTime<Utc>;
}
impl<F> Clock for F
where
F: Fn() -> DateTime<Utc> + Send + Sync,
{
fn now(&self) -> DateTime<Utc> {
self()
}
}
impl<T: Clock + ?Sized> Clock for Arc<T> {
fn now(&self) -> DateTime<Utc> {
(**self).now()
}
}
impl fmt::Debug for dyn Clock {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Clock(..)")
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct SystemClock;
impl Clock for SystemClock {
fn now(&self) -> DateTime<Utc> {
Utc::now()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FixedClock(pub DateTime<Utc>);
impl Clock for FixedClock {
fn now(&self) -> DateTime<Utc> {
self.0
}
}
#[must_use]
pub fn default_clock() -> Arc<dyn Clock> {
Arc::new(SystemClock)
}