qubit_clock/lib.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! Thread-safe clock abstractions for Rust.
11//!
12//! This crate provides a flexible and type-safe clock abstraction system with
13//! support for:
14//!
15//! - **Basic time access**: Get current UTC time
16//! - **High precision**: Nanosecond-level time measurements
17//! - **Timezone support**: Convert to local time in any timezone
18//! - **Monotonic time**: Time that never goes backwards
19//! - **Testing support**: Controllable mock clocks for tests
20//!
21//! # Architecture
22//!
23//! The crate is built around several orthogonal traits:
24//!
25//! - [`Clock`]: Base trait providing UTC time
26//! - [`NanoClock`]: Extension for nanosecond precision
27//! - [`ZonedClock`]: Extension for timezone support
28//! - [`ControllableClock`]: Extension for time control (testing)
29//!
30//! # Implementations
31//!
32//! Several clock implementations are provided:
33//!
34//! - [`SystemClock`]: Uses system wall clock time
35//! - [`MonotonicClock`]: Monotonic time (unaffected by system time changes)
36//! - [`NanoMonotonicClock`]: Monotonic time with nanosecond precision
37//! - [`MockClock`]: Controllable clock for testing
38//! - [`MockNanoClock`]: Nanosecond-precision controllable clock for testing
39//! - [`MockClockProgression`]: Frozen or monotonic mock-clock progression mode
40//! - [`Zoned<C>`](Zoned): Wrapper that adds timezone support to any clock
41//!
42//! # Examples
43//!
44//! ## Basic Usage
45//!
46//! ```
47//! use qubit_clock::{Clock, SystemClock};
48//!
49//! let clock = SystemClock::new();
50//! let timestamp = clock.millis();
51//! let time = clock.time();
52//! println!("Current time: {}", time);
53//! ```
54//!
55//! ## With Timezone
56//!
57//! ```
58//! use qubit_clock::{Clock, ZonedClock, SystemClock, Zoned};
59//! use chrono_tz::Asia::Shanghai;
60//!
61//! let clock = Zoned::new(SystemClock::new(), Shanghai);
62//! let local = clock.local_time();
63//! println!("Local time in Shanghai: {}", local);
64//! ```
65//!
66//! ## Monotonic Time for Performance Measurement
67//!
68//! ```
69//! use qubit_clock::{Clock, MonotonicClock};
70//! use std::thread;
71//! use std::time::Duration;
72//!
73//! let clock = MonotonicClock::new();
74//! let start = clock.millis();
75//!
76//! thread::sleep(Duration::from_millis(100));
77//!
78//! let elapsed = clock.millis() - start;
79//! println!("Elapsed: {} ms", elapsed);
80//! ```
81//!
82//! ## Testing with MockClock
83//!
84//! ```
85//! use qubit_clock::{Clock, ControllableClock, MockClock};
86//! use chrono::{DateTime, Duration, Utc};
87//!
88//! let clock = MockClock::new();
89//!
90//! // Set to a specific time
91//! let fixed_time = DateTime::parse_from_rfc3339(
92//! "2024-01-01T00:00:00Z"
93//! ).unwrap().with_timezone(&Utc);
94//! clock.set_time(fixed_time);
95//!
96//! assert_eq!(clock.time(), fixed_time);
97//!
98//! // Advance time
99//! clock.add_duration(Duration::hours(1));
100//! assert_eq!(clock.time(), fixed_time + Duration::hours(1));
101//! ```
102//!
103//! ## High-Precision Measurements
104//!
105//! ```
106//! use qubit_clock::{NanoClock, NanoMonotonicClock};
107//!
108//! let clock = NanoMonotonicClock::new();
109//! let start = clock.nanos();
110//!
111//! // Perform some operation
112//! for _ in 0..1000 {
113//! // Some work
114//! }
115//!
116//! let elapsed = clock.nanos() - start;
117//! println!("Elapsed: {} ns", elapsed);
118//! ```
119//!
120//! ## Time Meters for Elapsed Time Measurement
121//!
122//! ```
123//! use qubit_clock::meter::TimeMeter;
124//! use std::thread;
125//! use std::time::Duration;
126//!
127//! let mut meter = TimeMeter::new();
128//! meter.start();
129//! thread::sleep(Duration::from_millis(100));
130//! meter.stop();
131//! println!("Elapsed: {}", meter.readable_duration());
132//! ```
133//!
134//! # Design Principles
135//!
136//! - **Interface Segregation**: Don't force implementations to provide
137//! features they don't need
138//! - **Single Responsibility**: Each trait and type has one clear purpose
139//! - **Composition over Inheritance**: Extend functionality through wrappers
140//! - **Zero-Cost Abstractions**: Pay only for what you use
141//!
142
143// Re-export chrono types for convenience
144pub use chrono::{
145 DateTime,
146 Duration,
147 Utc,
148};
149pub use chrono_tz::Tz;
150
151// Traits
152mod clock;
153mod controllable_clock;
154mod nano_clock;
155mod zoned_clock;
156
157pub use clock::Clock;
158pub use controllable_clock::ControllableClock;
159pub use nano_clock::NanoClock;
160pub use zoned_clock::ZonedClock;
161
162// Implementations
163mod mock_clock;
164mod mock_clock_progression;
165mod mock_nano_clock;
166mod monotonic_clock;
167mod nano_monotonic_clock;
168mod system_clock;
169mod zoned;
170
171pub use mock_clock::MockClock;
172pub use mock_clock_progression::MockClockProgression;
173pub use mock_nano_clock::MockNanoClock;
174pub use monotonic_clock::MonotonicClock;
175pub use nano_monotonic_clock::NanoMonotonicClock;
176pub use system_clock::SystemClock;
177pub use zoned::Zoned;
178
179// Time meters
180pub mod meter;