# v0.3.0 — The Mockable Clock
The headline feature of `clock-lib` lands in this release: a [`Clock`](../API.md#clock) trait with two implementations — [`SystemClock`](../API.md#systemclock) for production and [`ManualClock`](../API.md#manualclock) for tests — so timing-driven code becomes deterministically testable without ever calling `thread::sleep`.
## Highlights
- **[`Clock`](../API.md#clock) trait.** A `Send + Sync` source of time exposing `now() -> Monotonic` and `wall() -> Wall`. Take it as a dependency anywhere your code reads the clock; substitute it in tests.
- **[`SystemClock`](../API.md#systemclock).** Zero-sized, `Copy`, `const`-constructible. Forwards directly to the OS readings already in the crate — nothing extra to pay over the free functions.
- **[`ManualClock`](../API.md#manualclock).** Lock-free advance via an `AtomicU64` offset. The clock never moves on its own. Tests advance it forward in arbitrary increments and observe the timing-driven behavior exactly.
- **Blanket impls.** `Clock` is implemented for `Arc<C>` and `&C` where `C: Clock`, so shared ownership and borrowed access work without re-implementing the trait.
- **TTL test pattern, no sleep.** The classic "is this expired?" check now takes 8 lines and zero milliseconds of real wall-clock time:
```rust
use clock_lib::{Clock, ManualClock, Monotonic};
use std::time::Duration;
fn expired<C: Clock>(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));
assert!(expired(&clock, stamp, Duration::from_secs(60)));
```
## What's New
### Added
- `Clock` trait with `now` and `wall` methods (`Send + Sync`).
- `SystemClock` struct (`Copy`, `const`-constructible).
- `ManualClock` struct with `new`, `advance`, and `offset` methods backed by an atomic offset.
- Blanket `Clock` impls for `Arc<C: Clock>` and `&C: Clock`.
- Integration tests covering: zero-advance idempotence, exact-advance semantics on both monotonic and wall, offset accumulation, the sleep-free TTL pattern, `Arc<ManualClock>` dispatch, and `Arc<dyn Clock>` trait-object usage.
- Doctests on every public item in the new module.
### Changed
- `Monotonic` and `Wall` fields are now `pub(crate)` (internal change — field access remains forbidden outside the crate, but `ManualClock` can construct synthetic readings).
## Compatibility
- **MSRV:** Rust 1.85 (unchanged)
- **Edition:** 2024 (unchanged)
- **Public API:** strictly additive. All 0.2.x code continues to compile unchanged.
## Upgrading From 0.2.x
```toml
[dependencies]
clock-lib = "0.3"
```
No code changes required. To adopt the mockable clock pattern, take a `C: Clock` (or `&dyn Clock`, or `Arc<dyn Clock>`) as a dependency wherever you call `clock_lib::now()` today, and pass `SystemClock` in production. Your tests can then swap to `ManualClock` and drop every `thread::sleep`.
## What's Next
- **0.4.0 — performance verification.** Criterion benchmarks for reading latency on both `SystemClock` and `ManualClock`, with committed baselines proving zero overhead over raw `std::time`.
- **0.5.0 — `no_std` hardening and the 1.0 release candidate.**