https://github.com/jamesgober/clock-lib
Monotonic and wall-clock time readings for Rust, with a mockable clock for deterministic testing. Simple Tier-1 API, zero dependencies, no unsafe. REPS-compliant.
https://github.com/jamesgober/clock-lib
clock mock monotonic reps rust testing time timekeeping
Last synced: about 18 hours ago
JSON representation
Monotonic and wall-clock time readings for Rust, with a mockable clock for deterministic testing. Simple Tier-1 API, zero dependencies, no unsafe. REPS-compliant.
- Host: GitHub
- URL: https://github.com/jamesgober/clock-lib
- Owner: jamesgober
- License: apache-2.0
- Created: 2026-05-21T06:26:39.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-21T09:45:57.000Z (about 2 months ago)
- Last Synced: 2026-05-21T15:49:46.880Z (about 2 months ago)
- Topics: clock, mock, monotonic, reps, rust, testing, time, timekeeping
- Language: Rust
- Size: 119 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
clock-lib
RUST TIME LIBRARY
Monotonic & Wall-Clock Time, Done Right
Simple, fast, zero-dependency time readings with a mockable clock for deterministic testing
clock-lib provides clean, correct access to the two kinds of time every program needs: monotonic time for measuring durations, and wall-clock time for timestamps. It draws a hard line between them at the API level, so you can never accidentally measure elapsed time with a clock that jumps backwards during an NTP sync.
The headline feature is the mockable clock. In production, time comes from the operating system. In tests, you inject a ManualClock and advance time instantly — no sleep, no flaky timing, fully deterministic. Every time-driven system built on clock-lib (rate limiters, TTL caches, timeouts, schedulers) becomes trivially testable.
Built for performance and correctness: a one-line Tier-1 API for the common case, zero runtime dependencies, #![forbid(unsafe_code)] at the crate root, and no_std-compatible builds. clock-lib wraps std::time with a thin, well-inlined layer that benchmarks at zero overhead — you pay the syscall cost and nothing more.
## Features
### Two Kinds of Time, Clearly Separated
- **Monotonic readings** — for measuring elapsed time; never goes backwards
- **Wall-clock readings** — for timestamps and calendar time
- **Type-level separation** — the API makes it impossible to subtract a wall-clock time from a monotonic one
### Mockable Clock (the killer feature)
- **`SystemClock`** — reads the OS in production
- **`ManualClock`** — advance time instantly in tests, fully deterministic
- **`Clock` trait** — inject time into any system for testability
### Simple Tier-1 API
- **`now()`** — monotonic reading
- **`elapsed(earlier)`** — duration since a monotonic reading
- **`wall()`** — wall-clock reading
- **`unix()` / `unix_ms()` / `unix_ns()`** — unix time conveniences
### Lean & Correct
- **Zero runtime dependencies** — wraps `std::time`
- **`#![forbid(unsafe_code)]`** — enforced by the compiler
- **`no_std`-compatible** — the crate builds against bare-metal targets with `default-features = false`
- **Cross-platform** — Linux, macOS, Windows
> This crate deliberately does **not** do calendar math, date formatting, or timezones. For that, use [`chrono`](https://crates.io/crates/chrono) or [`time`](https://crates.io/crates/time). clock-lib is the lean primitive layer beneath them.
## Installation
```toml
[dependencies]
clock-lib = "1.0"
```
For `no_std` builds, opt out of the default `std` feature:
```toml
[dependencies]
clock-lib = { version = "1.0", default-features = false }
```
In `no_std` mode, only the `VERSION` constant is exposed — the reading APIs all require an OS clock and are gated behind the `std` feature. This is the honest cost of a portable clock library: the readings themselves are platform-specific.
## Quick Start
```rust
use clock_lib as clock;
// Measure elapsed time (monotonic — safe)
let start = clock::now();
// ... do work ...
let took = clock::elapsed(start);
// Get a timestamp (wall-clock)
let unix_seconds = clock::unix();
```
Reach for the typed surface when you need it — [`Monotonic`](https://docs.rs/clock-lib/latest/clock_lib/struct.Monotonic.html) for elapsed-time math, [`Wall`](https://docs.rs/clock-lib/latest/clock_lib/struct.Wall.html) for timestamps. The compiler refuses to mix the two, so you cannot accidentally measure an interval with a clock that can step backwards.
### Deterministic Time in Tests
```rust
use clock_lib::{Clock, ManualClock, Monotonic};
use std::time::Duration;
fn expired(clock: &C, stamp: Monotonic, ttl: Duration) -> bool {
clock.now().duration_since(stamp) >= ttl
}
let clock = ManualClock::new();
let stamp = clock.now();
assert!(!expired(&clock, stamp, Duration::from_secs(60)));
clock.advance(Duration::from_secs(60)); // instant, no sleep
assert!(expired(&clock, stamp, Duration::from_secs(60)));
```
Inject [`Clock`](https://docs.rs/clock-lib/latest/clock_lib/trait.Clock.html) into anything time-driven (rate limiters, TTL caches, timeouts) and your test suite drops every `thread::sleep` it had.
## Documentation
- [API reference](docs/API.md) — every public type, trait, and function with examples.
- [Performance](docs/PERFORMANCE.md) — benchmark methodology and the zero-overhead claim, verified.
- [Developer guidelines](docs/GUIDELINES.md) — the engineering bar this project is built to.
- [Release notes](docs/release/) — what shipped, when, and why.
## Contributing
Contributions are welcome under the project's dual license. Before opening a pull request, please make sure:
1. `cargo fmt --all -- --check` passes.
2. `cargo clippy --all-targets --all-features -- -D warnings` is clean.
3. `cargo test --all-features` passes.
4. New public items include documentation and at least one example.
5. The [API reference](docs/API.md) and [CHANGELOG](CHANGELOG.md) are updated alongside code changes.
License
clock-lib is dual-licensed under either of:
-
Apache License, Version 2.0 — see LICENSE-APACHE or apache.org/licenses/LICENSE-2.0
-
MIT License — see LICENSE-MIT or opensource.org/licenses/MIT
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in clock-lib by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.
Unless required by applicable law or agreed to in writing, software distributed under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
COPYRIGHT © 2026 JAMES GOBER.