fbe/
field_model.rs

1//! Fast Binary Encoding field models
2//!
3//! Field model pattern for type-safe serialization/deserialization.
4//! Following original FBE design with Rust zero-cost abstractions.
5
6use crate::buffer::{ReadBuffer, WriteBuffer};
7
8/// Base trait for all field models
9pub trait FieldModel {
10    /// Get field offset in buffer
11    fn offset(&self) -> usize;
12
13    /// Set field offset in buffer
14    fn set_offset(&mut self, offset: usize);
15
16    /// Get field size in bytes
17    fn size(&self) -> usize;
18
19    /// Get extra size for dynamic types (strings, vectors, etc.)
20    fn extra(&self) -> usize {
21        0
22    }
23
24    /// Shift offset forward
25    fn shift(&mut self, size: usize) {
26        let current = self.offset();
27        self.set_offset(current + size);
28    }
29
30    /// Shift offset backward
31    fn unshift(&mut self, size: usize) {
32        let current = self.offset();
33        self.set_offset(current - size);
34    }
35
36    /// Verify field value
37    fn verify(&self) -> bool {
38        true
39    }
40}
41
42// ============================================================================
43// Macro for primitive field models
44// ============================================================================
45
46macro_rules! impl_primitive_field_model {
47    ($name:ident, $name_mut:ident, $type:ty, $size:expr, $read_fn:ident, $write_fn:ident) => {
48        pub struct $name<'a> {
49            buffer: &'a [u8],
50            offset: usize,
51        }
52
53        impl<'a> $name<'a> {
54            pub fn new(buffer: &'a [u8], offset: usize) -> Self {
55                Self { buffer, offset }
56            }
57
58            pub fn get(&self) -> $type {
59                ReadBuffer::from(self.buffer.to_vec()).$read_fn(self.offset)
60            }
61        }
62
63        impl<'a> FieldModel for $name<'a> {
64            fn offset(&self) -> usize {
65                self.offset
66            }
67            fn set_offset(&mut self, offset: usize) {
68                self.offset = offset;
69            }
70            fn size(&self) -> usize {
71                $size
72            }
73        }
74
75        pub struct $name_mut<'a> {
76            buffer: &'a mut WriteBuffer,
77            offset: usize,
78        }
79
80        impl<'a> $name_mut<'a> {
81            pub fn new(buffer: &'a mut WriteBuffer, offset: usize) -> Self {
82                Self { buffer, offset }
83            }
84
85            pub fn set(&mut self, value: $type) {
86                self.buffer.$write_fn(self.offset, value);
87            }
88        }
89
90        impl<'a> FieldModel for $name_mut<'a> {
91            fn offset(&self) -> usize {
92                self.offset
93            }
94            fn set_offset(&mut self, offset: usize) {
95                self.offset = offset;
96            }
97            fn size(&self) -> usize {
98                $size
99            }
100        }
101    };
102}
103
104// ============================================================================
105// Primitive Types
106// ============================================================================
107
108impl_primitive_field_model!(
109    FieldModelBool,
110    FieldModelBoolMut,
111    bool,
112    1,
113    read_bool,
114    write_bool
115);
116impl_primitive_field_model!(FieldModelByte, FieldModelByteMut, u8, 1, read_byte, write_byte);
117impl_primitive_field_model!(FieldModelChar, FieldModelCharMut, u8, 1, read_char, write_char);
118impl_primitive_field_model!(FieldModelWChar, FieldModelWCharMut, u32, 4, read_wchar, write_wchar);
119impl_primitive_field_model!(FieldModelI8, FieldModelI8Mut, i8, 1, read_i8, write_i8);
120impl_primitive_field_model!(FieldModelI16, FieldModelI16Mut, i16, 2, read_i16, write_i16);
121impl_primitive_field_model!(FieldModelI32, FieldModelI32Mut, i32, 4, read_i32, write_i32);
122impl_primitive_field_model!(FieldModelI64, FieldModelI64Mut, i64, 8, read_i64, write_i64);
123impl_primitive_field_model!(FieldModelU8, FieldModelU8Mut, u8, 1, read_u8, write_u8);
124impl_primitive_field_model!(FieldModelU16, FieldModelU16Mut, u16, 2, read_u16, write_u16);
125impl_primitive_field_model!(FieldModelU32, FieldModelU32Mut, u32, 4, read_u32, write_u32);
126impl_primitive_field_model!(FieldModelU64, FieldModelU64Mut, u64, 8, read_u64, write_u64);
127impl_primitive_field_model!(FieldModelF32, FieldModelF32Mut, f32, 4, read_f32, write_f32);
128impl_primitive_field_model!(FieldModelF64, FieldModelF64Mut, f64, 8, read_f64, write_f64);
129
130// ============================================================================
131// String
132// ============================================================================
133
134pub struct FieldModelString<'a> {
135    buffer: &'a [u8],
136    offset: usize,
137}
138
139impl<'a> FieldModelString<'a> {
140    pub fn new(buffer: &'a [u8], offset: usize) -> Self {
141        Self { buffer, offset }
142    }
143
144    pub fn get(&self) -> String {
145        ReadBuffer::from(self.buffer.to_vec()).read_string(self.offset)
146    }
147}
148
149impl<'a> FieldModel for FieldModelString<'a> {
150    fn offset(&self) -> usize {
151        self.offset
152    }
153    fn set_offset(&mut self, offset: usize) {
154        self.offset = offset;
155    }
156    fn size(&self) -> usize {
157        4
158    } // Size prefix only
159
160    fn extra(&self) -> usize {
161        if self.buffer.len() < self.offset + 4 {
162            return 0;
163        }
164        let len_bytes = &self.buffer[self.offset..self.offset + 4];
165        u32::from_le_bytes([len_bytes[0], len_bytes[1], len_bytes[2], len_bytes[3]]) as usize
166    }
167}
168
169pub struct FieldModelStringMut<'a> {
170    buffer: &'a mut WriteBuffer,
171    offset: usize,
172}
173
174impl<'a> FieldModelStringMut<'a> {
175    pub fn new(buffer: &'a mut WriteBuffer, offset: usize) -> Self {
176        Self { buffer, offset }
177    }
178
179    pub fn set(&mut self, value: &str) {
180        self.buffer.write_string(self.offset, value);
181    }
182}
183
184impl<'a> FieldModel for FieldModelStringMut<'a> {
185    fn offset(&self) -> usize {
186        self.offset
187    }
188    fn set_offset(&mut self, offset: usize) {
189        self.offset = offset;
190    }
191    fn size(&self) -> usize {
192        4
193    }
194}
195
196// ============================================================================
197// Timestamp
198// ============================================================================
199
200impl_primitive_field_model!(
201    FieldModelTimestamp,
202    FieldModelTimestampMut,
203    u64,
204    8,
205    read_timestamp,
206    write_timestamp
207);
208
209// ============================================================================
210// UUID
211// ============================================================================
212
213pub struct FieldModelUuid<'a> {
214    buffer: &'a [u8],
215    offset: usize,
216}
217
218impl<'a> FieldModelUuid<'a> {
219    pub fn new(buffer: &'a [u8], offset: usize) -> Self {
220        Self { buffer, offset }
221    }
222
223    pub fn get(&self) -> String {
224        let bytes = ReadBuffer::from(self.buffer.to_vec()).read_uuid(self.offset);
225        // Convert binary to UUID string
226        format!("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
227            bytes[0], bytes[1], bytes[2], bytes[3],
228            bytes[4], bytes[5],
229            bytes[6], bytes[7],
230            bytes[8], bytes[9],
231            bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15])
232    }
233}
234
235impl<'a> FieldModel for FieldModelUuid<'a> {
236    fn offset(&self) -> usize {
237        self.offset
238    }
239    fn set_offset(&mut self, offset: usize) {
240        self.offset = offset;
241    }
242    fn size(&self) -> usize {
243        16
244    }
245}
246
247pub struct FieldModelUuidMut<'a> {
248    buffer: &'a mut WriteBuffer,
249    offset: usize,
250}
251
252impl<'a> FieldModelUuidMut<'a> {
253    pub fn new(buffer: &'a mut WriteBuffer, offset: usize) -> Self {
254        Self { buffer, offset }
255    }
256
257    pub fn set(&mut self, value: &str) {
258        // Parse UUID string to binary
259        let uuid_str = value.replace("-", "");
260        let mut bytes = [0u8; 16];
261        for i in 0..16 {
262            bytes[i] = u8::from_str_radix(&uuid_str[i * 2..i * 2 + 2], 16).unwrap_or(0);
263        }
264        self.buffer.write_uuid(self.offset, &bytes);
265    }
266}
267
268impl<'a> FieldModel for FieldModelUuidMut<'a> {
269    fn offset(&self) -> usize {
270        self.offset
271    }
272    fn set_offset(&mut self, offset: usize) {
273        self.offset = offset;
274    }
275    fn size(&self) -> usize {
276        16
277    }
278}
279
280// ============================================================================
281// Bytes
282// ============================================================================
283
284pub struct FieldModelBytes<'a> {
285    buffer: &'a [u8],
286    offset: usize,
287}
288
289impl<'a> FieldModelBytes<'a> {
290    pub fn new(buffer: &'a [u8], offset: usize) -> Self {
291        Self { buffer, offset }
292    }
293
294    pub fn get(&self) -> Vec<u8> {
295        ReadBuffer::from(self.buffer.to_vec()).read_bytes(self.offset)
296    }
297}
298
299impl<'a> FieldModel for FieldModelBytes<'a> {
300    fn offset(&self) -> usize {
301        self.offset
302    }
303    fn set_offset(&mut self, offset: usize) {
304        self.offset = offset;
305    }
306    fn size(&self) -> usize {
307        4
308    } // Size prefix only
309
310    fn extra(&self) -> usize {
311        if self.buffer.len() < self.offset + 4 {
312            return 0;
313        }
314        let len_bytes = &self.buffer[self.offset..self.offset + 4];
315        u32::from_le_bytes([len_bytes[0], len_bytes[1], len_bytes[2], len_bytes[3]]) as usize
316    }
317}
318
319pub struct FieldModelBytesMut<'a> {
320    buffer: &'a mut WriteBuffer,
321    offset: usize,
322}
323
324impl<'a> FieldModelBytesMut<'a> {
325    pub fn new(buffer: &'a mut WriteBuffer, offset: usize) -> Self {
326        Self { buffer, offset }
327    }
328
329    pub fn set(&mut self, value: &[u8]) {
330        self.buffer.write_bytes(self.offset, value);
331    }
332}
333
334impl<'a> FieldModel for FieldModelBytesMut<'a> {
335    fn offset(&self) -> usize {
336        self.offset
337    }
338    fn set_offset(&mut self, offset: usize) {
339        self.offset = offset;
340    }
341    fn size(&self) -> usize {
342        4
343    }
344}
345
346// ============================================================================
347// Decimal
348// ============================================================================
349
350pub struct FieldModelDecimal<'a> {
351    buffer: &'a [u8],
352    offset: usize,
353}
354
355impl<'a> FieldModelDecimal<'a> {
356    pub fn new(buffer: &'a [u8], offset: usize) -> Self {
357        Self { buffer, offset }
358    }
359
360    pub fn get(&self) -> (i128, u8, bool) {
361        ReadBuffer::from(self.buffer.to_vec()).read_decimal(self.offset)
362    }
363}
364
365impl<'a> FieldModel for FieldModelDecimal<'a> {
366    fn offset(&self) -> usize {
367        self.offset
368    }
369    fn set_offset(&mut self, offset: usize) {
370        self.offset = offset;
371    }
372    fn size(&self) -> usize {
373        16
374    }
375}
376
377pub struct FieldModelDecimalMut<'a> {
378    buffer: &'a mut WriteBuffer,
379    offset: usize,
380}
381
382impl<'a> FieldModelDecimalMut<'a> {
383    pub fn new(buffer: &'a mut WriteBuffer, offset: usize) -> Self {
384        Self { buffer, offset }
385    }
386
387    pub fn set(&mut self, value: i128, scale: u8, negative: bool) {
388        self.buffer
389            .write_decimal(self.offset, value, scale, negative);
390    }
391}
392
393impl<'a> FieldModel for FieldModelDecimalMut<'a> {
394    fn offset(&self) -> usize {
395        self.offset
396    }
397    fn set_offset(&mut self, offset: usize) {
398        self.offset = offset;
399    }
400    fn size(&self) -> usize {
401        16
402    }
403}
404
405
406// ============================================================================
407// Collection Field Models
408// ============================================================================
409
410/// FieldModel for vector<T> (pointer-based, dynamic size)
411pub struct FieldModelVector<'a, T> {
412    buffer: &'a [u8],
413    offset: usize,
414    item_model: fn(&'a [u8], usize) -> T,
415}
416
417impl<'a, T> FieldModelVector<'a, T> {
418    pub fn new(buffer: &'a [u8], offset: usize, item_model: fn(&'a [u8], usize) -> T) -> Self {
419        Self { buffer, offset, item_model }
420    }
421
422    pub fn get(&self) -> Vec<T> {
423        let mut read_buf = ReadBuffer::new();
424        read_buf.attach_buffer(self.buffer, 0, self.buffer.len());
425        
426        // Read pointer at offset
427        let pointer = read_buf.read_u32(self.offset) as usize;
428        if pointer == 0 {
429            return Vec::new();
430        }
431        
432        // Read size at pointer location
433        let size = read_buf.read_u32(pointer) as usize;
434        let mut result = Vec::with_capacity(size);
435        
436        // Read items
437        let mut item_offset = pointer + 4;
438        for _ in 0..size {
439            result.push((self.item_model)(self.buffer, item_offset));
440            item_offset += std::mem::size_of::<T>();
441        }
442        
443        result
444    }
445}
446
447impl<'a, T> FieldModel for FieldModelVector<'a, T> {
448    fn offset(&self) -> usize {
449        self.offset
450    }
451
452    fn set_offset(&mut self, offset: usize) {
453        self.offset = offset;
454    }
455
456    fn size(&self) -> usize {
457        4 // Pointer size
458    }
459}
460
461/// FieldModel for array<T, N> (inline, fixed size)
462pub struct FieldModelArray<'a, T, const N: usize> {
463    buffer: &'a [u8],
464    offset: usize,
465    item_model: fn(&'a [u8], usize) -> T,
466}
467
468impl<'a, T, const N: usize> FieldModelArray<'a, T, N> {
469    pub fn new(buffer: &'a [u8], offset: usize, item_model: fn(&'a [u8], usize) -> T) -> Self {
470        Self { buffer, offset, item_model }
471    }
472
473    pub fn get(&self) -> [T; N] {
474        let mut result = Vec::with_capacity(N);
475        let mut item_offset = self.offset;
476        
477        for _ in 0..N {
478            result.push((self.item_model)(self.buffer, item_offset));
479            item_offset += std::mem::size_of::<T>();
480        }
481        
482        result.try_into().unwrap_or_else(|_| panic!("Array size mismatch"))
483    }
484}
485
486impl<'a, T, const N: usize> FieldModel for FieldModelArray<'a, T, N> {
487    fn offset(&self) -> usize {
488        self.offset
489    }
490
491    fn set_offset(&mut self, offset: usize) {
492        self.offset = offset;
493    }
494
495    fn size(&self) -> usize {
496        N * std::mem::size_of::<T>()
497    }
498}
499
500/// FieldModel for map<K, V> (pointer-based)
501pub struct FieldModelMap<'a, K, V> {
502    buffer: &'a [u8],
503    offset: usize,
504    key_model: fn(&'a [u8], usize) -> K,
505    value_model: fn(&'a [u8], usize) -> V,
506}
507
508impl<'a, K, V> FieldModelMap<'a, K, V> {
509    pub fn new(
510        buffer: &'a [u8],
511        offset: usize,
512        key_model: fn(&'a [u8], usize) -> K,
513        value_model: fn(&'a [u8], usize) -> V,
514    ) -> Self {
515        Self { buffer, offset, key_model, value_model }
516    }
517
518    pub fn get(&self) -> std::collections::HashMap<K, V>
519    where
520        K: std::hash::Hash + Eq,
521    {
522        let mut read_buf = ReadBuffer::new();
523        read_buf.attach_buffer(self.buffer, 0, self.buffer.len());
524        
525        let pointer = read_buf.read_u32(self.offset) as usize;
526        if pointer == 0 {
527            return std::collections::HashMap::new();
528        }
529        
530        let size = read_buf.read_u32(pointer) as usize;
531        let mut result = std::collections::HashMap::with_capacity(size);
532        
533        let mut item_offset = pointer + 4;
534        for _ in 0..size {
535            let key = (self.key_model)(self.buffer, item_offset);
536            item_offset += std::mem::size_of::<K>();
537            let value = (self.value_model)(self.buffer, item_offset);
538            item_offset += std::mem::size_of::<V>();
539            result.insert(key, value);
540        }
541        
542        result
543    }
544}
545
546impl<'a, K, V> FieldModel for FieldModelMap<'a, K, V> {
547    fn offset(&self) -> usize {
548        self.offset
549    }
550
551    fn set_offset(&mut self, offset: usize) {
552        self.offset = offset;
553    }
554
555    fn size(&self) -> usize {
556        4 // Pointer size
557    }
558}
559
560/// FieldModel for set<T> (pointer-based)
561pub struct FieldModelSet<'a, T> {
562    buffer: &'a [u8],
563    offset: usize,
564    item_model: fn(&'a [u8], usize) -> T,
565}
566
567impl<'a, T> FieldModelSet<'a, T> {
568    pub fn new(buffer: &'a [u8], offset: usize, item_model: fn(&'a [u8], usize) -> T) -> Self {
569        Self { buffer, offset, item_model }
570    }
571
572    pub fn get(&self) -> std::collections::HashSet<T>
573    where
574        T: std::hash::Hash + Eq,
575    {
576        let mut read_buf = ReadBuffer::new();
577        read_buf.attach_buffer(self.buffer, 0, self.buffer.len());
578        
579        let pointer = read_buf.read_u32(self.offset) as usize;
580        if pointer == 0 {
581            return std::collections::HashSet::new();
582        }
583        
584        let size = read_buf.read_u32(pointer) as usize;
585        let mut result = std::collections::HashSet::with_capacity(size);
586        
587        let mut item_offset = pointer + 4;
588        for _ in 0..size {
589            result.insert((self.item_model)(self.buffer, item_offset));
590            item_offset += std::mem::size_of::<T>();
591        }
592        
593        result
594    }
595}
596
597impl<'a, T> FieldModel for FieldModelSet<'a, T> {
598    fn offset(&self) -> usize {
599        self.offset
600    }
601
602    fn set_offset(&mut self, offset: usize) {
603        self.offset = offset;
604    }
605
606    fn size(&self) -> usize {
607        4 // Pointer size
608    }
609}
610
611/// FieldModel for list<T> (pointer-based, linked list)
612pub struct FieldModelList<'a, T> {
613    buffer: &'a [u8],
614    offset: usize,
615    item_model: fn(&'a [u8], usize) -> T,
616}
617
618impl<'a, T> FieldModelList<'a, T> {
619    pub fn new(buffer: &'a [u8], offset: usize, item_model: fn(&'a [u8], usize) -> T) -> Self {
620        Self { buffer, offset, item_model }
621    }
622
623    pub fn get(&self) -> std::collections::LinkedList<T> {
624        let mut read_buf = ReadBuffer::new();
625        read_buf.attach_buffer(self.buffer, 0, self.buffer.len());
626        
627        let pointer = read_buf.read_u32(self.offset) as usize;
628        if pointer == 0 {
629            return std::collections::LinkedList::new();
630        }
631        
632        let size = read_buf.read_u32(pointer) as usize;
633        let mut result = std::collections::LinkedList::new();
634        
635        let mut item_offset = pointer + 4;
636        for _ in 0..size {
637            result.push_back((self.item_model)(self.buffer, item_offset));
638            item_offset += std::mem::size_of::<T>();
639        }
640        
641        result
642    }
643}
644
645impl<'a, T> FieldModel for FieldModelList<'a, T> {
646    fn offset(&self) -> usize {
647        self.offset
648    }
649
650    fn set_offset(&mut self, offset: usize) {
651        self.offset = offset;
652    }
653
654    fn size(&self) -> usize {
655        4 // Pointer size
656    }
657}
658
659
660// ============================================================================
661// Optional<T>
662// ============================================================================
663
664/// FieldModel for optional<T> (pointer-based, nullable)
665/// 
666/// Format:
667/// - 1 byte: has_value flag (0 = null, 1 = has value)
668/// - If has_value: followed by value data
669pub struct FieldModelOptional<'a, T, M>
670where
671    M: FieldModel,
672{
673    buffer: &'a [u8],
674    offset: usize,
675    value_model_fn: fn(&'a [u8], usize) -> M,
676    _phantom: std::marker::PhantomData<T>,
677}
678
679impl<'a, T, M> FieldModelOptional<'a, T, M>
680where
681    M: FieldModel,
682{
683    #[inline]
684    pub fn new(buffer: &'a [u8], offset: usize, value_model_fn: fn(&'a [u8], usize) -> M) -> Self {
685        Self {
686            buffer,
687            offset,
688            value_model_fn,
689            _phantom: std::marker::PhantomData,
690        }
691    }
692
693    #[inline]
694    pub fn has_value(&self) -> bool {
695        if self.buffer.len() < self.offset + 1 {
696            return false;
697        }
698        self.buffer[self.offset] != 0
699    }
700
701    pub fn get<F>(&self, extract_fn: F) -> Option<T>
702    where
703        F: Fn(&M) -> T,
704    {
705        if !self.has_value() {
706            return None;
707        }
708
709        let value_offset = self.offset + 1;
710        let value_model = (self.value_model_fn)(self.buffer, value_offset);
711        Some(extract_fn(&value_model))
712    }
713}
714
715impl<'a, T, M> FieldModel for FieldModelOptional<'a, T, M>
716where
717    M: FieldModel,
718{
719    fn offset(&self) -> usize {
720        self.offset
721    }
722
723    fn set_offset(&mut self, offset: usize) {
724        self.offset = offset;
725    }
726
727    fn size(&self) -> usize {
728        if !self.has_value() {
729            return 1; // Only flag byte
730        }
731        
732        let value_offset = self.offset + 1;
733        let value_model = (self.value_model_fn)(self.buffer, value_offset);
734        1 + value_model.size()
735    }
736
737    fn extra(&self) -> usize {
738        if !self.has_value() {
739            return 0;
740        }
741        
742        let value_offset = self.offset + 1;
743        let value_model = (self.value_model_fn)(self.buffer, value_offset);
744        value_model.extra()
745    }
746}
747
748/// Mutable version for writing
749pub struct FieldModelOptionalMut<'a, T, M>
750where
751    M: FieldModel,
752{
753    buffer: &'a mut WriteBuffer,
754    offset: usize,
755    value_model_fn: fn(&'a mut WriteBuffer, usize) -> M,
756    _phantom: std::marker::PhantomData<T>,
757}
758
759impl<'a, T, M> FieldModelOptionalMut<'a, T, M>
760where
761    M: FieldModel,
762{
763    #[inline]
764    pub fn new(
765        buffer: &'a mut WriteBuffer,
766        offset: usize,
767        value_model_fn: fn(&'a mut WriteBuffer, usize) -> M,
768    ) -> Self {
769        Self {
770            buffer,
771            offset,
772            value_model_fn,
773            _phantom: std::marker::PhantomData,
774        }
775    }
776
777    pub fn set_none(&mut self) {
778        self.buffer.write_byte(self.offset, 0);
779    }
780
781    pub fn set_some<F>(self, value: T, write_fn: F)
782    where
783        F: FnOnce(&mut M, T),
784    {
785        // Write has_value = 1
786        self.buffer.write_byte(self.offset, 1);
787        
788        // Write value
789        let value_offset = self.offset + 1;
790        let mut value_model = (self.value_model_fn)(self.buffer, value_offset);
791        write_fn(&mut value_model, value);
792    }
793}
794
795impl<'a, T, M> FieldModel for FieldModelOptionalMut<'a, T, M>
796where
797    M: FieldModel,
798{
799    fn offset(&self) -> usize {
800        self.offset
801    }
802
803    fn set_offset(&mut self, offset: usize) {
804        self.offset = offset;
805    }
806
807    fn size(&self) -> usize {
808        1 // Minimum size (flag byte)
809    }
810}
811
812