rate-guard 0.1.0

Thread-safe rate limiting library with multiple algorithms and Duration-based configuration
Documentation
#![cfg(feature = "tokio-time")]
use rate_guard::{
    Nanos, TokioTimeSource, RateLimit, RateLimitError,
    limits::TokenBucketBuilder,
};
use tokio::time::{ Duration , sleep };
const MAX_RETRIES: usize = 5;

#[tokio::main]
async fn main() {
    let bucket = TokenBucketBuilder::builder()
        .capacity(100)
        .refill_amount(10)
        .refill_every(Duration::from_millis(100))
        .with_time(TokioTimeSource::new())
        .with_precision::<Nanos>()
        .build()
        .expect("Failed to build token bucket");

    println!("Starting token bucket (async with retry)");

    for i in 0..20 {
        let success = acquire_with_retry(&bucket, 20, MAX_RETRIES).await;
        match success {
            Ok(()) => println!("[{:02}] Allowed", i),
            Err(e) => println!("[{:02}] Failed after retries: {}", i, e),
        }
    }

    println!("Done.");
}

async fn acquire_with_retry(
    limiter: &impl RateLimit,
    tokens: u64,
    max_retries: usize,
) -> Result<(), RateLimitError> {
    for attempt in 0..max_retries {
        match limiter.try_acquire_verbose(tokens) {
            Ok(()) => return Ok(()),
            Err(RateLimitError::InsufficientCapacity { retry_after, .. }) => {
                // Wait and retry
                if attempt < max_retries - 1 {
                    println!(
                        "Attempt {}: Insufficient capacity, retrying in {:?}...",
                        attempt + 1,
                        retry_after.as_nanos()
                    );
                    sleep(retry_after).await;
                } else {
                    return Err(RateLimitError::InsufficientCapacity {
                        acquiring: tokens,
                        available: 0,
                        retry_after,
                    });
                }
            }
            Err(e) => return Err(e),
        }
    }

    unreachable!() // loop guarantees return
}