revolt_database/models/ratelimit_events/ops/
mongodb.rs

1use std::time::{Duration, SystemTime};
2
3use super::AbstractRatelimitEvents;
4use crate::{MongoDb, RatelimitEvent, RatelimitEventType};
5use revolt_result::Result;
6use ulid::Ulid;
7
8static COL: &str = "ratelimit_events";
9
10#[async_trait]
11impl AbstractRatelimitEvents for MongoDb {
12    /// Insert a new ratelimit event
13    async fn insert_ratelimit_event(&self, event: &RatelimitEvent) -> Result<()> {
14        query!(self, insert_one, COL, &event).map(|_| ())
15    }
16
17    /// Count number of events in given duration and check if we've hit the limit
18    async fn has_ratelimited(
19        &self,
20        target_id: &str,
21        event_type: RatelimitEventType,
22        period: Duration,
23        count: usize,
24    ) -> Result<bool> {
25        self.col::<RatelimitEvent>(COL)
26            .count_documents(doc! {
27                "_id": {
28                    "$gte": Ulid::from_datetime(SystemTime::now() - period).to_string()
29                },
30                "target_id": target_id,
31                "event_type": event_type.to_string()
32            })
33            .await
34            .map(|c| c as usize >= count)
35            .map_err(|_| create_database_error!("count_documents", COL))
36    }
37}