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