1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! # better-bucket
//!
//! A genuinely better token bucket for Rust. The hot path — `try_acquire` — is
//! designed to be **lock-free**, **allocation-free**, and **cache-aligned**: a
//! single compare-and-swap over a packed `(tokens, last_refill_tick)` word.
//! Refill is **lazy**, computed from a monotonic clock the instant you ask, so
//! an idle bucket costs nothing — no background timer thread, no per-tick
//! wakeups. The defining correctness property is that the bucket **never
//! over-grants**: across any concurrent interleaving, the total tokens handed
//! out never exceed capacity plus accrued refill.
//!
//! The crate is a single-purpose primitive. It owns token-bucket accounting and
//! nothing else, so it can sit at the bottom of a dependency tree (its first
//! consumer is the `rate-net` rate limiter) without dragging in an async
//! runtime or a keyed-state store.
//!
//! ## Status
//!
//! Pre-1.0 (beta), hardened, **API frozen** until `1.0`: the lock-free
//! [`Bucket`], the Tier-2 [`BucketBuilder`], [`BucketConfig`], [`Decision`],
//! [`BucketError`], and the [`TokenBucket`] trait. The surface is validated
//! against the first-consumer pattern (trait-based checks, injected shared
//! clock, [`Decision`]-to-retry mapping) with no friction. `try_acquire` is a
//! single `compare_exchange_weak` on a packed atomic word — allocation-free,
//! cache-line aligned, with a division-free fixed-point refill. The safety
//! contract (no panic, no wrap, no over-grant, tokens in `[0, capacity]`) holds
//! under adversarial inputs and extreme uptime, defended by `loom`, a stress
//! test, an allocation audit, an adversarial/edge suite, and `proptest`. The
//! bucket's own accounting measures around six nanoseconds; end-to-end
//! `try_acquire` is bounded by the monotonic clock read. See `docs/BENCHMARKS.md`.
//!
//! Token bucket is the crate's sole algorithm by design — leaky-bucket and
//! sliding-window limiting live in the downstream `rate-net` crate.
//!
//! ```
//! # #[cfg(feature = "clock")] {
//! use better_bucket::Bucket;
//!
//! // 100 tokens per second, capacity 100.
//! let bucket = Bucket::per_second(100);
//!
//! if bucket.try_acquire(1) {
//! // allowed — do the work
//! } else {
//! // denied — shed load / return 429 / back off
//! }
//! # }
//! ```
//!
//! The bucket reads time from [`clock-lib`](https://crates.io/crates/clock-lib);
//! the `clock` feature (on by default) provides it and implies `std`. A bare
//! `no_std` build (`default-features = false`) currently exposes only
//! [`VERSION`] — the no_std-capable, caller-driven core lands with the lock-free
//! rewrite in `0.3`.
//!
//! ## Design goals
//!
//! - **Lock-free acquire.** One `compare_exchange_weak` on a packed atomic
//! word; no `Mutex`, no parking on the hot path.
//! - **Allocation-free steady state.** A bucket is a small, cache-line-aligned
//! value with no heap tail; acquiring never allocates.
//! - **Lazy refill.** Tokens accrue from elapsed monotonic time on access — no
//! timer thread, no wakeups, no watts burned while idle.
//! - **Overflow-safe.** Every refill and capacity computation is checked or
//! saturating; a hostile request count or a multi-day idle gap can neither
//! wrap the counter nor over-fill the bucket.
//! - **`no_std`-capable.** The core runs without the standard library; the
//! caller drives time when `std` is disabled.
//!
//! ## Feature flags
//!
//! | Feature | Default | Description |
//! |---------|---------|-------------|
//! | `std` | yes | Standard library. Off → `no_std`, caller drives time. |
//! | `clock` | yes | Pluggable [`clock-lib`](https://crates.io/crates/clock-lib) time source plus a mockable clock for deterministic tests. |
// `no_std` for the library build when `std` is off, but always link `std` under
// `test` so the unit-test harness (and dev-dependencies) have what they need.
// The token-bucket surface requires a clock to read time and a `Mutex` for the
// simple implementation; both are gated on `clock` (which implies `std`). The
// no_std, caller-driven core arrives with the lock-free rewrite in 0.3.
pub use crate;
pub use crateBucketBuilder;
pub use crateBucketConfig;
pub use crateDecision;
pub use crateBucketError;
/// The version of this crate, taken from `Cargo.toml` at compile time.
///
/// Exposed so a consumer can report the exact `better-bucket` build it links
/// against — useful in diagnostics and version-skew checks across a dependency
/// tree.
///
/// # Examples
///
/// ```
/// // Reports the current 0.x series and carries a major.minor.patch core.
/// let version = better_bucket::VERSION;
/// assert!(version.starts_with("0.9"));
/// assert_eq!(version.split('.').count(), 3);
/// ```
pub const VERSION: &str = env!;