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}