fuel-web-utils 0.0.23

Fuel library for web utils
use std::{
    sync::Arc,
    time::{Duration, Instant},
};

use dashmap::DashMap;
use tokio::sync::RwLock;

#[derive(Clone, Debug)]
struct RateLimiter {
    last_request_time: Arc<RwLock<Instant>>,
    rate_limit: Duration,
}

impl RateLimiter {
    fn new(rate_limit: Duration) -> Self {
        RateLimiter {
            last_request_time: Arc::new(RwLock::new(Instant::now())),
            rate_limit,
        }
    }
}

#[derive(Debug, Default)]
pub struct RateLimitsController {
    map: DashMap<u64, RateLimiter>,
    rate_limit: Duration,
}

impl RateLimitsController {
    pub fn new(rate_limit: Duration) -> Self {
        Self {
            map: DashMap::new(),
            rate_limit,
        }
    }

    pub fn arc(self) -> Arc<Self> {
        Arc::new(self)
    }

    pub async fn check_rate_limit(&self, user_id: u64) -> bool {
        let user_rate_limiter = self.map.get(&user_id);
        match user_rate_limiter {
            Some(rate_limiter) => {
                let last_request_time =
                    rate_limiter.last_request_time.read().await;
                let elapsed = last_request_time.elapsed();
                if elapsed < rate_limiter.rate_limit {
                    return false;
                }
                true
            }
            None => {
                let rate_limiter = RateLimiter::new(self.rate_limit);
                self.map.insert(user_id, rate_limiter);
                true
            }
        }
    }
}

impl Clone for RateLimitsController {
    fn clone(&self) -> Self {
        Self {
            map: self.map.clone(),
            rate_limit: self.rate_limit,
        }
    }
}