throttlecrab_server/
types.rs

1//! Common types used across the server
2//!
3//! This module defines the core request and response types that are
4//! shared between different transport protocols and the actor system.
5//!
6//! # Type Conversions
7//!
8//! Each transport protocol converts between its protocol-specific types
9//! and these common types:
10//!
11//! - **HTTP**: JSON serialization
12//! - **gRPC**: Protocol Buffers
13
14use serde::{Deserialize, Serialize};
15use std::time::SystemTime;
16use throttlecrab::RateLimitResult;
17
18/// Internal rate limit request structure
19///
20/// This is the common request format used by all transports
21/// after parsing their protocol-specific formats.
22///
23/// # Fields
24///
25/// - `key`: Unique identifier for the rate limit (e.g., "user:123", "api:endpoint")
26/// - `max_burst`: Maximum tokens available at once (burst capacity)
27/// - `count_per_period`: Total tokens replenished per period
28/// - `period`: Time period in seconds for token replenishment
29/// - `quantity`: Number of tokens to consume (typically 1)
30/// - `timestamp`: Request timestamp for consistent rate limiting
31#[derive(Debug, Clone)]
32pub struct ThrottleRequest {
33    /// The key to rate limit (e.g., "user:123", "ip:192.168.1.1")
34    pub key: String,
35    /// Maximum burst capacity (tokens available at once)
36    pub max_burst: i64,
37    /// Tokens replenished per period
38    pub count_per_period: i64,
39    /// Period in seconds for token replenishment
40    pub period: i64,
41    /// Number of tokens to consume (default: 1)
42    pub quantity: i64,
43    /// Request timestamp for consistent rate limiting
44    pub timestamp: SystemTime,
45}
46
47/// Rate limit response structure
48///
49/// This is the common response format returned by all transports
50/// after checking a rate limit.
51///
52/// # Response Interpretation
53///
54/// - If `allowed` is true: The request can proceed
55/// - If `allowed` is false: The request should be rejected
56///   - Check `retry_after` to know when to retry
57///   - Check `reset_after` to know when the bucket resets
58///
59/// # Example
60///
61/// ```json
62/// {
63///   "allowed": false,
64///   "limit": 10,
65///   "remaining": 0,
66///   "retry_after": 30,
67///   "reset_after": 60
68/// }
69/// ```
70///
71/// This response indicates the request was denied, no tokens remain,
72/// retry in 30 seconds, and the bucket fully resets in 60 seconds.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct ThrottleResponse {
75    /// Whether the request is allowed
76    pub allowed: bool,
77    /// Maximum burst capacity
78    pub limit: i64,
79    /// Tokens remaining in the bucket
80    pub remaining: i64,
81    /// Seconds until the bucket fully resets
82    pub reset_after: i64,
83    /// Seconds until the next request can be made (0 if allowed)
84    pub retry_after: i64,
85}
86
87impl From<(bool, RateLimitResult)> for ThrottleResponse {
88    fn from((allowed, result): (bool, RateLimitResult)) -> Self {
89        ThrottleResponse {
90            allowed,
91            limit: result.limit,
92            remaining: result.remaining,
93            reset_after: result.reset_after.as_secs() as i64,
94            retry_after: result.retry_after.as_secs() as i64,
95        }
96    }
97}