skp_ratelimit/storage/
entry.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
10pub struct StorageEntry {
11 pub count: u64,
13
14 pub window_start: u64,
16
17 pub tat: Option<u64>,
19
20 pub tokens: Option<f64>,
22
23 pub last_update: u64,
25
26 pub prev_count: Option<u64>,
28
29 #[serde(skip_serializing_if = "Option::is_none")]
31 pub timestamps: Option<Vec<u64>>,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub metadata: Option<Vec<u8>>,
36}
37
38impl StorageEntry {
39 pub fn new(count: u64, window_start: u64) -> Self {
41 Self {
42 count,
43 window_start,
44 tat: None,
45 tokens: None,
46 last_update: window_start,
47 prev_count: None,
48 timestamps: None,
49 metadata: None,
50 }
51 }
52
53 pub fn with_tat(tat: u64) -> Self {
55 Self {
56 count: 0,
57 window_start: tat,
58 tat: Some(tat),
59 tokens: None,
60 last_update: tat,
61 prev_count: None,
62 timestamps: None,
63 metadata: None,
64 }
65 }
66
67 pub fn with_tokens(tokens: f64, last_update: u64) -> Self {
69 Self {
70 count: 0,
71 window_start: last_update,
72 tat: None,
73 tokens: Some(tokens),
74 last_update,
75 prev_count: None,
76 timestamps: None,
77 metadata: None,
78 }
79 }
80
81 pub fn with_timestamps(timestamps: Vec<u64>) -> Self {
83 let now = timestamps.last().copied().unwrap_or(0);
84 Self {
85 count: timestamps.len() as u64,
86 window_start: now,
87 tat: None,
88 tokens: None,
89 last_update: now,
90 prev_count: None,
91 timestamps: Some(timestamps),
92 metadata: None,
93 }
94 }
95
96 pub fn set_tat(mut self, tat: u64) -> Self {
98 self.tat = Some(tat);
99 self
100 }
101
102 pub fn set_tokens(mut self, tokens: f64) -> Self {
104 self.tokens = Some(tokens);
105 self
106 }
107
108 pub fn set_last_update(mut self, last_update: u64) -> Self {
110 self.last_update = last_update;
111 self
112 }
113
114 pub fn set_prev_count(mut self, count: u64) -> Self {
116 self.prev_count = Some(count);
117 self
118 }
119
120 pub fn set_metadata(mut self, metadata: Vec<u8>) -> Self {
122 self.metadata = Some(metadata);
123 self
124 }
125
126 pub fn tokens_or_default(&self) -> f64 {
128 self.tokens.unwrap_or(0.0)
129 }
130
131 pub fn tat_or_default(&self) -> u64 {
133 self.tat.unwrap_or(0)
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn test_entry_new() {
143 let entry = StorageEntry::new(5, 1000);
144 assert_eq!(entry.count, 5);
145 assert_eq!(entry.window_start, 1000);
146 assert!(entry.tat.is_none());
147 assert!(entry.tokens.is_none());
148 }
149
150 #[test]
151 fn test_entry_with_tat() {
152 let entry = StorageEntry::with_tat(5000);
153 assert_eq!(entry.tat, Some(5000));
154 assert_eq!(entry.tat_or_default(), 5000);
155 }
156
157 #[test]
158 fn test_entry_with_tokens() {
159 let entry = StorageEntry::with_tokens(10.5, 2000);
160 assert_eq!(entry.tokens, Some(10.5));
161 assert_eq!(entry.tokens_or_default(), 10.5);
162 assert_eq!(entry.last_update, 2000);
163 }
164
165 #[test]
166 fn test_entry_with_timestamps() {
167 let timestamps = vec![1000, 2000, 3000];
168 let entry = StorageEntry::with_timestamps(timestamps.clone());
169 assert_eq!(entry.timestamps, Some(timestamps));
170 assert_eq!(entry.count, 3);
171 }
172
173 #[test]
174 fn test_entry_serialization() {
175 let entry = StorageEntry::new(10, 1000).set_tokens(5.5).set_tat(2000);
176 let json = serde_json::to_string(&entry).unwrap();
177 let deserialized: StorageEntry = serde_json::from_str(&json).unwrap();
178 assert_eq!(entry, deserialized);
179 }
180}