Skip to main content

mockforge_foundation/
clock.rs

1//! Pluggable clock — foundation's `now()` defaults to `Utc::now()` but can be
2//! overridden (e.g., by `mockforge-core::time_travel`) via `set_clock`.
3//!
4//! This allows foundation types like `SessionState` to respect time travel
5//! without depending on `mockforge-core`.
6
7use chrono::{DateTime, Utc};
8use std::sync::OnceLock;
9
10/// Type alias for a clock function (returns the current time).
11pub type ClockFn = fn() -> DateTime<Utc>;
12
13static CLOCK: OnceLock<ClockFn> = OnceLock::new();
14
15/// Returns the current time. Uses the registered clock function if any,
16/// otherwise falls back to real wall-clock time (`Utc::now()`).
17pub fn now() -> DateTime<Utc> {
18    if let Some(clock) = CLOCK.get() {
19        clock()
20    } else {
21        Utc::now()
22    }
23}
24
25/// Register a custom clock function. Can only be called once per process;
26/// subsequent calls are silently ignored (returns `Err` if already set).
27///
28/// This is intended for `mockforge-core::time_travel` to register its virtual
29/// clock once at startup.
30pub fn set_clock(clock: ClockFn) -> Result<(), ClockFn> {
31    CLOCK.set(clock)
32}