rate_guard/lib.rs
1//! Rate-Guard: A flexible and type-safe rate limiting library for Rust.
2//!
3//! Rate-Guard provides a unified interface for multiple rate limiting algorithms
4//! with Duration-based configuration, type-safe time handling, and comprehensive
5//! error reporting. It's designed to integrate seamlessly with Rust's async
6//! ecosystem while maintaining high performance through zero-cost abstractions.
7//!
8//! Key Features:
9//! - Duration-Based Configuration: All timing parameters use std::time::Duration
10//! - Multiple Algorithms: Token bucket, fixed window counter, sliding window counter, and approximate sliding window
11//! - Time Source Abstraction: Pluggable time sources (mock, std::time, etc.)
12//! - Precision Control: Compile-time precision selection for optimal performance
13//! - Builder Pattern: Fluent configuration API with compile-time validation
14//! - Zero-Cost Abstractions: High-level ergonomics without runtime overhead
15//! - Comprehensive Testing: Built-in mock time source for deterministic testing
16//!
17//!
18//! # Feature Flags
19//!
20//! ## Time Sources (Optional)
21//! - `std-time` - Standard library time source (recommended for production)
22//! - `tokio-time` - Tokio time source (for async environments)
23//!
24//! ## Precision Types (Mutually Exclusive, defaults to u64)
25//! - `tick-u64` (default) - 64-bit precision, suitable for most scenarios
26//! - `tick-u128` - 128-bit precision, for extreme long-duration use cases
27//!
28//! ```toml
29//! # Default configuration
30//! rate-guard = "0.1.0"
31//!
32//! # Production recommended
33//! rate-guard = { version = "0.1.0", features = ["std-time"] }
34//!
35//! # Special requirements: high precision
36//! rate-guard = { version = "0.1.0", features = ["std-time", "tick-u128"] }
37//! ```
38//!
39//!
40//! # Quick Start
41//!
42//! ```rust
43//! use rate_guard::{Nanos, MockTimeSource, RateLimit};
44//! use rate_guard::limits::TokenBucketBuilder;
45//! use std::time::Duration;
46//!
47//! // Create a token bucket using the builder pattern
48//! let bucket = TokenBucketBuilder::builder()
49//! .capacity(100)
50//! .refill_amount(10)
51//! .refill_every(Duration::from_millis(100))
52//! .with_time(MockTimeSource::new())
53//! .with_precision::<Nanos>()
54//! .build()
55//! .unwrap();
56//!
57//! // Use the rate limiter
58//! match bucket.try_acquire(50) {
59//! Ok(()) => println!("Request allowed"),
60//! Err(_) => println!("Rate limited"),
61//! }
62//! ```
63//!
64//! # Testing with Mock Time
65//!
66//! ```rust
67//! use rate_guard::{Millis, MockTimeSource, RateLimit};
68//! use rate_guard::limits::TokenBucketBuilder;
69//! use std::time::Duration;
70//!
71//! let time_source = MockTimeSource::new();
72//! let bucket = TokenBucketBuilder::builder()
73//! .capacity(50)
74//! .refill_amount(5)
75//! .refill_every(Duration::from_millis(200))
76//! .with_time(time_source.clone())
77//! .with_precision::<Millis>()
78//! .build()
79//! .unwrap();
80//!
81//! // Use all tokens
82//! assert!(bucket.try_acquire(50).is_ok());
83//! assert_eq!(bucket.capacity_remaining().unwrap(), 0);
84//!
85//! // Advance time to trigger refill
86//! time_source.advance(Duration::from_millis(200));
87//! assert_eq!(bucket.capacity_remaining().unwrap(), 5);
88//! ```
89//!
90//! # All Rate Limiter Types
91//!
92//! ```rust
93//! use rate_guard::{
94//! Millis, MockTimeSource, RateLimit
95//! };
96//! use rate_guard::limits::{
97//! TokenBucketBuilder, FixedWindowCounterBuilder,
98//! SlidingWindowCounterBuilder, ApproximateSlidingWindowBuilder
99//! };
100//! use std::time::Duration;
101//!
102//! let time_source = MockTimeSource::new();
103//!
104//! // Token Bucket - allows bursts
105//! let token_bucket = TokenBucketBuilder::builder()
106//! .capacity(100)
107//! .refill_amount(10)
108//! .refill_every(Duration::from_millis(100))
109//! .with_time(time_source.clone())
110//! .with_precision::<Millis>()
111//! .build()
112//! .unwrap();
113//!
114//!
115//! // Fixed Window Counter
116//! let fixed_window = FixedWindowCounterBuilder::builder()
117//! .capacity(100)
118//! .window_duration(Duration::from_secs(60))
119//! .with_time(time_source.clone())
120//! .with_precision::<Millis>()
121//! .build()
122//! .unwrap();
123//!
124//! // Sliding Window Counter
125//! let sliding_window = SlidingWindowCounterBuilder::builder()
126//! .capacity(100)
127//! .bucket_duration(Duration::from_secs(10))
128//! .bucket_count(6)
129//! .with_time(time_source.clone())
130//! .with_precision::<Millis>()
131//! .build()
132//! .unwrap();
133//!
134//! // Approximate Sliding Window
135//! let approx_window = ApproximateSlidingWindowBuilder::builder()
136//! .capacity(100)
137//! .window_duration(Duration::from_secs(60))
138//! .with_time(time_source)
139//! .with_precision::<Millis>()
140//! .build()
141//! .unwrap();
142//! ```
143
144// Re-export core types
145pub use rate_guard_core::types::Uint;
146
147// Precision system
148pub mod precision;
149pub use precision::{Precision, Nanos, Micros, Millis, Secs};
150
151// Time source abstraction
152pub mod time_source;
153pub use time_source::{TimeSource, MockTimeSource};
154#[cfg(feature = "std-time")]
155pub use time_source::StdTimeSource;
156
157#[cfg(feature = "tokio-time")]
158pub use time_source::TokioTimeSource;
159
160// Error types with Duration-based retry timing and builder validation
161pub mod error;
162pub use error::{
163 RateLimitError, RateLimitResult, BuildError, BuildResult,
164};
165
166// Rate limiter implementations
167pub mod limits;
168pub use limits::{
169 RateLimit,
170 TokenBucket, TokenBucketBuilder,
171 FixedWindowCounter, FixedWindowCounterBuilder,
172 SlidingWindowCounter, SlidingWindowCounterBuilder,
173 ApproximateSlidingWindow, ApproximateSlidingWindowBuilder,
174 // Backward compatibility aliases
175 PrecisionFixedWindowCounter,
176 PrecisionSlidingWindowCounter,
177 PrecisionApproximateSlidingWindow,
178};
179
180// Configuration types (keeping for backward compatibility)
181pub mod types;
182pub use types::*;
183
184
185// Standard rate limiter type aliases for backward compatibility
186
187/// Type alias for a fixed window counter with standard nanosecond precision.
188pub type FixedWindowCounterNanos = FixedWindowCounter<Nanos, MockTimeSource>;
189
190/// Type alias for a sliding window counter with standard nanosecond precision.
191pub type SlidingWindowCounterNanos = SlidingWindowCounter<Nanos, MockTimeSource>;
192
193/// Type alias for an approximate sliding window with standard nanosecond precision.
194pub type ApproximateSlidingWindowNanos = ApproximateSlidingWindow<Nanos, MockTimeSource>;
195
196// Type aliases for common configurations (users can define their own)
197/// Common configuration: Token bucket with nanosecond precision and standard time.
198#[cfg(feature = "std-time")]
199pub type StdTokenBucket = TokenBucket<Nanos, StdTimeSource>;
200
201/// Common configuration: Token bucket with nanosecond precision and mock time for testing.
202pub type MockTokenBucket = TokenBucket<Nanos, MockTimeSource>;
203
204/// Common configuration: Token bucket with millisecond precision and standard time.
205#[cfg(feature = "std-time")]
206pub type MillisTokenBucket = TokenBucket<Millis, StdTimeSource>;
207
208/// Common configuration: Token bucket with millisecond precision and mock time for testing.
209pub type MillisMockTokenBucket = TokenBucket<Millis, MockTimeSource>;
210
211#[cfg(feature = "std-time")]
212pub type StdFixedWindowCounter = FixedWindowCounter<Nanos, StdTimeSource>;
213pub type MockFixedWindowCounter = FixedWindowCounter<Nanos, MockTimeSource>;
214
215#[cfg(feature = "std-time")]
216pub type StdSlidingWindowCounter = SlidingWindowCounter<Nanos, StdTimeSource>;
217pub type MockSlidingWindowCounter = SlidingWindowCounter<Nanos, MockTimeSource>;
218
219#[cfg(feature = "std-time")]
220pub type StdApproximateSlidingWindow = ApproximateSlidingWindow<Nanos, StdTimeSource>;
221pub type MockApproximateSlidingWindow = ApproximateSlidingWindow<Nanos, MockTimeSource>;