use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use async_trait::async_trait;
#[async_trait]
pub trait Clock: Send + Sync + std::fmt::Debug {
fn now(&self) -> Instant;
fn timestamp_ms(&self) -> u64;
fn timestamp_rfc3339(&self) -> String;
fn timestamp_datetime(&self) -> chrono::DateTime<chrono::Utc>;
async fn sleep(&self, duration: Duration);
async fn sleep_until(&self, deadline: Instant);
}
#[derive(Debug, Default, Clone, Copy)]
pub struct SystemClock;
#[async_trait]
impl Clock for SystemClock {
fn now(&self) -> Instant {
Instant::now()
}
fn timestamp_ms(&self) -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
fn timestamp_rfc3339(&self) -> String {
self.timestamp_datetime().to_rfc3339()
}
fn timestamp_datetime(&self) -> chrono::DateTime<chrono::Utc> {
chrono::Utc::now()
}
async fn sleep(&self, duration: Duration) {
tokio::time::sleep(duration).await;
}
async fn sleep_until(&self, deadline: Instant) {
tokio::time::sleep_until(tokio::time::Instant::from_std(deadline)).await;
}
}