rate_net/algorithm.rs
1//! The rate-limiting algorithm a limiter applies.
2
3/// Selects the algorithm a limiter uses to decide a request.
4///
5/// Every algorithm shares the same [`Limiter`](crate::Limiter) surface, so the
6/// strategy can change without touching call sites. This enum is the selector a
7/// future builder uses to pick between them.
8///
9/// `#[non_exhaustive]`: algorithms are added over the `0.x` series, so a `match`
10/// must include a wildcard arm. [`TokenBucket`](Self::TokenBucket) — the default
11/// — is always available; the leaky bucket and the window algorithms are
12/// compiled in under the `algorithms` feature, so their variants only exist when
13/// it is enabled.
14///
15/// # Examples
16///
17/// ```
18/// use rate_net::Algorithm;
19///
20/// // The default is the token bucket — smooth refill with burst headroom.
21/// assert_eq!(Algorithm::default(), Algorithm::TokenBucket);
22/// ```
23#[non_exhaustive]
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
25pub enum Algorithm {
26 /// Smooth refill with burst headroom up to the configured capacity. The
27 /// general-purpose default; delegates its accounting to `better-bucket`.
28 #[default]
29 TokenBucket,
30 /// Constant-drain shaping that smooths bursts to a steady output rate.
31 /// Requires the `algorithms` feature.
32 #[cfg(feature = "algorithms")]
33 LeakyBucket,
34 /// A counter that resets each window; cheapest, tolerates boundary bursts.
35 /// Requires the `algorithms` feature.
36 #[cfg(feature = "algorithms")]
37 FixedWindow,
38 /// Exact request timestamps within the trailing window; highest accuracy,
39 /// higher memory. Requires the `algorithms` feature.
40 #[cfg(feature = "algorithms")]
41 SlidingWindowLog,
42 /// A weighted blend of the current and previous window; an accuracy/cost
43 /// balance and a common production choice. Requires the `algorithms` feature.
44 #[cfg(feature = "algorithms")]
45 SlidingWindowCounter,
46}
47
48#[cfg(test)]
49mod tests {
50 use super::Algorithm;
51
52 #[test]
53 fn test_default_is_token_bucket() {
54 assert_eq!(Algorithm::default(), Algorithm::TokenBucket);
55 }
56
57 #[cfg(feature = "algorithms")]
58 #[test]
59 fn test_variants_are_distinct() {
60 assert_ne!(Algorithm::TokenBucket, Algorithm::LeakyBucket);
61 assert_ne!(Algorithm::FixedWindow, Algorithm::SlidingWindowLog);
62 }
63}