Skip to main content

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}