1use std::marker::PhantomData;
15
16use serde::Serialize;
17use serde::de::DeserializeOwned;
18
19use noxu_db::DatabaseEntry;
20
21use crate::Result;
22use crate::entry_binding::{EntityBinding, EntryBinding};
23use crate::serial::serde_binding::SerdeBinding;
24use crate::tuple::sort_key::SortKey;
25use crate::tuple::{TupleInput, TupleOutput};
26
27pub struct TupleSerdeBinding<K, V> {
59 key_extractor: Box<dyn Fn(&V) -> K + Send + Sync>,
61 entity_creator: Box<dyn Fn(K, V) -> V + Send + Sync>,
63 _phantom: PhantomData<(K, V)>,
64}
65
66impl<K, V> TupleSerdeBinding<K, V>
67where
68 K: SortKey,
69 V: Serialize + DeserializeOwned,
70{
71 pub fn new<FKey, FCreate>(
76 key_extractor: FKey,
77 entity_creator: FCreate,
78 ) -> Self
79 where
80 FKey: Fn(&V) -> K + Send + Sync + 'static,
81 FCreate: Fn(K, V) -> V + Send + Sync + 'static,
82 {
83 Self {
84 key_extractor: Box::new(key_extractor),
85 entity_creator: Box::new(entity_creator),
86 _phantom: PhantomData,
87 }
88 }
89}
90
91impl<K, V> std::fmt::Debug for TupleSerdeBinding<K, V> {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 f.debug_struct("TupleSerdeBinding")
94 .field("key_type", &std::any::type_name::<K>())
95 .field("value_type", &std::any::type_name::<V>())
96 .finish()
97 }
98}
99
100impl<K, V> EntityBinding<V> for TupleSerdeBinding<K, V>
101where
102 K: SortKey,
103 V: Serialize + DeserializeOwned,
104{
105 fn entry_to_object(
106 &self,
107 key: &DatabaseEntry,
108 data: &DatabaseEntry,
109 ) -> Result<V> {
110 let mut inp = TupleInput::new(key.data());
111 let k = K::decode_sort_key(&mut inp)?;
112 let data_binding = SerdeBinding::<V>::new();
113 let v = data_binding.entry_to_object(data)?;
114 Ok((self.entity_creator)(k, v))
115 }
116
117 fn object_to_key(&self, object: &V, key: &mut DatabaseEntry) -> Result<()> {
118 let mut out = TupleOutput::new();
119 let k = (self.key_extractor)(object);
120 k.encode_sort_key(&mut out);
121 key.set_data_vec(out.into_vec());
122 Ok(())
123 }
124
125 fn object_to_data(
126 &self,
127 object: &V,
128 data: &mut DatabaseEntry,
129 ) -> Result<()> {
130 let data_binding = SerdeBinding::<V>::new();
131 data_binding.object_to_entry(object, data)
132 }
133}
134
135pub struct TupleSerdeKeyDataBinding<K, V> {
141 _phantom: PhantomData<(K, V)>,
142}
143
144impl<K, V> TupleSerdeKeyDataBinding<K, V> {
145 pub fn new() -> Self {
147 Self { _phantom: PhantomData }
148 }
149}
150
151impl<K, V> Default for TupleSerdeKeyDataBinding<K, V> {
152 fn default() -> Self {
153 Self::new()
154 }
155}
156
157impl<K, V> Clone for TupleSerdeKeyDataBinding<K, V> {
158 fn clone(&self) -> Self {
159 Self::new()
160 }
161}
162
163impl<K, V> std::fmt::Debug for TupleSerdeKeyDataBinding<K, V> {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 f.debug_struct("TupleSerdeKeyDataBinding")
166 .field("key_type", &std::any::type_name::<K>())
167 .field("value_type", &std::any::type_name::<V>())
168 .finish()
169 }
170}
171
172impl<K, V> EntityBinding<(K, V)> for TupleSerdeKeyDataBinding<K, V>
173where
174 K: SortKey + Clone,
175 V: Serialize + DeserializeOwned + Clone,
176{
177 fn entry_to_object(
178 &self,
179 key: &DatabaseEntry,
180 data: &DatabaseEntry,
181 ) -> Result<(K, V)> {
182 let mut inp = TupleInput::new(key.data());
183 let k = K::decode_sort_key(&mut inp)?;
184 let data_binding = SerdeBinding::<V>::new();
185 let v = data_binding.entry_to_object(data)?;
186 Ok((k, v))
187 }
188
189 fn object_to_key(
190 &self,
191 object: &(K, V),
192 key: &mut DatabaseEntry,
193 ) -> Result<()> {
194 let mut out = TupleOutput::new();
195 object.0.encode_sort_key(&mut out);
196 key.set_data_vec(out.into_vec());
197 Ok(())
198 }
199
200 fn object_to_data(
201 &self,
202 object: &(K, V),
203 data: &mut DatabaseEntry,
204 ) -> Result<()> {
205 let data_binding = SerdeBinding::<V>::new();
206 data_binding.object_to_entry(&object.1, data)
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213 use serde::{Deserialize, Serialize};
214
215 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
216 struct Employee {
217 id: u64,
218 name: String,
219 department: String,
220 }
221
222 #[test]
223 fn test_tuple_serde_binding_round_trip() {
224 let binding = TupleSerdeBinding::<u64, Employee>::new(
225 |emp| emp.id,
226 |_key, data| data,
227 );
228
229 let emp = Employee {
230 id: 42,
231 name: "Alice".to_string(),
232 department: "Engineering".to_string(),
233 };
234
235 let mut key_entry = DatabaseEntry::new();
236 let mut data_entry = DatabaseEntry::new();
237
238 binding.object_to_key(&emp, &mut key_entry).unwrap();
239 binding.object_to_data(&emp, &mut data_entry).unwrap();
240
241 let decoded = binding.entry_to_object(&key_entry, &data_entry).unwrap();
242 assert_eq!(decoded, emp);
243 }
244
245 #[test]
246 fn test_tuple_serde_binding_key_extraction() {
247 let binding = TupleSerdeBinding::<u64, Employee>::new(
248 |emp| emp.id,
249 |_key, data| data,
250 );
251
252 let emp = Employee {
253 id: 99,
254 name: "Bob".to_string(),
255 department: "Sales".to_string(),
256 };
257
258 let mut key_entry = DatabaseEntry::new();
259 binding.object_to_key(&emp, &mut key_entry).unwrap();
260
261 let mut inp = TupleInput::new(key_entry.data());
263 let key: u64 = u64::decode_sort_key(&mut inp).unwrap();
264 assert_eq!(key, 99);
265 }
266
267 #[test]
269 fn test_u64_key_is_8_bytes_fixed_width() {
270 let binding = TupleSerdeBinding::<u64, Employee>::new(
271 |emp| emp.id,
272 |_key, data| data,
273 );
274 for id in [0u64, 1, 2, 10, 100, u64::MAX] {
275 let emp =
276 Employee { id, name: String::new(), department: String::new() };
277 let mut key_entry = DatabaseEntry::new();
278 binding.object_to_key(&emp, &mut key_entry).unwrap();
279 assert_eq!(
280 key_entry.data().len(),
281 8,
282 "u64 key must be 8 bytes (id={})",
283 id
284 );
285 }
286 }
287
288 #[test]
291 fn test_u64_key_sort_order_preserved() {
292 let binding = TupleSerdeBinding::<u64, Employee>::new(
293 |emp| emp.id,
294 |_key, data| data,
295 );
296
297 let key_bytes = |id: u64| {
298 let emp =
299 Employee { id, name: String::new(), department: String::new() };
300 let mut key_entry = DatabaseEntry::new();
301 binding.object_to_key(&emp, &mut key_entry).unwrap();
302 key_entry.get_data().unwrap().to_vec()
303 };
304
305 let b0 = key_bytes(0);
306 let b1 = key_bytes(1);
307 let b2 = key_bytes(2);
308 let b10 = key_bytes(10);
309 let bmax = key_bytes(u64::MAX);
310
311 assert!(b0 < b1, "0 < 1");
312 assert!(b1 < b2, "1 < 2");
313 assert!(b2 < b10, "2 < 10");
314 assert!(b10 < bmax, "10 < MAX");
315 }
316
317 #[test]
319 fn test_i64_key_sort_order_preserved() {
320 let binding = TupleSerdeBinding::<i64, Employee>::new(
321 |emp| emp.id as i64,
322 |_key, data| data,
323 );
324
325 let key_bytes = |id: i64| {
326 let emp = Employee {
327 id: id as u64,
328 name: String::new(),
329 department: String::new(),
330 };
331 let mut key_entry = DatabaseEntry::new();
332 binding.object_to_key(&emp, &mut key_entry).unwrap();
333 key_entry.get_data().unwrap().to_vec()
334 };
335
336 let vals = [i64::MIN, -1000i64, -1, 0, 1, 1000, i64::MAX];
337 for w in vals.windows(2) {
338 assert!(
339 key_bytes(w[0]) < key_bytes(w[1]),
340 "i64 sort order: {} should be < {}",
341 w[0],
342 w[1]
343 );
344 }
345 }
346
347 #[test]
349 fn test_string_key_sort_order_preserved() {
350 let binding = TupleSerdeBinding::<String, Employee>::new(
351 |emp| emp.name.clone(),
352 |_key, data| data,
353 );
354
355 let key_bytes = |name: &str| {
356 let emp = Employee {
357 id: 0,
358 name: name.to_string(),
359 department: String::new(),
360 };
361 let mut key_entry = DatabaseEntry::new();
362 binding.object_to_key(&emp, &mut key_entry).unwrap();
363 key_entry.get_data().unwrap().to_vec()
364 };
365
366 assert!(key_bytes("a") < key_bytes("b"));
367 assert!(key_bytes("abc") < key_bytes("abd"));
368 assert!(key_bytes("a") < key_bytes("aa"));
369 assert!(key_bytes("") < key_bytes("a"));
370 }
371
372 #[test]
373 fn test_key_data_binding_round_trip() {
374 let binding = TupleSerdeKeyDataBinding::<u32, String>::new();
375
376 let entity = (42u32, "hello".to_string());
377 let mut key_entry = DatabaseEntry::new();
378 let mut data_entry = DatabaseEntry::new();
379
380 binding.object_to_key(&entity, &mut key_entry).unwrap();
381 binding.object_to_data(&entity, &mut data_entry).unwrap();
382
383 let decoded = binding.entry_to_object(&key_entry, &data_entry).unwrap();
384 assert_eq!(decoded, entity);
385 }
386
387 #[test]
389 fn test_key_data_binding_u32_sort_order() {
390 let binding = TupleSerdeKeyDataBinding::<u32, String>::new();
391
392 let key_bytes = |k: u32| {
393 let entity = (k, String::new());
394 let mut key_entry = DatabaseEntry::new();
395 binding.object_to_key(&entity, &mut key_entry).unwrap();
396 key_entry.get_data().unwrap().to_vec()
397 };
398
399 let vals = [0u32, 1, 2, 10, 100, 1000, u32::MAX];
400 for w in vals.windows(2) {
401 assert!(
402 key_bytes(w[0]) < key_bytes(w[1]),
403 "{} should sort before {}",
404 w[0],
405 w[1]
406 );
407 }
408 }
409
410 #[test]
411 fn test_key_data_binding_with_struct() {
412 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
413 struct Product {
414 name: String,
415 price: f64,
416 }
417
418 let binding = TupleSerdeKeyDataBinding::<u64, Product>::new();
419
420 let entity =
421 (100u64, Product { name: "Widget".to_string(), price: 9.99 });
422
423 let mut key_entry = DatabaseEntry::new();
424 let mut data_entry = DatabaseEntry::new();
425
426 binding.object_to_key(&entity, &mut key_entry).unwrap();
427 binding.object_to_data(&entity, &mut data_entry).unwrap();
428
429 let decoded = binding.entry_to_object(&key_entry, &data_entry).unwrap();
430 assert_eq!(decoded, entity);
431 }
432
433 #[test]
434 fn test_key_data_binding_default() {
435 let binding = TupleSerdeKeyDataBinding::<u32, String>::default();
436 let entity = (1u32, "test".to_string());
437 let mut key_entry = DatabaseEntry::new();
438 let mut data_entry = DatabaseEntry::new();
439 binding.object_to_key(&entity, &mut key_entry).unwrap();
440 binding.object_to_data(&entity, &mut data_entry).unwrap();
441 let decoded = binding.entry_to_object(&key_entry, &data_entry).unwrap();
442 assert_eq!(decoded, entity);
443 }
444
445 #[test]
446 fn test_key_data_binding_clone() {
447 let binding = TupleSerdeKeyDataBinding::<u32, String>::new();
448 let cloned = binding.clone();
449 let entity = (7u32, "clone".to_string());
450 let mut key_entry = DatabaseEntry::new();
451 let mut data_entry = DatabaseEntry::new();
452 binding.object_to_key(&entity, &mut key_entry).unwrap();
453 binding.object_to_data(&entity, &mut data_entry).unwrap();
454 let decoded = cloned.entry_to_object(&key_entry, &data_entry).unwrap();
455 assert_eq!(decoded, entity);
456 }
457
458 #[test]
459 fn test_key_data_binding_debug() {
460 let binding = TupleSerdeKeyDataBinding::<u32, String>::new();
461 let debug = format!("{:?}", binding);
462 assert!(debug.contains("TupleSerdeKeyDataBinding"));
463 }
464
465 #[test]
466 fn test_tuple_serde_binding_debug() {
467 let binding = TupleSerdeBinding::<u64, Employee>::new(
468 |emp| emp.id,
469 |_key, data| data,
470 );
471 let debug = format!("{:?}", binding);
472 assert!(debug.contains("TupleSerdeBinding"));
473 }
474
475 #[test]
476 fn test_key_data_with_option_value() {
477 let binding = TupleSerdeKeyDataBinding::<String, Option<u64>>::new();
478 let entity = ("key".to_string(), Some(42u64));
479 let mut key_entry = DatabaseEntry::new();
480 let mut data_entry = DatabaseEntry::new();
481 binding.object_to_key(&entity, &mut key_entry).unwrap();
482 binding.object_to_data(&entity, &mut data_entry).unwrap();
483 let decoded = binding.entry_to_object(&key_entry, &data_entry).unwrap();
484 assert_eq!(decoded, entity);
485 }
486
487 #[test]
488 fn test_key_data_with_vec_value() {
489 let binding = TupleSerdeKeyDataBinding::<u32, Vec<String>>::new();
490 let entity = (1u32, vec!["a".to_string(), "b".to_string()]);
491 let mut key_entry = DatabaseEntry::new();
492 let mut data_entry = DatabaseEntry::new();
493 binding.object_to_key(&entity, &mut key_entry).unwrap();
494 binding.object_to_data(&entity, &mut data_entry).unwrap();
495 let decoded = binding.entry_to_object(&key_entry, &data_entry).unwrap();
496 assert_eq!(decoded, entity);
497 }
498
499 #[test]
500 fn test_entity_creator_transforms() {
501 let binding = TupleSerdeBinding::<u64, Employee>::new(
502 |emp| emp.id,
503 |key, mut data| {
504 data.id = key;
505 data
506 },
507 );
508
509 let emp = Employee {
510 id: 42,
511 name: "Test".to_string(),
512 department: "Eng".to_string(),
513 };
514
515 let mut key_entry = DatabaseEntry::new();
516 let mut data_entry = DatabaseEntry::new();
517 binding.object_to_key(&emp, &mut key_entry).unwrap();
518 binding.object_to_data(&emp, &mut data_entry).unwrap();
519
520 let decoded = binding.entry_to_object(&key_entry, &data_entry).unwrap();
521 assert_eq!(decoded.id, 42);
522 assert_eq!(decoded.name, "Test");
523 }
524
525 #[test]
527 fn test_u32_key_is_4_bytes_fixed_width() {
528 let binding = TupleSerdeKeyDataBinding::<u32, String>::new();
529 for k in [0u32, 1, 255, 256, u32::MAX] {
530 let entity = (k, String::new());
531 let mut key_entry = DatabaseEntry::new();
532 binding.object_to_key(&entity, &mut key_entry).unwrap();
533 assert_eq!(
534 key_entry.data().len(),
535 4,
536 "u32 key must be 4 bytes (k={})",
537 k
538 );
539 }
540 }
541}