touch_ratelimit 0.1.0

A composable, extensible rate limiting crate for Rust
Documentation
use std::collections::HashMap;

use parking_lot::Mutex;

use crate::{bucket::RateLimiter, storage::RateLimitStore};

/// In-memory rate limit storage.
///
/// This store keeps all rate-limiting state in the application's memory.
/// Each unique key is associated with a separate rate limiter instance.
///
/// ## Characteristics
///
/// - Fast
/// - No external dependencies
/// - State is lost on restart
/// - Not shared across multiple processes
pub struct InMemoryStore<L: RateLimiter> {
    buckets: Mutex<HashMap<String, L>>,
    factory: Box<dyn Fn() -> L + Send + Sync>,
}

impl<L> InMemoryStore<L>
where
    L: RateLimiter,
{
    /// Create a new in-memory store using the provided limiter factory.
    ///
    /// The factory is called whenever a new key is encountered.
    pub fn new(factory: impl Fn() -> L + Send + Sync + 'static) -> Self {
        Self {
            buckets: Mutex::new(HashMap::new()),
            factory: Box::new(factory),
        }
    }
}

impl<L> RateLimitStore for InMemoryStore<L>
where
    L: RateLimiter,
{
    fn allow(&self, key: &str) -> bool {
        let mut map = self.buckets.lock();
        let limiter = map
            .entry(key.to_string())
            .or_insert_with(|| (self.factory)());

        limiter.allow()
    }
}