#[derive(Debug, Clone)]
pub(super) struct TokenBucket {
pub(super) tokens: f64,
pub(super) capacity: f64,
pub(super) refill_rate: f64,
pub(super) last_refill: std::time::Instant,
}
impl TokenBucket {
pub(super) fn new(capacity: f64, refill_rate: f64) -> Self {
Self {
tokens: capacity,
capacity,
refill_rate,
last_refill: std::time::Instant::now(),
}
}
pub(super) fn try_consume(&mut self, tokens: f64) -> bool {
let now = std::time::Instant::now();
let elapsed = now.duration_since(self.last_refill).as_secs_f64();
let refilled = elapsed * self.refill_rate;
self.tokens = (self.tokens + refilled).min(self.capacity);
self.last_refill = now;
if self.tokens >= tokens {
self.tokens -= tokens;
true
} else {
false
}
}
pub(super) fn token_count(&self) -> f64 {
let now = std::time::Instant::now();
let elapsed = now.duration_since(self.last_refill).as_secs_f64();
let refilled = elapsed * self.refill_rate;
(self.tokens + refilled).min(self.capacity)
}
}