1pub mod request;
15pub mod response;
16pub mod types;
17
18pub use request::Request;
20pub use response::Response;
21pub use types::{BatchRequest, BatchResponse, DbStats, Direction, Filter, QueryOptions, Record, RecordSet};
22
23#[cfg(test)]
24mod tests {
25 use crate::types::{BatchRequest, BatchResponse, DbStats, Direction, Filter, QueryOptions, Record, RecordSet};
26 use crate::{Request, Response};
27 use serde_json::json;
28 use std::collections::HashMap;
29
30 fn test_serialization_json<T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + std::fmt::Debug>(
34 value: T,
35 ) -> T {
36 let serialized = serde_json::to_string(&value).expect("Failed to serialize to JSON");
37 let deserialized = serde_json::from_str(&serialized).expect("Failed to deserialize from JSON");
38 assert_eq!(value, deserialized, "Data loss during JSON serialization roundtrip");
39 deserialized
40 }
41
42 fn test_serialization_bincode<T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + std::fmt::Debug>(
44 value: T,
45 ) -> T {
46 let serialized = bincode::serialize(&value).expect("Failed to serialize");
47 let deserialized = bincode::deserialize(&serialized).expect("Failed to deserialize");
48 assert_eq!(value, deserialized, "Data loss during bincode serialization roundtrip");
49 deserialized
50 }
51
52 #[test]
53 fn test_record_serialization() {
54 let mut record = Record::new();
55 record.insert("name".to_string(), json!("John Doe"));
56 record.insert("age".to_string(), json!(30));
57 record.insert("active".to_string(), json!(true));
58 record.insert("scores".to_string(), json!([85, 90, 78]));
59
60 let deserialized = test_serialization_json(record);
61 assert_eq!(deserialized["name"], json!("John Doe"));
62 }
63
64 #[test]
65 fn test_recordset_serialization() {
66 let mut record1 = Record::new();
67 record1.insert("id".to_string(), json!(1));
68 record1.insert("name".to_string(), json!("Record 1"));
69
70 let mut record2 = Record::new();
71 record2.insert("id".to_string(), json!(2));
72 record2.insert("name".to_string(), json!("Record 2"));
73
74 let recordset = RecordSet {
75 records: vec![record1, record2],
76 };
77
78 test_serialization_json(recordset);
79 }
80
81 #[test]
82 fn test_filter_serialization() {
83 let filters = vec![
85 Filter::Equals {
86 field: "status".to_string(),
87 value: json!("active"),
88 },
89 Filter::NotEquals {
90 field: "deleted".to_string(),
91 value: json!(true),
92 },
93 Filter::GreaterThan {
94 field: "age".to_string(),
95 value: 18.0,
96 },
97 Filter::LessThan {
98 field: "price".to_string(),
99 value: 100.0,
100 },
101 Filter::In {
102 field: "category".to_string(),
103 values: vec![json!("electronics"), json!("books")],
104 },
105 Filter::And(vec![
106 Filter::Equals {
107 field: "active".to_string(),
108 value: json!(true),
109 },
110 Filter::GreaterThan {
111 field: "score".to_string(),
112 value: 70.0,
113 },
114 ]),
115 Filter::Or(vec![
116 Filter::Equals {
117 field: "type".to_string(),
118 value: json!("premium"),
119 },
120 Filter::Equals {
121 field: "special".to_string(),
122 value: json!(true),
123 },
124 ]),
125 ];
126
127 for filter in filters {
128 test_serialization_json(filter);
129 }
130 }
131
132 #[test]
133 fn test_query_options_serialization() {
134 let options = QueryOptions {
135 sort_by: Some(("created_at".to_string(), Direction::Desc)),
136 limit: Some(100),
137 offset: Some(20),
138 };
139
140 test_serialization_bincode(options);
142 }
143
144 #[test]
145 fn test_db_stats_serialization() {
146 let stats = DbStats {
147 collection_count: 5,
148 record_count: 1000,
149 };
150
151 test_serialization_bincode(stats);
153 }
154
155 #[test]
156 fn test_batch_request_serialization() {
157 let mut requests = HashMap::new();
158 requests.insert("key1".to_string(), ("testdb".to_string(), "users".to_string(), "user_1".to_string()));
159 requests.insert("key2".to_string(), ("testdb".to_string(), "products".to_string(), "product_1".to_string()));
160
161 let batch_request = BatchRequest { requests };
162 test_serialization_bincode(batch_request);
164 }
165
166 #[test]
167 fn test_batch_response_serialization() {
168 let mut record1 = Record::new();
169 record1.insert("id".to_string(), json!("user_1"));
170 record1.insert("name".to_string(), json!("John Doe"));
171
172 let mut record2 = Record::new();
173 record2.insert("id".to_string(), json!("product_1"));
174 record2.insert("name".to_string(), json!("Widget"));
175
176 let mut results = HashMap::new();
177 results.insert("key1".to_string(), Some(record1));
178 results.insert("key2".to_string(), Some(record2));
179 results.insert("key3".to_string(), None); let batch_response = BatchResponse { results };
182 test_serialization_json(batch_response);
183 }
184
185 #[test]
186 fn test_request_serialization() {
187 let requests = vec![
189 Request::CreateDatabase { db_name: "testdb".to_string() },
191 Request::DropDatabase { db_name: "testdb".to_string() },
192 Request::ListDatabases,
193
194 Request::ListCollections,
196 Request::CreateCollection { db_name: "users".to_string(), collection_name: "users".to_string() },
197 Request::DropCollection { db_name: "users".to_string(), collection_name: "users".to_string() },
198 Request::GetStats,
199 Request::Flush,
200
201 Request::CreateIndex {
203 db_name: "users".to_string(),
204 collection: "users".to_string(),
205 field_name: "email".to_string(),
206 },
207 Request::DropIndex {
208 db_name: "users".to_string(),
209 collection: "users".to_string(),
210 field_name: "email".to_string(),
211 },
212 Request::ListIndexes {
213 db_name: "users".to_string(),
214 collection: "users".to_string(),
215 },
216
217 Request::CreateRecord {
219 db_name: "users".to_string(),
220 collection: "users".to_string(),
221 record_id: "user123".to_string(),
222 data: {
223 let mut record = Record::new();
224 record.insert("name".to_string(), json!("Alice"));
225 record.insert("email".to_string(), json!("alice@example.com"));
226 record
227 },
228 },
229 Request::UpdateRecord {
230 db_name: "users".to_string(),
231 collection: "users".to_string(),
232 record_id: "user123".to_string(),
233 data: {
234 let mut record = Record::new();
235 record.insert("active".to_string(), json!(false));
236 record
237 },
238 },
239 Request::UpsertRecord {
240 db_name: "users".to_string(),
241 collection: "users".to_string(),
242 record_id: "user123".to_string(),
243 data: {
244 let mut record = Record::new();
245 record.insert("name".to_string(), json!("Alice"));
246 record.insert("email".to_string(), json!("updated@example.com"));
247 record
248 },
249 },
250 Request::GetRecord {
251 db_name: "users".to_string(),
252 collection: "users".to_string(),
253 record_id: "user123".to_string(),
254 },
255 Request::DeleteRecord {
256 db_name: "users".to_string(),
257 collection: "users".to_string(),
258 record_id: "user123".to_string(),
259 cascade: true,
260 },
261 Request::GetLastInsertId,
262
263 Request::FindRecords {
265 db_name: "users".to_string(),
266 collection: "users".to_string(),
267 filter: crate::types::Filter::And(vec![
268 crate::types::Filter::Equals {
269 field: "active".to_string(),
270 value: json!(true),
271 },
272 crate::types::Filter::GreaterThan {
273 field: "age".to_string(),
274 value: 21.0,
275 },
276 ]),
277 options: Some(crate::types::QueryOptions {
278 sort_by: Some(("created_at".to_string(), crate::types::Direction::Desc)),
279 limit: Some(50),
280 offset: Some(0),
281 }),
282 },
283 Request::CountRecords {
284 db_name: "users".to_string(),
285 collection: "users".to_string(),
286 filter: crate::types::Filter::Equals {
287 field: "active".to_string(),
288 value: json!(true),
289 },
290 },
291 Request::GetRecordWithRelated {
292 db_name: "users".to_string(),
293 primary_collection: "orders".to_string(),
294 primary_record_id: "order123".to_string(),
295 relation_key_field: "user_id".to_string(),
296 related_collection: "users".to_string(),
297 },
298 Request::ExecuteBatchGet({
299 let mut requests = HashMap::new();
300 requests.insert("key1".to_string(), ("testdb".to_string(), "users".to_string(), "user123".to_string()));
301 requests.insert("key2".to_string(), ("testdb".to_string(), "products".to_string(), "product456".to_string()));
302 crate::types::BatchRequest { requests }
303 }),
304 ];
305
306 for request in requests {
307 test_serialization_json(request);
308 }
309 }
310
311 #[test]
312 fn test_response_serialization() {
313 let responses = vec![
315 Response::Success,
317 Response::Error("Invalid request format".to_string()),
318
319 Response::DatabaseList(vec![
321 "testdb".to_string(),
322 "userdb".to_string(),
323 "analytics".to_string(),
324 ]),
325 Response::DatabaseCreated(true),
326 Response::DatabaseDropped(true),
327
328 Response::CollectionList(vec![
330 "users".to_string(),
331 "products".to_string(),
332 "orders".to_string(),
333 ]),
334 Response::Stats(crate::types::DbStats {
335 collection_count: 3,
336 record_count: 1500,
337 }),
338 Response::IndexList(vec![
339 "email".to_string(),
340 "username".to_string(),
341 ]),
342
343 Response::Record(Some({
345 let mut record = Record::new();
346 record.insert("id".to_string(), json!("user123"));
347 record.insert("name".to_string(), json!("Bob"));
348 record.insert("email".to_string(), json!("bob@example.com"));
349 record
350 })),
351 Response::Record(None), Response::RecordSet(crate::types::RecordSet {
353 records: vec![
354 {
355 let mut record = Record::new();
356 record.insert("id".to_string(), json!("1"));
357 record.insert("name".to_string(), json!("Item 1"));
358 record
359 },
360 {
361 let mut record = Record::new();
362 record.insert("id".to_string(), json!("2"));
363 record.insert("name".to_string(), json!("Item 2"));
364 record
365 },
366 ],
367 }),
368 Response::RecordCount(42),
369 Response::RecordDeleted(true),
370 Response::LastInsertId(123),
371 Response::RecordWithRelated(Some(({
372 let mut order = Record::new();
373 order.insert("id".to_string(), json!("order123"));
374 order.insert("amount".to_string(), json!(99.99));
375 order
376 }, {
377 let mut user = Record::new();
378 user.insert("id".to_string(), json!("user456"));
379 user.insert("name".to_string(), json!("Charlie"));
380 user
381 }))),
382 Response::RecordWithRelated(None), Response::BatchResponse({
384 let mut results = HashMap::new();
385 let mut user_record = Record::new();
386 user_record.insert("id".to_string(), json!("user123"));
387 user_record.insert("name".to_string(), json!("Dave"));
388
389 let mut product_record = Record::new();
390 product_record.insert("id".to_string(), json!("product456"));
391 product_record.insert("name".to_string(), json!("Gadget"));
392
393 results.insert("key1".to_string(), Some(user_record));
394 results.insert("key2".to_string(), Some(product_record));
395 results.insert("key3".to_string(), None); crate::types::BatchResponse { results }
398 }),
399 ];
400
401 for response in responses {
402 test_serialization_json(response);
403 }
404 }
405}