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}