Skip to main content

clock_kit/
clock.rs

1//! The estate time idiom: [`Clock`] — and the chronoshift bridge.
2//!
3//! clock-kit does **not** mint a rival time abstraction (spec §Decisions #1,
4//! recommended resolution): chronoshift (L0) owns time *abstraction*,
5//! clock-kit owns time *precision and cost*. With the `chronoshift` feature
6//! a blanket impl makes every `chronoshift::Clock` a clock-kit [`Clock`],
7//! bridging `now_ns()` into a full [`Timestamp`] with the monotonic floor
8//! applied.
9
10#[cfg(feature = "chronoshift")]
11use crate::monotonic::mono_floor;
12use crate::quality::{ClockSource, SyncQuality};
13use crate::timestamp::Timestamp;
14#[cfg(feature = "chronoshift")]
15use crate::timestamp::WallTime;
16
17/// A time source producing wall+monotonic [`Timestamp`]s.
18///
19/// Object-safe; all implementations enforce REQ-CLK-001 by construction
20/// (`mono` passes through a process-wide floor). Two advisory accessors
21/// make cost and trust observable instead of guessed.
22///
23/// REQ-CLK-001, REQ-CLK-004.
24pub trait Clock {
25    /// Current reading. `t.mono` never decreases across calls within a
26    /// process, even if the underlying source regresses. REQ-CLK-001.
27    fn now(&self) -> Timestamp;
28
29    /// Advisory sync quality of the underlying source (G2 — a hint, never a
30    /// guarantee). REQ-CLK-004.
31    fn quality(&self) -> SyncQuality;
32
33    /// Which underlying source reads are actually served from. REQ-CLK-003.
34    fn source(&self) -> ClockSource;
35}
36
37#[cfg(feature = "chronoshift")]
38impl<T: chronoshift::Clock> Clock for T {
39    fn now(&self) -> Timestamp {
40        let ns = chronoshift::Clock::now_ns(self);
41        // Bridge is lossy at the edges, documented: chronoshift nanos are
42        // i64 (signed, wall scale). Negative (pre-epoch) clamps to 0 for
43        // both fields; monotonic passes through the process-wide floor so
44        // even a regressing bridged source honors REQ-CLK-001.
45        let wall = u64::try_from(ns).unwrap_or(0);
46        Timestamp {
47            wall: WallTime::from_unix_nanos(wall),
48            mono: mono_floor(wall),
49        }
50    }
51
52    fn quality(&self) -> SyncQuality {
53        // The bridge cannot know how the foreign clock is disciplined;
54        // fail-closed to distrust (G2).
55        SyncQuality::Fallback
56    }
57
58    fn source(&self) -> ClockSource {
59        ClockSource::External
60    }
61}