#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct RateLimitConfig {
pub requests_per_window: u64,
pub window_secs: u64,
pub trusted_proxy_hops: usize,
pub max_buckets: usize,
}
pub const DEFAULT_MAX_BUCKETS: usize = 10_000;
impl Default for RateLimitConfig {
fn default() -> Self {
Self {
requests_per_window: 100,
window_secs: 60,
trusted_proxy_hops: 0,
max_buckets: DEFAULT_MAX_BUCKETS,
}
}
}
impl RateLimitConfig {
#[must_use]
pub const fn with_requests_per_window(mut self, requests: u64) -> Self {
self.requests_per_window = requests;
self
}
#[must_use]
pub const fn with_window_secs(mut self, secs: u64) -> Self {
self.window_secs = secs;
self
}
#[must_use]
pub const fn with_trusted_proxy_hops(mut self, hops: usize) -> Self {
self.trusted_proxy_hops = hops;
self
}
#[must_use]
pub const fn with_max_buckets(mut self, max: usize) -> Self {
self.max_buckets = max;
self
}
}
#[cfg(test)]
mod tests {
use super::RateLimitConfig;
#[test]
fn every_setter_sets_its_field() {
let d = RateLimitConfig::default();
let cfg = RateLimitConfig::default()
.with_requests_per_window(d.requests_per_window + 1)
.with_window_secs(d.window_secs + 1)
.with_trusted_proxy_hops(d.trusted_proxy_hops + 1)
.with_max_buckets(d.max_buckets + 1);
assert_eq!(cfg.requests_per_window, d.requests_per_window + 1);
assert_eq!(cfg.window_secs, d.window_secs + 1);
assert_eq!(cfg.trusted_proxy_hops, d.trusted_proxy_hops + 1);
assert_eq!(cfg.max_buckets, d.max_buckets + 1);
}
}