1use std::time::{Duration, SystemTime};
2
3use async_trait::async_trait;
4
5pub trait Clock: Send + Sync {
6 fn current_timestamp(&self) -> u64;
7}
8
9#[async_trait]
10pub trait Sleeper: Send + Sync {
11 async fn sleep(&self, duration: Duration);
12}
13
14pub struct SystemClock(u64);
15
16impl SystemClock {
17 pub const fn default() -> Self {
18 Self(1)
19 }
20
21 pub const fn accelerated(scale: u64) -> Self {
22 Self(scale)
23 }
24}
25
26impl Clock for SystemClock {
27 fn current_timestamp(&self) -> u64 {
28 SystemTime::now()
29 .duration_since(SystemTime::UNIX_EPOCH)
30 .unwrap()
31 .as_secs()
32 * self.0
33 }
34}
35
36pub struct TokioSleeper(pub u32);
37
38impl TokioSleeper {
39 pub const fn default() -> Self {
40 Self(1)
41 }
42
43 pub const fn accelerated(scale: u32) -> Self {
44 Self(scale)
45 }
46}
47
48#[async_trait]
49impl Sleeper for TokioSleeper {
50 async fn sleep(&self, duration: Duration) {
51 tokio::time::sleep(duration / self.0).await
52 }
53}
54
55pub struct Insomniac;
56
57#[async_trait]
58impl Sleeper for Insomniac {
59 async fn sleep(&self, _duration: Duration) {}
60}