runlimit_core/limiter.rs
1use std::{error::Error, future::Future};
2
3use crate::{BatchDecision, Check, Decision, RateLimitPolicy};
4
5/// An asynchronous, backend-independent rate limiter.
6///
7/// Implementations evaluate one check or an atomic batch using their own
8/// authoritative time source. The returned futures are [`Send`], so adapters
9/// can await them on a multithreaded executor without Runlimit depending on a
10/// particular async runtime.
11///
12/// This trait uses return-position `impl Future` for static dispatch without
13/// requiring a boxed future. It is intentionally not object-safe. Applications
14/// that need runtime backend selection can implement `Limiter` for an
15/// application-owned enum and delegate to each variant. The executor
16/// portability guarantee also requires limiter and error types to be [`Send`]
17/// and [`Sync`], excluding deliberately single-thread-only implementations.
18pub trait Limiter: Send + Sync {
19 /// Policy algorithm supported by this backend.
20 type Policy: RateLimitPolicy;
21
22 /// Backend-specific operational failure.
23 type Error: Error + Send + Sync + 'static;
24
25 /// Evaluates and, when allowed, consumes one check.
26 fn check(
27 &self,
28 check: &Check<'_, Self::Policy>,
29 ) -> impl Future<Output = Result<Decision, Self::Error>> + Send;
30
31 /// Evaluates a batch atomically.
32 ///
33 /// If any check is denied, no check consumes quota. Allowed decisions
34 /// preserve the caller's input order.
35 fn check_all(
36 &self,
37 checks: &[Check<'_, Self::Policy>],
38 ) -> impl Future<Output = Result<BatchDecision, Self::Error>> + Send;
39}