use std::time::Duration;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RateLimitConfig {
pub requests_per_minute: u32,
pub requests_per_hour: u32,
}
impl Default for RateLimitConfig {
fn default() -> Self {
Self {
requests_per_minute: 60,
requests_per_hour: 1000,
}
}
}
impl RateLimitConfig {
pub fn new(requests_per_minute: u32, requests_per_hour: u32) -> Self {
Self {
requests_per_minute,
requests_per_hour,
}
}
#[inline]
pub fn for_plan(plan: &str) -> Self {
match plan {
"enterprise" => Self {
requests_per_minute: 1000,
requests_per_hour: 50000,
},
"pro" => Self {
requests_per_minute: 100,
requests_per_hour: 5000,
},
_ => Self {
requests_per_minute: 20,
requests_per_hour: 500,
},
}
}
pub fn unlimited() -> Self {
Self {
requests_per_minute: u32::MAX,
requests_per_hour: u32::MAX,
}
}
pub fn is_unlimited(&self) -> bool {
self.requests_per_minute == u32::MAX && self.requests_per_hour == u32::MAX
}
pub fn minute_window() -> Duration {
Duration::from_secs(60)
}
pub fn hour_window() -> Duration {
Duration::from_secs(3600)
}
}
#[derive(Debug, Clone)]
pub struct RateLimitConfigBuilder {
requests_per_minute: u32,
requests_per_hour: u32,
}
impl Default for RateLimitConfigBuilder {
fn default() -> Self {
Self::new()
}
}
impl RateLimitConfigBuilder {
pub fn new() -> Self {
Self {
requests_per_minute: 60,
requests_per_hour: 1000,
}
}
pub fn per_minute(mut self, limit: u32) -> Self {
self.requests_per_minute = limit;
self
}
pub fn per_hour(mut self, limit: u32) -> Self {
self.requests_per_hour = limit;
self
}
pub fn build(self) -> RateLimitConfig {
RateLimitConfig {
requests_per_minute: self.requests_per_minute,
requests_per_hour: self.requests_per_hour,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = RateLimitConfig::default();
assert_eq!(config.requests_per_minute, 60);
assert_eq!(config.requests_per_hour, 1000);
}
#[test]
fn test_for_plan() {
let free = RateLimitConfig::for_plan("free");
assert_eq!(free.requests_per_minute, 20);
assert_eq!(free.requests_per_hour, 500);
let pro = RateLimitConfig::for_plan("pro");
assert_eq!(pro.requests_per_minute, 100);
assert_eq!(pro.requests_per_hour, 5000);
let enterprise = RateLimitConfig::for_plan("enterprise");
assert_eq!(enterprise.requests_per_minute, 1000);
assert_eq!(enterprise.requests_per_hour, 50000);
let unknown = RateLimitConfig::for_plan("unknown");
assert_eq!(unknown, RateLimitConfig::for_plan("free"));
}
#[test]
fn test_unlimited() {
let config = RateLimitConfig::unlimited();
assert!(config.is_unlimited());
}
#[test]
fn test_builder() {
let config = RateLimitConfigBuilder::new()
.per_minute(200)
.per_hour(10000)
.build();
assert_eq!(config.requests_per_minute, 200);
assert_eq!(config.requests_per_hour, 10000);
}
}