zeppelin_embed/lifecycle/
clock.rs1use std::time::Instant;
4
5pub trait MonotonicClock: Send + Sync {
10 fn now(&self) -> Instant;
12}
13
14#[derive(Clone, Copy, Debug, Default)]
16pub struct SystemMonotonicClock;
17
18impl MonotonicClock for SystemMonotonicClock {
19 fn now(&self) -> Instant {
20 Instant::now()
21 }
22}
23
24#[cfg(any(test, feature = "test-seams"))]
26#[derive(Debug)]
27pub struct ManualMonotonicClock {
28 base: Instant,
29 offset: std::sync::Mutex<std::time::Duration>,
30}
31
32#[cfg(any(test, feature = "test-seams"))]
33impl ManualMonotonicClock {
34 #[must_use]
36 pub fn new() -> Self {
37 Self::starting_at(Instant::now())
38 }
39
40 #[must_use]
45 pub fn starting_at(base: Instant) -> Self {
46 Self {
47 base,
48 offset: std::sync::Mutex::new(std::time::Duration::ZERO),
49 }
50 }
51
52 pub fn advance(&self, duration: std::time::Duration) {
54 if let Ok(mut offset) = self.offset.lock() {
55 *offset = offset.saturating_add(duration);
56 }
57 }
58}
59
60#[cfg(any(test, feature = "test-seams"))]
61impl Default for ManualMonotonicClock {
62 fn default() -> Self {
63 Self::new()
64 }
65}
66
67#[cfg(any(test, feature = "test-seams"))]
68impl MonotonicClock for ManualMonotonicClock {
69 fn now(&self) -> Instant {
70 let offset = self
71 .offset
72 .lock()
73 .map_or(std::time::Duration::ZERO, |offset| *offset);
74 self.base.checked_add(offset).unwrap_or(self.base)
75 }
76}