Skip to main content

qubit_clock/
lib.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8#![cfg_attr(docsrs, feature(doc_cfg))]
9//! Injectable wall clocks, monotonic clocks, and deterministic timers.
10//!
11//! Wall time and monotonic time are deliberately separate. Long-lived
12//! services can inject [`WallClock`] for business timestamps, while timeout
13//! and delay code injects [`MonotonicClock`] or [`Timer`]. A
14//! [`BlockingSleeper`] can adapt the same timer when synchronous code must
15//! block, provided the timer backend can progress while the calling thread is
16//! parked. Manual implementations allow tests to advance logical time without
17//! waiting for real time to pass.
18//!
19//! # Examples
20//!
21//! A manual timer can drive a blocking sleep without waiting for real time:
22//!
23//! ```
24//! use qubit_clock::{
25//!     BlockingSleeper, ManualMonotonicClock, MonotonicClock,
26//! };
27//! use std::time::Duration;
28//!
29//! let clock = ManualMonotonicClock::new_shared();
30//! let sleeper = BlockingSleeper::new(clock.new_timer());
31//! let worker = std::thread::spawn(move || {
32//!     sleeper
33//!         .sleep_for(Duration::from_secs(5))
34//!         .expect("manual sleep should complete");
35//! });
36//!
37//! assert!(clock.wait_for_waiters(1, Duration::from_secs(1)));
38//! clock
39//!     .advance(Duration::from_secs(5))
40//!     .expect("manual time should advance");
41//! worker.join().expect("sleeping thread should finish");
42//! ```
43
44pub(crate) mod internal;
45
46pub mod error;
47pub mod monotonic;
48pub mod sleep;
49#[cfg(feature = "test-util")]
50#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
51pub mod test_util;
52pub mod timer;
53pub mod wall;
54
55pub use error::TimeError;
56pub use error::TimerUnavailableError;
57#[cfg(feature = "tokio")]
58pub use error::TokioRuntimeError;
59pub use monotonic::ClockDomain;
60pub use monotonic::ManualDeadlineFuture;
61pub use monotonic::ManualMonotonicClock;
62pub use monotonic::ManualWaiterFuture;
63pub use monotonic::MonotonicClock;
64pub use monotonic::MonotonicInstant;
65pub use monotonic::StdMonotonicClock;
66#[cfg(feature = "tokio")]
67pub use monotonic::TokioMonotonicClock;
68pub use sleep::BlockingSleeper;
69pub use timer::ManualTimer;
70pub use timer::StdTimer;
71pub use timer::Timer;
72pub use timer::TimerFuture;
73#[cfg(feature = "tokio")]
74pub use timer::TokioTimer;
75// qubit-style: allow coverage-cfg
76#[doc(hidden)]
77#[cfg(coverage)]
78pub use timer::internal::std_timer_scheduler::fail_next_std_timer_worker_spawn;
79#[doc(hidden)]
80#[cfg(coverage)]
81pub use timer::internal::std_timer_scheduler::panic_next_std_timer_worker;
82#[doc(hidden)]
83#[cfg(coverage)]
84pub use timer::internal::std_timer_scheduler::reset_std_timer_worker_notification_count;
85#[doc(hidden)]
86#[cfg(coverage)]
87pub use timer::internal::std_timer_scheduler::std_timer_worker_notification_count;
88#[doc(hidden)]
89#[cfg(all(coverage, feature = "tokio"))]
90pub use timer::panic_next_tokio_timer_sleep_poll;
91pub use wall::FixedWallClock;
92pub use wall::ManualWallClock;
93pub use wall::StdWallClock;
94pub use wall::WallClock;