pub mod direct;
pub mod keyed;
mod in_memory;
pub(crate) use self::{direct::*, in_memory::InMemoryState};
use crate::{
gcra::Gcra,
nanos::Nanos,
quota::Quota,
timer::{DefaultTimer, Timer},
};
pub(crate) trait StateStore {
type Key;
fn measure_and_replace<T, F, E>(&self, key: &Self::Key, f: F) -> Result<T, E>
where
F: Fn(Option<Nanos>) -> Result<(T, Nanos), E>;
}
#[derive(Debug)]
pub(crate) struct RateLimiter<K, S, C = DefaultTimer>
where
S: StateStore<Key = K>,
C: Timer,
{
state: S,
gcra: Gcra,
clock: C,
start: C::Instant,
}
impl<K, S, C> RateLimiter<K, S, C>
where
S: StateStore<Key = K>,
C: Timer,
{
pub(crate) fn new(quota: Quota, state: S, clock: &C) -> Self {
let gcra = Gcra::new(quota);
let start = clock.now();
let clock = clock.clone();
RateLimiter {
state,
clock,
gcra,
start,
}
}
#[cfg(test)]
pub(crate) fn into_state_store(self) -> S {
self.state
}
}