marque_engine/clock.rs
1// SPDX-FileCopyrightText: 2026 Knitli Inc.
2//
3// SPDX-License-Identifier: LicenseRef-MarqueLicense-1.0
4
5//! Clock abstraction for deterministic timestamps in audit records.
6//!
7//! `Engine` uses `dyn Clock` exclusively for `AppliedFix::timestamp`.
8//! Production code injects `SystemClock`; tests inject `FixedClock`
9//! so snapshot tests of audit NDJSON are deterministic.
10
11use std::time::SystemTime;
12
13/// Abstraction over `SystemTime::now()` for testability.
14pub trait Clock: Send + Sync {
15 fn now(&self) -> SystemTime;
16}
17
18/// Production clock — delegates to `SystemTime::now()`.
19pub struct SystemClock;
20
21impl Clock for SystemClock {
22 fn now(&self) -> SystemTime {
23 SystemTime::now()
24 }
25}
26
27/// Test clock — always returns the same instant.
28pub struct FixedClock(SystemTime);
29
30impl FixedClock {
31 /// Construct a fixed clock that always returns `instant`.
32 pub const fn new(instant: SystemTime) -> Self {
33 Self(instant)
34 }
35}
36
37impl Clock for FixedClock {
38 fn now(&self) -> SystemTime {
39 self.0
40 }
41}