#[cfg(feature = "rate-limiting")]
use std::future::Future;
#[cfg(feature = "rate-limiting")]
use std::pin::Pin;
#[cfg(feature = "rate-limiting")]
pub use governor::{
clock::DefaultClock,
state::{keyed::DefaultKeyedStateStore, InMemoryState},
DefaultDirectRateLimiter, DefaultKeyedRateLimiter, Quota, RateLimiter,
};
#[cfg(feature = "rate-limiting")]
pub trait CacheAwareRateLimiter: Send + Sync + 'static {
fn until_key_ready(
&self,
key: &str,
) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
fn check_key(&self, key: &str) -> bool;
}
#[cfg(feature = "rate-limiting")]
#[derive(Debug)]
pub struct DomainRateLimiter {
limiter: DefaultKeyedRateLimiter<String>,
}
#[cfg(feature = "rate-limiting")]
impl DomainRateLimiter {
pub fn new(quota: Quota) -> Self {
Self { limiter: DefaultKeyedRateLimiter::keyed(quota) }
}
}
#[cfg(feature = "rate-limiting")]
impl CacheAwareRateLimiter for DomainRateLimiter {
fn until_key_ready(
&self,
key: &str,
) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
let key = key.to_string();
Box::pin(async move {
self.limiter.until_key_ready(&key).await;
})
}
fn check_key(&self, key: &str) -> bool {
self.limiter.check_key(&key.to_string()).is_ok()
}
}
#[cfg(feature = "rate-limiting")]
#[derive(Debug)]
pub struct DirectRateLimiter {
limiter: DefaultDirectRateLimiter,
}
#[cfg(feature = "rate-limiting")]
impl DirectRateLimiter {
pub fn direct(quota: Quota) -> DirectRateLimiter {
DirectRateLimiter { limiter: DefaultDirectRateLimiter::direct(quota) }
}
}
#[cfg(feature = "rate-limiting")]
impl CacheAwareRateLimiter for DirectRateLimiter {
fn until_key_ready(
&self,
_key: &str,
) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
Box::pin(async move {
self.limiter.until_ready().await;
})
}
fn check_key(&self, _key: &str) -> bool {
self.limiter.check().is_ok()
}
}