1use std::time::{Duration, Instant};
2
3#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
5pub struct ClockInstant {
6 nanos_since_origin: u128,
7}
8
9impl ClockInstant {
10 pub fn from_duration_since_origin(duration: Duration) -> Self {
12 Self {
13 nanos_since_origin: duration.as_nanos(),
14 }
15 }
16
17 pub(crate) fn saturating_add_duration(self, duration: Duration) -> Self {
18 Self {
19 nanos_since_origin: self.nanos_since_origin.saturating_add(duration.as_nanos()),
20 }
21 }
22
23 pub(crate) fn saturating_duration_since(self, earlier: Self) -> Duration {
24 let nanos = self
25 .nanos_since_origin
26 .saturating_sub(earlier.nanos_since_origin);
27 Duration::from_nanos(nanos.min(u64::MAX.into()) as u64)
28 }
29}
30
31pub trait Clock: Send + Sync + 'static {
33 fn now(&self) -> ClockInstant;
35}
36
37#[derive(Clone, Debug)]
39pub struct SystemClock {
40 origin: Instant,
41}
42
43impl SystemClock {
44 pub fn new() -> Self {
46 Self {
47 origin: Instant::now(),
48 }
49 }
50}
51
52impl Default for SystemClock {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58impl Clock for SystemClock {
59 fn now(&self) -> ClockInstant {
60 ClockInstant::from_duration_since_origin(self.origin.elapsed())
61 }
62}