salvo_rate_limiter/
fixed_guard.rs

1use serde::{Deserialize, Serialize};
2use time::OffsetDateTime;
3
4use super::{BasicQuota, RateGuard};
5
6/// Fixed window implement.
7#[derive(Deserialize, Serialize, Clone, Debug)]
8pub struct FixedGuard {
9    reset: OffsetDateTime,
10    count: usize,
11    quota: Option<BasicQuota>,
12}
13
14impl Default for FixedGuard {
15    fn default() -> Self {
16        Self::new()
17    }
18}
19
20impl FixedGuard {
21    /// Create a new `FixedGuard`.
22    pub fn new() -> Self {
23        Self {
24            reset: OffsetDateTime::now_utc(),
25            count: 0,
26            quota: None,
27        }
28    }
29}
30
31impl RateGuard for FixedGuard {
32    type Quota = BasicQuota;
33    async fn verify(&mut self, quota: &Self::Quota) -> bool {
34        if self.quota.is_none() || OffsetDateTime::now_utc() > self.reset || self.quota.as_ref() != Some(quota) {
35            if self.quota.as_ref() != Some(quota) {
36                let mut quota = quota.clone();
37                if quota.limit == 0 {
38                    quota.limit = 1;
39                }
40                self.quota = Some(quota);
41            }
42            self.reset = OffsetDateTime::now_utc() + quota.period;
43            self.count = 1;
44            true
45        } else if self.count < quota.limit {
46            self.count += 1;
47            true
48        } else {
49            false
50        }
51    }
52
53    async fn remaining(&self, quota: &Self::Quota) -> usize {
54        quota.limit - self.count
55    }
56
57    async fn reset(&self, _: &Self::Quota) -> i64 {
58        self.reset.unix_timestamp()
59    }
60
61    async fn limit(&self, quota: &Self::Quota) -> usize {
62        quota.limit
63    }
64}