1use std::ops::{Add, Sub};
9use std::sync::Arc;
10use std::time::Duration;
11use tokio::time::Instant;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15pub struct Timestamp(Instant);
16
17impl Timestamp {
18 pub fn duration_since(&self, earlier: Timestamp) -> Duration {
20 self.0
21 .checked_duration_since(earlier.0)
22 .unwrap_or_else(|| Duration::from_secs(0))
23 }
24
25 pub fn now() -> Self {
27 Timestamp(Instant::now())
28 }
29}
30
31impl Add<Duration> for Timestamp {
32 type Output = Timestamp;
33
34 fn add(self, duration: Duration) -> Self::Output {
35 Timestamp(self.0 + duration)
36 }
37}
38
39impl Sub<Duration> for Timestamp {
40 type Output = Timestamp;
41
42 fn sub(self, duration: Duration) -> Self::Output {
43 Timestamp(self.0 - duration)
44 }
45}
46
47pub trait Time: Send + Sync {
49 fn now(&self) -> Timestamp;
51}
52
53impl<T: Time> Time for Arc<T>
54where
55 T: Time,
56{
57 fn now(&self) -> Timestamp {
58 <T as Time>::now(self)
59 }
60}
61
62impl<T: Time> Time for Box<T>
63where
64 T: Time,
65{
66 fn now(&self) -> Timestamp {
67 <T as Time>::now(self)
68 }
69}
70
71impl<T: Time> Time for &T
72where
73 T: Time,
74{
75 fn now(&self) -> Timestamp {
76 <T as Time>::now(self)
77 }
78}
79
80#[derive(Debug, Clone, Copy)]
82pub struct TokioTime {
83 base_instant: Instant,
84 base_timestamp: Timestamp,
85}
86
87impl TokioTime {
88 pub fn new() -> Self {
90 let base_instant = tokio::time::Instant::now();
91 let base_timestamp = Timestamp::now(); Self {
94 base_instant,
95 base_timestamp,
96 }
97 }
98}
99
100impl Default for TokioTime {
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106impl Time for TokioTime {
107 fn now(&self) -> Timestamp {
108 let now = Instant::now();
109 let elapsed = now.duration_since(self.base_instant);
110 self.base_timestamp + elapsed
111 }
112}