Skip to main content

haste_rate_limit/
lib.rs

1use std::pin::Pin;
2
3pub enum RateLimitError {
4    Error(String),
5    Exceeded,
6}
7
8pub trait RateLimit: Sync + Send {
9    /// Spends `points` against `rate_key` and returns the running total, or
10    /// [`RateLimitError::Exceeded`] once it would pass `max`. May be served
11    /// from a short-lived in-memory cache, so concurrent callers can each read
12    /// the same pre-spend total and slip past the cap by a small margin before
13    /// the backing store catches up.
14    fn check<'a>(
15        &'a self,
16        rate_key: &'a str,
17        max: i32,
18        points: i32,
19        window_in_seconds: i32,
20    ) -> Pin<Box<dyn Future<Output = Result<i32, RateLimitError>> + Send + 'a>>;
21
22    /// Like [`RateLimit::check`], but always consults the backing store rather
23    /// than any in-memory cache, so every concurrent call is counted exactly.
24    /// Use it to gate security-sensitive actions where the cache's slack would
25    /// let parallel requests exceed the cap, such as verification-code guesses.
26    /// The default delegates to [`RateLimit::check`]; back it with a serialized
27    /// store operation in real implementations.
28    fn check_uncached<'a>(
29        &'a self,
30        rate_key: &'a str,
31        max: i32,
32        points: i32,
33        window_in_seconds: i32,
34    ) -> Pin<Box<dyn Future<Output = Result<i32, RateLimitError>> + Send + 'a>> {
35        self.check(rate_key, max, points, window_in_seconds)
36    }
37}