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