1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5pub struct Message {
6 pub id: Uuid,
7 pub body: String,
8 pub state: MessageState,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 pub lock_until: Option<String>, pub retry_count: u32,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
15#[serde(rename_all = "PascalCase")]
16pub enum MessageState {
17 Ready,
18 Processing,
19 Failed,
20}
21
22impl Message {
23 pub fn new(body: String) -> Self {
24 Self {
25 id: Uuid::now_v7(),
26 body,
27 state: MessageState::Ready,
28 lock_until: None,
29 retry_count: 0,
30 }
31 }
32}
33
34#[derive(Debug, Serialize)]
35pub struct AddMessageRequest {
36 pub body: String,
37}
38
39#[derive(Debug, Serialize)]
40pub struct GetMessagesRequest {
41 pub count: u32,
42}
43
44#[derive(Debug, Serialize)]
45pub struct DeleteMessagesRequest {
46 pub ids: Vec<Uuid>,
47}
48
49#[derive(Debug, Serialize)]
50pub struct RetryMessagesRequest {
51 pub ids: Vec<Uuid>,
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use serde_json;
58
59 #[test]
60 fn test_message_creation() {
61 let message = Message::new("Test message".to_string());
62
63 assert_eq!(message.body, "Test message");
64 assert_eq!(message.state, MessageState::Ready);
65 assert_eq!(message.retry_count, 0);
66
67 assert!(!message.id.to_string().is_empty());
69 }
70
71 #[test]
72 fn test_message_state_serialization() {
73 assert_eq!(
75 serde_json::to_string(&MessageState::Ready).unwrap(),
76 "\"Ready\""
77 );
78 assert_eq!(
79 serde_json::to_string(&MessageState::Processing).unwrap(),
80 "\"Processing\""
81 );
82 assert_eq!(
83 serde_json::to_string(&MessageState::Failed).unwrap(),
84 "\"Failed\""
85 );
86 }
87
88 #[test]
89 fn test_message_state_deserialization() {
90 assert_eq!(
92 serde_json::from_str::<MessageState>("\"Ready\"").unwrap(),
93 MessageState::Ready
94 );
95 assert_eq!(
96 serde_json::from_str::<MessageState>("\"Processing\"").unwrap(),
97 MessageState::Processing
98 );
99 assert_eq!(
100 serde_json::from_str::<MessageState>("\"Failed\"").unwrap(),
101 MessageState::Failed
102 );
103 }
104
105 #[test]
106 fn test_message_state_invalid_deserialization() {
107 let result = serde_json::from_str::<MessageState>("\"Invalid\"");
109 assert!(result.is_err());
110
111 let result = serde_json::from_str::<MessageState>("\"ready\""); assert!(result.is_err());
113
114 let result = serde_json::from_str::<MessageState>("\"READY\""); assert!(result.is_err());
116 }
117
118 #[test]
119 fn test_message_serialization() {
120 let message = Message::new("test body".to_string());
121
122 let json = serde_json::to_string(&message).unwrap();
123
124 assert!(json.contains("\"id\":"));
126 assert!(json.contains("\"body\":\"test body\""));
127 assert!(json.contains("\"state\":\"Ready\""));
128 assert!(json.contains("\"retry_count\":0"));
129
130 let deserialized: Message = serde_json::from_str(&json).unwrap();
132 assert_eq!(deserialized.body, message.body);
133 assert_eq!(deserialized.state, message.state);
134 assert_eq!(deserialized.retry_count, message.retry_count);
135 assert_eq!(deserialized.id, message.id);
136 }
137
138 #[test]
139 fn test_message_with_special_characters() {
140 let special_body = "Test with 🦀 emojis and \"quotes\" and \n newlines \t tabs";
141 let message = Message::new(special_body.to_string());
142
143 assert_eq!(message.body, special_body);
144
145 let json = serde_json::to_string(&message).unwrap();
147 let deserialized: Message = serde_json::from_str(&json).unwrap();
148 assert_eq!(deserialized.body, special_body);
149 }
150
151 #[test]
152 fn test_message_with_very_long_body() {
153 let long_body = "a".repeat(100_000);
154 let message = Message::new(long_body.clone());
155
156 assert_eq!(message.body, long_body);
157 assert_eq!(message.body.len(), 100_000);
158 }
159
160 #[test]
161 fn test_message_with_empty_body() {
162 let message = Message::new("".to_string());
163
164 assert_eq!(message.body, "");
165 assert_eq!(message.state, MessageState::Ready);
166 assert_eq!(message.retry_count, 0);
167 }
168
169 #[test]
170 fn test_request_response_structures() {
171 let add_req = AddMessageRequest {
173 body: "test message".to_string(),
174 };
175 let json = serde_json::to_string(&add_req).unwrap();
176 assert!(json.contains("\"body\":\"test message\""));
177
178 let get_req = GetMessagesRequest { count: 5 };
180 let json = serde_json::to_string(&get_req).unwrap();
181 assert!(json.contains("\"count\":5"));
182
183 use uuid::Uuid;
185 let id1 = Uuid::now_v7();
186 let id2 = Uuid::now_v7();
187 let delete_req = DeleteMessagesRequest {
188 ids: vec![id1, id2],
189 };
190 let json = serde_json::to_string(&delete_req).unwrap();
191 assert!(json.contains("\"ids\":"));
192
193 let retry_req = RetryMessagesRequest { ids: vec![id1] };
195 let json = serde_json::to_string(&retry_req).unwrap();
196 assert!(json.contains("\"ids\":"));
197 }
198
199 #[test]
200 fn test_response_deserialization() {
201 let message_json = r#"{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test","state":"Ready","lock_until":null,"retry_count":0}"#;
203 let message: Message = serde_json::from_str(message_json).unwrap();
204 assert_eq!(message.body, "test");
205 assert_eq!(message.state, MessageState::Ready);
206 assert_eq!(message.retry_count, 0);
207 assert_eq!(message.lock_until, None);
208
209 let messages_json = r#"[{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test1","state":"Processing","lock_until":null,"retry_count":1}]"#;
211 let messages: Vec<Message> = serde_json::from_str(messages_json).unwrap();
212 assert_eq!(messages.len(), 1);
213 assert_eq!(messages[0].body, "test1");
214 assert_eq!(messages[0].state, MessageState::Processing);
215
216 let success_response: String = serde_json::from_str(r#""Success""#).unwrap();
218 assert_eq!(success_response, "Success");
219
220 let health_response: String = serde_json::from_str(r#""Hello World""#).unwrap();
222 assert_eq!(health_response, "Hello World");
223 }
224
225 #[test]
226 fn test_malformed_response_deserialization() {
227 let malformed_json = r#"{"id": invalid}"#;
229 let result = serde_json::from_str::<Message>(malformed_json);
230 assert!(result.is_err());
231
232 let incomplete_json = r#"{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test"}"#; let result = serde_json::from_str::<Message>(incomplete_json);
235 assert!(result.is_err());
236
237 let wrong_type_json = r#"{"id":"0198fbd8-344e-7b70-841f-3fbd4b371e4c","body":"test","state":"Ready","retry_count":"not_a_number"}"#;
239 let result = serde_json::from_str::<Message>(wrong_type_json);
240 assert!(result.is_err());
241
242 let bad_uuid_json = r#"{"id":"invalid-uuid","body":"test","state":"Ready","lock_until":null,"retry_count":0}"#;
244 let result = serde_json::from_str::<Message>(bad_uuid_json);
245 assert!(result.is_err()); let bad_array_json = r#"[{"id":"invalid"}]"#;
249 let result = serde_json::from_str::<Vec<Message>>(bad_array_json);
250 assert!(result.is_err());
251 }
252}