async_rate_limit/
limiters.rs

1use std::future::Future;
2
3/// A per-call rate limiter, where each call has an implied cost of 1 permit.
4///
5/// See [`SlidingWindowRateLimiter`] for a common use case.
6///
7/// [`SlidingWindowRateLimiter`]: ../sliding_window/struct.SlidingWindowRateLimiter.html
8pub trait RateLimiter {
9    fn wait_until_ready(&mut self) -> impl Future<Output = ()> + Send;
10}
11
12/// A cost-based rate limiter, where each call can be of a variable cost.
13///
14/// Calls that cost more than all potentially available permits WILL deadlock permanently.
15///
16///  See [`TokenBucketRateLimiter`] for a common use case.
17///
18///  [`TokenBucketRateLimiter`]: ../token_bucket/struct.TokenBucketRateLimiter.html
19pub trait VariableCostRateLimiter {
20    fn wait_with_cost(&mut self, cost: usize) -> impl Future<Output = ()> + Send;
21}
22
23/// A threadsafe per-call rate limiter, where each call has an implied cost of 1 permit.
24///
25/// See [`SlidingWindowRateLimiter`] for a common use case.
26///
27/// [`SlidingWindowRateLimiter`]: ../sliding_window/struct.SlidingWindowRateLimiter.html
28pub trait ThreadsafeRateLimiter {
29    fn wait_until_ready(&self) -> impl Future<Output = ()> + Send;
30}
31
32/// All [`RateLimiter`]s are [`ThreadsafeRateLimiter`]s, since they can pass `&mut self` as `&self`.
33///
34/// This blanket implementation saves implementers from having to define the trait manually.
35impl<L: ThreadsafeRateLimiter> RateLimiter for L {
36    fn wait_until_ready(&mut self) -> impl Future<Output = ()> + Send {
37        <Self as ThreadsafeRateLimiter>::wait_until_ready(self)
38    }
39}
40
41/// A threadsafe cost-based rate limiter, where each call can be of a variable cost.
42///
43/// Calls that cost more than all potentially available permits WILL deadlock permanently.
44///
45///  See [`TokenBucketRateLimiter`] for a common use case.
46///
47///  [`TokenBucketRateLimiter`]: ../token_bucket/struct.TokenBucketRateLimiter.html
48pub trait ThreadsafeVariableRateLimiter {
49    fn wait_with_cost(&self, cost: usize) -> impl Future<Output = ()> + Send;
50}
51
52/// All [`VariableCostRateLimiter`]s are [`ThreadsafeVariableRateLimiter`]s, since they can pass `&mut self` as `&self`.
53///
54/// This blanket implementation saves implementers from having to define the trait manually.
55impl<L: ThreadsafeVariableRateLimiter> VariableCostRateLimiter for L {
56    fn wait_with_cost(&mut self, cost: usize) -> impl Future<Output = ()> + Send {
57        <Self as ThreadsafeVariableRateLimiter>::wait_with_cost(self, cost)
58    }
59}