rate_guard_core/
lib.rs

1//! # `rate-guard-core`
2//! A comprehensive rate limiting library for Rust applications with multiple thread-safe algorithms.
3//!
4//! ## Features
5//! - **5 Rate Limiting Algorithms**: Token Bucket, Leaky Bucket, Fixed Window Counter, Sliding Window Counter, and Approximate Sliding Window  
6//! - **Thread-Safe**: All algorithms use non-blocking locks  
7//! - **Zero Dependencies**: Lightweight with no external dependencies  
8//! - **Flexible Time**: Works with any time unit via abstract “ticks”  
9//! - **Configurable Tick Precision**: Compile-time feature flags allow choosing `u64` (default) or `u128` for tick units  
10//! - **Rust 1.60+**: Compatible with older Rust versions  
11//!
12//! ---
13//!
14//! ## Quick Start
15//!
16//! ### from crate.io
17//! Add to your `Cargo.toml`:
18//! ```toml
19//! [dependencies]
20//! rate-guard-core = { version = "0.5.2" }
21//! ```
22//!
23//! ### from Github
24//! Add to your `Cargo.toml`:
25//! ```toml
26//! [dependencies]
27//! rate-guard-core = { git = "https://github.com/Kuanlin/rate-guard-core", tag = "v0.5.2" }
28//! ```
29//!
30//! ---
31//!
32//! ## Tick Precision (u64 / u128)
33//! By default, the crate uses `u64` as the tick unit, allowing up to ~584 years of nanosecond-resolution time.
34//! If your application needs ultra-long durations or ultra-high precision, you can enable `u128` support via feature flags:
35//!
36//! ### from crate.io
37//! ```toml
38//! [dependencies]
39//! rate-guard-core = { version = "0.5.2", default-features = false, features = ["tick_u128"] }
40//! ```
41//!
42//! ### from Github
43//! ```toml
44//! [dependencies]
45//! rate-guard-core = { git = "https://github.com/Kuanlin/rate-guard-core", tag = "v0.5.2", default-features = false, features = ["tick_u128"] }
46//! ```
47//!
48//! ---
49//!
50//! ## Usage Examples
51//!
52//! ### Token Bucket  
53//! Perfect for APIs that allow occasional bursts while maintaining average rate:
54//!
55//! ```rust
56//! use rate_guard_core::cores::{TokenBucketCore, TokenBucketCoreConfig};
57//!
58//! let config = TokenBucketCoreConfig {
59//!     capacity: 100,
60//!     refill_interval: 5,
61//!     refill_amount: 10,
62//! };
63//!
64//! let limiter: TokenBucketCore = config.into();
65//!
66//! ```
67//!
68//! ---
69//!
70//! ### Leaky Bucket  
71//! Great for maintaining steady traffic flow:
72//!
73//! ```rust
74//! use rate_guard_core::cores::{LeakyBucketCore, LeakyBucketCoreConfig};
75//!
76//! let config = LeakyBucketCoreConfig {
77//!     capacity: 50,
78//!     leak_interval: 10,
79//!     leak_amount: 5,
80//! };
81//!
82//! let limiter: LeakyBucketCore = config.into();
83//!
84//! ```
85//!
86//! ---
87//!
88//! ### Fixed Window Counter
89//!
90//! ```rust
91//! use rate_guard_core::cores::{FixedWindowCounterCore, FixedWindowCounterCoreConfig};
92//!
93//! let config = FixedWindowCounterCoreConfig {
94//!     capacity: 100,
95//!     window_size: 60,
96//! };
97//!
98//! let limiter: FixedWindowCounterCore = config.into();
99//! ```
100//!
101//! ---
102//!
103//! ### Sliding Window Counter
104//!
105//! ```rust
106//! use rate_guard_core::cores::{SlidingWindowCounterCore, SlidingWindowCounterCoreConfig};
107//!
108//! let config = SlidingWindowCounterCoreConfig {
109//!     capacity: 100,
110//!     bucket_ticks: 10,
111//!     bucket_count: 6,
112//! };
113//!
114//! let limiter: SlidingWindowCounterCore = config.into();
115//! ```
116//!
117//! ---
118//!
119//! ### Approximate Sliding Window  
120//! A memory-optimized version of sliding window counter.  
121//! Formula:  
122//! `Used = (1 - X%) * lastWindow + currentWindow` where X is the proportion of request time within the current window.
123//!
124//! ```rust
125//! use rate_guard_core::cores::{ApproximateSlidingWindowCore, ApproximateSlidingWindowCoreConfig};
126//!
127//! let config = ApproximateSlidingWindowCoreConfig {
128//!     capacity: 100,
129//!     window_ticks: 60,
130//! };
131//!
132//! let limiter: ApproximateSlidingWindowCore = config.into();
133//! ```
134//!
135//! > Both `into()` and `from()` are functionally equivalent in Rust.  
136//! > `into()` is shorter and idiomatic; `from()` is more explicit and beginner-friendly.  
137//! > These examples are duplicated to help both Rust newcomers and non-Rust readers understand the conversion logic.
138//!
139//!
140//! ---
141//!
142//! ### Approximate Sliding Window  
143//! A memory-optimized version of sliding window counter.  
144//! Formula:  
145//! `Used = (1 - X%) * lastWindow + currentWindow` where X is the proportion of request time within the current window.
146//!
147//! ```rust
148//! use rate_guard_core::cores::{ApproximateSlidingWindowCore, ApproximateSlidingWindowCoreConfig};
149//!
150//! let config = ApproximateSlidingWindowCoreConfig {
151//!     capacity: 100,
152//!     window_ticks: 60,
153//! };
154//! let limiter: ApproximateSlidingWindowCore = ApproximateSlidingWindowCore::from(config);
155//! ```
156//!
157//! ---
158//!
159//! ## Error Handling
160//! All limiters' try_acquire_at returns `SimpleRateLimitResult`:
161//! ```Rust
162//! use rate_guard_core::{SimpleRateLimitError, SimpleRateLimitResult};
163//! match limiter.try_acquire_at(tick, 1) {
164//!     Ok(()) => {
165//!         // Request allowed
166//!     },
167//!     Err(SimpleRateLimitError::InsufficientCapacity) => {
168//!         // Rate limit exceeded
169//!     },
170//!     Err(SimpleRateLimitError::BeyondCapacity) => {
171//!         // Acquiring too much
172//!     },
173//!     Err(SimpleRateLimitError::ExpiredTick) => {
174//!         // Time went backwards
175//!     },
176//!     Err(SimpleRateLimitError::ContentionFailure) => {
177//!         // Lock contention, you can do sleep and retry here.
178//!     },
179//! }
180//! ```
181//!
182//! ---
183//!
184//! ## Verbose Error Reporting
185//!
186//! Each limiter also supports `try_acquire_verbose_at(tick, tokens)`, which returns a `VerboseRateLimitError` with richer diagnostics:
187//!
188//! - `ContentionFailure`: Lock was unavailable
189//! - `ExpiredTick { min_acceptable_tick }`: Time went backwards
190//! - `BeyondCapacity { acquiring, capacity }`: Requested tokens exceed max
191//! - `InsufficientCapacity { acquiring, available, retry_after_ticks }`: Not enough tokens now, but suggests how long to wait before retrying
192//!
193//! ```Rust
194//! use rate_guard_core::{VerboseRateLimitError, VerboseRateLimitResult};
195//!
196//! match limiter.try_acquire_verbose_at(tick, 5) {
197//!     Ok(()) => {
198//!         // Request allowed
199//!     }
200//!     Err(VerboseRateLimitError::InsufficientCapacity { retry_after_ticks, .. }) => {
201//!         println!("Retry after {} ticks", retry_after_ticks);
202//!     }
203//!     Err(e) => {
204//!         println!("Rate limit error: {:?}", e);
205//!     }
206//! }
207//! ```
208//!
209//! > `try_acquire_verbose_at` is useful for retry logic, logging, or adaptive throttling.
210//!
211//! ---
212//!
213//! ## Time Management
214//! The library uses abstract “ticks” for time. You can map any time source:
215//! ```Rust
216//! // Seconds
217//! let tick = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
218//! // Milliseconds
219//! let tick = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
220//! // Custom time
221//! let tick = my_monotonic_timer.elapsed_ticks();
222//! ```
223//!
224//! ---
225//!
226//! ## Thread Safety
227//! ```Rust
228//! use std::sync::Arc;
229//! use std::thread;
230//! use rate_guard_core::cores::TokenBucketCore;
231//! let limiter = Arc::new(TokenBucketCore::new(100, 1, 10));
232//! for _ in 0..10 {
233//!     let limiter = limiter.clone();
234//!     thread::spawn(move || {
235//!         match limiter.try_acquire_at(get_current_tick(), 1) {
236//!             Ok(()) => println!("Request processed"),
237//!             Err(e) => println!("Rate limited: {}", e),
238//!         }
239//!     });
240//! }
241//! ```
242//!
243//! ---
244//!
245//! ## License
246//! Licensed under either of Apache License, Version 2.0 or MIT license at your option.
247//!
248//! ---
249//!
250//! ## Contributing
251//! Contributions are welcome! Please feel free to submit a Pull Request.
252
253pub mod types;
254pub mod cores;
255pub mod rate_limit;
256pub mod error; // 新增
257
258pub use types::Uint;
259pub use error::{
260    SimpleRateLimitError, VerboseRateLimitError,
261    SimpleRateLimitResult, VerboseRateLimitResult,
262};