1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
20pub struct Message {
21 pub id: Uuid,
23 pub body: String,
25 pub state: MessageState,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub lock_until: Option<String>, pub retry_count: u32,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
56#[serde(rename_all = "PascalCase")]
57pub enum MessageState {
58 Ready,
60 Processing,
62 Failed,
64}
65
66impl Message {
67 pub fn new(body: String) -> Self {
91 Self {
92 id: Uuid::now_v7(),
93 body,
94 state: MessageState::Ready,
95 lock_until: None,
96 retry_count: 0,
97 }
98 }
99}
100
101#[derive(Debug, Serialize)]
105pub struct AddMessageRequest {
106 pub body: String,
107}
108
109#[derive(Debug, Serialize)]
111pub struct GetMessagesRequest {
112 pub count: u32,
113}
114
115#[derive(Debug, Serialize)]
117pub struct DeleteMessagesRequest {
118 pub ids: Vec<Uuid>,
119}
120
121#[derive(Debug, Serialize)]
123pub struct RetryMessagesRequest {
124 pub ids: Vec<Uuid>,
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use serde_json;
131
132 #[test]
133 fn test_message_creation() {
134 let message = Message::new("Test message".to_string());
135
136 assert_eq!(message.body, "Test message");
137 assert_eq!(message.state, MessageState::Ready);
138 assert_eq!(message.retry_count, 0);
139
140 assert!(!message.id.to_string().is_empty());
142 }
143
144 #[test]
145 fn test_message_state_serialization() {
146 assert_eq!(
148 serde_json::to_string(&MessageState::Ready).unwrap(),
149 "\"Ready\""
150 );
151 assert_eq!(
152 serde_json::to_string(&MessageState::Processing).unwrap(),
153 "\"Processing\""
154 );
155 assert_eq!(
156 serde_json::to_string(&MessageState::Failed).unwrap(),
157 "\"Failed\""
158 );
159 }
160
161 #[test]
162 fn test_message_state_deserialization() {
163 assert_eq!(
165 serde_json::from_str::<MessageState>("\"Ready\"").unwrap(),
166 MessageState::Ready
167 );
168 assert_eq!(
169 serde_json::from_str::<MessageState>("\"Processing\"").unwrap(),
170 MessageState::Processing
171 );
172 assert_eq!(
173 serde_json::from_str::<MessageState>("\"Failed\"").unwrap(),
174 MessageState::Failed
175 );
176 }
177
178 #[test]
179 fn test_message_state_invalid_deserialization() {
180 let result = serde_json::from_str::<MessageState>("\"Invalid\"");
182 assert!(result.is_err());
183
184 let result = serde_json::from_str::<MessageState>("\"ready\""); assert!(result.is_err());
186
187 let result = serde_json::from_str::<MessageState>("\"READY\""); assert!(result.is_err());
189 }
190
191 #[test]
192 fn test_message_serialization() {
193 let message = Message::new("test body".to_string());
194
195 let json = serde_json::to_string(&message).unwrap();
196
197 assert!(json.contains("\"id\":"));
199 assert!(json.contains("\"body\":\"test body\""));
200 assert!(json.contains("\"state\":\"Ready\""));
201 assert!(json.contains("\"retry_count\":0"));
202
203 let deserialized: Message = serde_json::from_str(&json).unwrap();
205 assert_eq!(deserialized.body, message.body);
206 assert_eq!(deserialized.state, message.state);
207 assert_eq!(deserialized.retry_count, message.retry_count);
208 assert_eq!(deserialized.id, message.id);
209 }
210
211 #[test]
212 fn test_message_with_special_characters() {
213 let special_body = "Test with 🦀 emojis and \"quotes\" and \n newlines \t tabs";
214 let message = Message::new(special_body.to_string());
215
216 assert_eq!(message.body, special_body);
217
218 let json = serde_json::to_string(&message).unwrap();
220 let deserialized: Message = serde_json::from_str(&json).unwrap();
221 assert_eq!(deserialized.body, special_body);
222 }
223
224 #[test]
225 fn test_message_with_very_long_body() {
226 let long_body = "a".repeat(100_000);
227 let message = Message::new(long_body.clone());
228
229 assert_eq!(message.body, long_body);
230 assert_eq!(message.body.len(), 100_000);
231 }
232
233 #[test]
234 fn test_message_with_empty_body() {
235 let message = Message::new("".to_string());
236
237 assert_eq!(message.body, "");
238 assert_eq!(message.state, MessageState::Ready);
239 assert_eq!(message.retry_count, 0);
240 }
241
242 #[test]
243 fn test_request_response_structures() {
244 let add_req = AddMessageRequest {
246 body: "test message".to_string(),
247 };
248 let json = serde_json::to_string(&add_req).unwrap();
249 assert!(json.contains("\"body\":\"test message\""));
250
251 let get_req = GetMessagesRequest { count: 5 };
253 let json = serde_json::to_string(&get_req).unwrap();
254 assert!(json.contains("\"count\":5"));
255
256 use uuid::Uuid;
258 let id1 = Uuid::now_v7();
259 let id2 = Uuid::now_v7();
260 let delete_req = DeleteMessagesRequest {
261 ids: vec![id1, id2],
262 };
263 let json = serde_json::to_string(&delete_req).unwrap();
264 assert!(json.contains("\"ids\":"));
265
266 let retry_req = RetryMessagesRequest { ids: vec![id1] };
268 let json = serde_json::to_string(&retry_req).unwrap();
269 assert!(json.contains("\"ids\":"));
270 }
271
272 #[test]
273 fn test_response_deserialization() {
274 let message_json = r#"{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test","state":"Ready","lock_until":null,"retry_count":0}"#;
276 let message: Message = serde_json::from_str(message_json).unwrap();
277 assert_eq!(message.body, "test");
278 assert_eq!(message.state, MessageState::Ready);
279 assert_eq!(message.retry_count, 0);
280 assert_eq!(message.lock_until, None);
281
282 let messages_json = r#"[{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test1","state":"Processing","lock_until":null,"retry_count":1}]"#;
284 let messages: Vec<Message> = serde_json::from_str(messages_json).unwrap();
285 assert_eq!(messages.len(), 1);
286 assert_eq!(messages[0].body, "test1");
287 assert_eq!(messages[0].state, MessageState::Processing);
288
289 let success_response: String = serde_json::from_str(r#""Success""#).unwrap();
291 assert_eq!(success_response, "Success");
292
293 let health_response: String = serde_json::from_str(r#""Hello World""#).unwrap();
295 assert_eq!(health_response, "Hello World");
296 }
297
298 #[test]
299 fn test_malformed_response_deserialization() {
300 let malformed_json = r#"{"id": invalid}"#;
302 let result = serde_json::from_str::<Message>(malformed_json);
303 assert!(result.is_err());
304
305 let incomplete_json = r#"{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test"}"#; let result = serde_json::from_str::<Message>(incomplete_json);
308 assert!(result.is_err());
309
310 let wrong_type_json = r#"{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test","state":"Ready","retry_count":"not_a_number"}"#;
312 let result = serde_json::from_str::<Message>(wrong_type_json);
313 assert!(result.is_err());
314
315 let bad_uuid_json = r#"{"id":"invalid-uuid","body":"test","state":"Ready","lock_until":null,"retry_count":0}"#;
317 let result = serde_json::from_str::<Message>(bad_uuid_json);
318 assert!(result.is_err()); let bad_array_json = r#"[{"id":"invalid"}]"#;
322 let result = serde_json::from_str::<Vec<Message>>(bad_array_json);
323 assert!(result.is_err());
324 }
325}