use governor::{
clock::{Clock, DefaultClock},
state::{InMemoryState, NotKeyed},
RateLimiter as Governor,
};
use std::sync::Arc;
use std::time::Duration;
#[derive(Debug)]
pub struct RateLimitError {
wait_time: Duration,
}
impl RateLimitError {
pub fn wait_time(&self) -> Duration {
self.wait_time
}
}
#[derive(Debug, Clone)]
pub struct RateLimiter {
limiter: Arc<Governor<NotKeyed, InMemoryState, DefaultClock>>,
}
impl RateLimiter {
pub fn new(quota: governor::Quota) -> Self {
Self {
limiter: Arc::new(Governor::direct(quota)),
}
}
pub async fn check(&self) -> Result<(), RateLimitError> {
self.limiter.check().map_err(|negative| RateLimitError {
wait_time: negative.wait_time_from(self.limiter.clock().now()),
})
}
}
impl Default for RateLimiter {
fn default() -> Self {
Self::new(governor::Quota::per_second(100u32.try_into().unwrap()))
}
}