use std::num::NonZeroU32;
use super::RateLimiter;
use crate::{
clock,
errors::InsufficientCapacity,
middleware::RateLimitingMiddleware,
state::{DirectStateStore, NotKeyed},
Jitter, NotUntil,
};
use futures_timer::Delay;
#[cfg(feature = "std")]
impl<S, C, MW> RateLimiter<NotKeyed, S, C, MW>
where
S: DirectStateStore,
C: clock::ReasonablyRealtime,
MW: RateLimitingMiddleware<C::Instant, NegativeOutcome = NotUntil<C::Instant>>,
{
pub async fn until_ready(&self) -> MW::PositiveOutcome {
self.until_ready_with_jitter(Jitter::NONE).await
}
pub async fn until_ready_with_jitter(&self, jitter: Jitter) -> MW::PositiveOutcome {
loop {
match self.check() {
Ok(x) => {
return x;
}
Err(negative) => {
let delay = Delay::new(jitter + negative.wait_time_from(self.clock.now()));
delay.await;
}
}
}
}
pub async fn until_n_ready(
&self,
n: NonZeroU32,
) -> Result<MW::PositiveOutcome, InsufficientCapacity> {
self.until_n_ready_with_jitter(n, Jitter::NONE).await
}
pub async fn until_n_ready_with_jitter(
&self,
n: NonZeroU32,
jitter: Jitter,
) -> Result<MW::PositiveOutcome, InsufficientCapacity> {
loop {
match self.check_n(n)? {
Ok(x) => {
return Ok(x);
}
Err(negative) => {
let delay = Delay::new(jitter + negative.wait_time_from(self.clock.now()));
delay.await;
}
}
}
}
}
#[cfg(test)]
mod test {
use assertables::assert_gt;
use super::*;
#[test]
fn insufficient_capacity_impl_coverage() {
let i = InsufficientCapacity(1);
assert_eq!(i.0, i.0);
assert_gt!(format!("{i}").len(), 0);
}
}