Skip to main content

protocache_core/
mutable.rs

1//! Mutable surface matching `access-ex.h`.
2
3use std::array;
4use std::borrow::Borrow;
5use std::collections::HashMap;
6use std::hash::Hash;
7use std::marker::PhantomData;
8
9use crate::access::checked_slice_end;
10use crate::serialize::serialize_map_pairs_at_mut;
11use crate::{
12    ArrayView, Buffer, FieldView, MapKey, MapView, MessageView, Scalar, StringView, Unit,
13    build_perfect_hash_index_with_positions, fold_field, serialize_array_at_mut, serialize_bool,
14    serialize_bytes, serialize_scalar, serialize_str,
15};
16
17#[derive(Debug)]
18/// Error returned while decoding or serializing a generated mutable message.
19pub enum MutableError {
20    InvalidRoot {
21        descriptor: String,
22    },
23    MissingField {
24        descriptor: String,
25        field: String,
26    },
27    TypeMismatch {
28        descriptor: String,
29        field: String,
30        expected: &'static str,
31    },
32    InvalidMapKey {
33        descriptor: String,
34        field: String,
35        key: String,
36    },
37    SerializeFailed {
38        descriptor: String,
39        field: String,
40    },
41}
42
43impl std::fmt::Display for MutableError {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Self::InvalidRoot { descriptor } => write!(f, "invalid root for {descriptor}"),
47            Self::MissingField { descriptor, field } => {
48                write!(f, "missing field {field} in {descriptor}")
49            }
50            Self::TypeMismatch {
51                descriptor,
52                field,
53                expected,
54            } => write!(
55                f,
56                "type mismatch for {descriptor}.{field}, expected {expected}"
57            ),
58            Self::InvalidMapKey {
59                descriptor,
60                field,
61                key,
62            } => write!(f, "invalid map key {key} for {descriptor}.{field}"),
63            Self::SerializeFailed { descriptor, field } => {
64                write!(f, "failed to serialize {descriptor}.{field}")
65            }
66        }
67    }
68}
69
70impl std::error::Error for MutableError {}
71
72#[derive(Clone, Copy)]
73/// The wire-level key representation used by a mutable map.
74pub enum MutableMapKeyKind {
75    String,
76    I32,
77    U32,
78    I64,
79    U64,
80}
81
82/// Encoding and dirty-tracking contract implemented by mutable field values.
83///
84/// This trait is primarily implemented by generated bindings. Application code
85/// normally interacts with the generated field accessors instead.
86pub trait MutableField<'a>: Clone + Default {
87    fn decode(field: FieldView<'a>) -> Option<Self>;
88    fn detect(field: FieldView<'a>) -> Option<&'a [u32]>;
89    fn folds_when_present() -> bool
90    where
91        Self: Sized,
92    {
93        true
94    }
95    fn is_empty_field(&self) -> bool {
96        false
97    }
98    fn omits_default_after_encode() -> bool
99    where
100        Self: Sized,
101    {
102        true
103    }
104    fn is_dirty(&self) -> bool {
105        false
106    }
107    fn has_nested_dirty(&self) -> bool {
108        self.is_dirty()
109    }
110    fn encode(&self, buffer: &mut Buffer) -> Result<Unit, MutableError>;
111}
112
113/// Array-specific extension of [`MutableField`] used by generated bindings.
114pub trait MutableArrayElement<'a>: MutableField<'a> {
115    fn decode_array(words: &'a [u32]) -> Option<Vec<Self>>;
116    fn detect_array_words(words: &'a [u32]) -> Option<&'a [u32]> {
117        detect_array_words::<Self>(words)
118    }
119    fn detect_array_field(field: FieldView<'a>) -> Option<&'a [u32]> {
120        Self::detect_array_words(field.object_words()?)
121    }
122    fn encode_array(values: &[Self], buffer: &mut Buffer) -> Result<Unit, MutableError>;
123}
124
125/// Map-key encoding contract used by [`MutableMap`].
126pub trait MutableMapKey<'a>: Clone + Eq + Hash {
127    fn decode_key(field: FieldView<'a>) -> Option<Self>;
128    fn detect_key(field: FieldView<'a>) -> Option<&'a [u32]>;
129    fn encode_key(&self, buffer: &mut Buffer) -> Result<Unit, MutableError>;
130    fn key_kind() -> MutableMapKeyKind;
131    fn borrowed_key_bytes(&self) -> Option<&[u8]> {
132        None
133    }
134    fn write_key_bytes<'b>(&'b self, scratch: &'b mut [u8; 8]) -> &'b [u8];
135}
136
137#[derive(Clone, Copy)]
138enum KeyBytes<'a> {
139    Borrowed(&'a [u8]),
140    Inline { data: [u8; 8], len: usize },
141}
142
143impl AsRef<[u8]> for KeyBytes<'_> {
144    fn as_ref(&self) -> &[u8] {
145        match self {
146            Self::Borrowed(bytes) => bytes,
147            Self::Inline { data, len } => &data[..*len],
148        }
149    }
150}
151
152#[derive(Clone, Debug)]
153/// An owned mutable array with dirty tracking for generated messages.
154pub struct MutableArray<'a, T> {
155    values: Vec<T>,
156    dirty: bool,
157    _marker: PhantomData<&'a ()>,
158}
159
160impl<'a, T> Default for MutableArray<'a, T> {
161    fn default() -> Self {
162        Self {
163            values: Vec::new(),
164            dirty: false,
165            _marker: PhantomData,
166        }
167    }
168}
169
170impl<'a, T> MutableArray<'a, T> {
171    /// Creates an empty, clean mutable array.
172    pub fn new() -> Self {
173        Self::default()
174    }
175
176    pub fn len(&self) -> usize {
177        self.values.len()
178    }
179
180    pub fn is_empty(&self) -> bool {
181        self.values.is_empty()
182    }
183
184    /// Removes all values and marks the array dirty.
185    pub fn clear(&mut self) {
186        self.dirty = true;
187        self.values.clear();
188    }
189
190    pub fn reserve(&mut self, additional: usize) {
191        self.values.reserve(additional);
192    }
193
194    /// Appends a value and marks the array dirty.
195    pub fn push(&mut self, value: T) {
196        self.dirty = true;
197        self.values.push(value);
198    }
199
200    pub fn as_slice(&self) -> &[T] {
201        &self.values
202    }
203
204    pub fn as_mut_slice(&mut self) -> &mut [T] {
205        self.dirty = true;
206        &mut self.values
207    }
208
209    pub fn iter(&self) -> impl Iterator<Item = &T> {
210        self.values.iter()
211    }
212
213    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
214        self.dirty = true;
215        self.values.iter_mut()
216    }
217}
218
219impl<'a, T> From<Vec<T>> for MutableArray<'a, T> {
220    fn from(values: Vec<T>) -> Self {
221        Self {
222            values,
223            dirty: false,
224            _marker: PhantomData,
225        }
226    }
227}
228
229impl<'a, T> Extend<T> for MutableArray<'a, T> {
230    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
231        self.dirty = true;
232        self.values.extend(iter);
233    }
234}
235
236impl<'a, T> std::iter::FromIterator<T> for MutableArray<'a, T> {
237    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
238        Self {
239            values: iter.into_iter().collect(),
240            dirty: false,
241            _marker: PhantomData,
242        }
243    }
244}
245
246impl<'b, 'a, T> IntoIterator for &'b MutableArray<'a, T> {
247    type Item = &'b T;
248    type IntoIter = std::slice::Iter<'b, T>;
249
250    fn into_iter(self) -> Self::IntoIter {
251        self.values.iter()
252    }
253}
254
255impl<'b, 'a, T> IntoIterator for &'b mut MutableArray<'a, T> {
256    type Item = &'b mut T;
257    type IntoIter = std::slice::IterMut<'b, T>;
258
259    fn into_iter(self) -> Self::IntoIter {
260        self.dirty = true;
261        self.values.iter_mut()
262    }
263}
264
265impl<'a, T> std::ops::Index<usize> for MutableArray<'a, T> {
266    type Output = T;
267
268    fn index(&self, index: usize) -> &Self::Output {
269        &self.values[index]
270    }
271}
272
273impl<'a, T> std::ops::IndexMut<usize> for MutableArray<'a, T> {
274    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
275        self.dirty = true;
276        &mut self.values[index]
277    }
278}
279
280impl<'a, T: MutableArrayElement<'a>> MutableArray<'a, T> {
281    /// Decodes all elements from an encoded array.
282    pub fn from_words(words: &'a [u32]) -> Option<Self> {
283        Some(Self {
284            values: T::decode_array(words)?,
285            dirty: false,
286            _marker: PhantomData,
287        })
288    }
289
290    /// Encodes the array into `buffer` and returns its field representation.
291    pub fn encode_to_unit(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
292        T::encode_array(&self.values, buffer)
293    }
294}
295
296#[derive(Clone, Debug)]
297/// An owned mutable map with dirty tracking and ProtoCache key encoding.
298pub struct MutableMap<'a, K, V> {
299    entries: HashMap<K, V>,
300    dirty: bool,
301    _marker: PhantomData<&'a ()>,
302}
303
304impl<'a, K, V> Default for MutableMap<'a, K, V> {
305    fn default() -> Self {
306        Self {
307            entries: HashMap::new(),
308            dirty: false,
309            _marker: PhantomData,
310        }
311    }
312}
313
314impl<'a, K: Eq + Hash, V> MutableMap<'a, K, V> {
315    /// Creates an empty, clean mutable map.
316    pub fn new() -> Self {
317        Self::default()
318    }
319
320    pub fn len(&self) -> usize {
321        self.entries.len()
322    }
323
324    pub fn is_empty(&self) -> bool {
325        self.entries.is_empty()
326    }
327
328    /// Removes all entries and marks the map dirty.
329    pub fn clear(&mut self) {
330        self.dirty = true;
331        self.entries.clear();
332    }
333
334    pub fn reserve(&mut self, additional: usize) {
335        self.entries.reserve(additional);
336    }
337
338    /// Inserts an entry and marks the map dirty.
339    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
340        self.dirty = true;
341        self.entries.insert(key, value)
342    }
343
344    pub fn contains_key<Q>(&self, key: &Q) -> bool
345    where
346        K: Borrow<Q>,
347        Q: Eq + Hash + ?Sized,
348    {
349        self.entries.contains_key(key)
350    }
351
352    pub fn get<Q>(&self, key: &Q) -> Option<&V>
353    where
354        K: Borrow<Q>,
355        Q: Eq + Hash + ?Sized,
356    {
357        self.entries.get(key)
358    }
359
360    /// Returns mutable access to a value and marks the map dirty when found.
361    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
362    where
363        K: Borrow<Q>,
364        Q: Eq + Hash + ?Sized,
365    {
366        self.dirty = true;
367        self.entries.get_mut(key)
368    }
369
370    pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
371    where
372        K: Borrow<Q>,
373        Q: Eq + Hash + ?Sized,
374    {
375        self.dirty = true;
376        self.entries.remove(key)
377    }
378
379    pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
380        self.entries.iter()
381    }
382}
383
384impl<'a, K, V> From<HashMap<K, V>> for MutableMap<'a, K, V> {
385    fn from(entries: HashMap<K, V>) -> Self {
386        Self {
387            entries,
388            dirty: false,
389            _marker: PhantomData,
390        }
391    }
392}
393
394impl<'a, K: Eq + Hash, V> Extend<(K, V)> for MutableMap<'a, K, V> {
395    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
396        self.dirty = true;
397        self.entries.extend(iter);
398    }
399}
400
401impl<'a, K: Eq + Hash, V> std::iter::FromIterator<(K, V)> for MutableMap<'a, K, V> {
402    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
403        Self {
404            entries: iter.into_iter().collect(),
405            dirty: false,
406            _marker: PhantomData,
407        }
408    }
409}
410
411impl<'b, 'a, K, V> IntoIterator for &'b MutableMap<'a, K, V> {
412    type Item = (&'b K, &'b V);
413    type IntoIter = std::collections::hash_map::Iter<'b, K, V>;
414
415    fn into_iter(self) -> Self::IntoIter {
416        self.entries.iter()
417    }
418}
419
420impl<'b, 'a, K, V> IntoIterator for &'b mut MutableMap<'a, K, V> {
421    type Item = (&'b K, &'b mut V);
422    type IntoIter = std::collections::hash_map::IterMut<'b, K, V>;
423
424    fn into_iter(self) -> Self::IntoIter {
425        self.dirty = true;
426        self.entries.iter_mut()
427    }
428}
429
430impl<'a, K: MutableMapKey<'a>, V: MutableField<'a>> MutableMap<'a, K, V> {
431    /// Decodes all entries from an encoded map.
432    pub fn from_words(words: &'a [u32]) -> Option<Self> {
433        let map = MapView::new(words)?;
434        let mut entries = HashMap::with_capacity(map.len());
435        for pair in map.iter() {
436            entries.insert(K::decode_key(pair.key())?, V::decode(pair.value())?);
437        }
438        Some(Self {
439            entries,
440            dirty: false,
441            _marker: PhantomData,
442        })
443    }
444
445    /// Encodes the map and its perfect-hash index into `buffer`.
446    pub fn encode_to_unit(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
447        if self.entries.is_empty() {
448            return Ok(Unit::inline(&[5u32 << 28]));
449        }
450
451        let last = buffer.len();
452        let mut memo = Vec::with_capacity(self.entries.len());
453        let mut key_bytes = Vec::with_capacity(self.entries.len());
454        match K::key_kind() {
455            MutableMapKeyKind::String => {
456                for pair in self.entries.iter() {
457                    key_bytes.push(KeyBytes::Borrowed(
458                        pair.0
459                            .borrowed_key_bytes()
460                            .expect("string keys should expose borrowed bytes"),
461                    ));
462                    memo.push(pair);
463                }
464            }
465            _ => {
466                for pair in self.entries.iter() {
467                    let mut scratch = [0u8; 8];
468                    let len = {
469                        let bytes = pair.0.write_key_bytes(&mut scratch);
470                        bytes.len()
471                    };
472                    key_bytes.push(KeyBytes::Inline { data: scratch, len });
473                    memo.push(pair);
474                }
475            }
476        }
477        let (index, positions) = build_perfect_hash_index_with_positions(&key_bytes).ok_or(
478            MutableError::SerializeFailed {
479                descriptor: "<map>".to_owned(),
480                field: "<index>".to_owned(),
481            },
482        )?;
483
484        let mut book = vec![memo[0]; memo.len()];
485        for (idx, position) in positions.into_iter().enumerate() {
486            book[position] = memo[idx];
487        }
488
489        let mut pairs = vec![(Unit::empty(), Unit::empty()); book.len()];
490        for i in (0..book.len()).rev() {
491            let (key, value) = book[i];
492            pairs[i].1 = value.encode(buffer)?;
493            pairs[i].0 = key.encode_key(buffer)?;
494        }
495
496        serialize_map_pairs_at_mut(&index, &mut pairs, buffer, last).ok_or_else(|| {
497            MutableError::SerializeFailed {
498                descriptor: "<map>".to_owned(),
499                field: "<encode>".to_owned(),
500            }
501        })
502    }
503}
504
505#[inline(always)]
506fn detect_array_words<'a, T: MutableField<'a>>(words: &'a [u32]) -> Option<&'a [u32]> {
507    let array = ArrayView::new(words)?;
508    let end = array.total_words();
509    for index in (0..array.len()).rev() {
510        let detected = T::detect(array.expect_field(index))?;
511        let detected_end = checked_slice_end(words, detected)?;
512        if detected_end > end {
513            return words.get(..detected_end);
514        }
515    }
516    words.get(..end)
517}
518
519#[inline(always)]
520fn detect_map_words<'a, K: MutableMapKey<'a>, V: MutableField<'a>>(
521    words: &'a [u32],
522) -> Option<&'a [u32]> {
523    let map = MapView::new(words)?;
524    let end = map.total_words();
525    for index in (0..map.len()).rev() {
526        let pair = map.expect_pair(index);
527        let detected = V::detect(pair.value())?;
528        let detected_end = checked_slice_end(words, detected)?;
529        if detected_end > end {
530            return words.get(..detected_end);
531        }
532
533        let detected = K::detect_key(pair.key())?;
534        let detected_end = checked_slice_end(words, detected)?;
535        if detected_end > end {
536            return words.get(..detected_end);
537        }
538    }
539    words.get(..end)
540}
541
542#[derive(Clone, Debug)]
543/// Lazy mutable state for a generated message.
544///
545/// `N` is the number of schema fields and `WORDS` is the generated bitset
546/// storage. Untouched fields continue to borrow their original encoded words.
547pub struct MutableMessage<'a, const N: usize, const WORDS: usize> {
548    words: Option<&'a [u32]>,
549    accessed: [u64; WORDS],
550}
551
552impl<'a, const N: usize, const WORDS: usize> Default for MutableMessage<'a, N, WORDS> {
553    fn default() -> Self {
554        Self {
555            words: None,
556            accessed: [0; WORDS],
557        }
558    }
559}
560
561impl<'a, const N: usize, const WORDS: usize> MutableMessage<'a, N, WORDS> {
562    /// Creates empty mutable state with no borrowed source message.
563    pub fn new() -> Self {
564        debug_assert_eq!(WORDS, N.div_ceil(64));
565        Self::default()
566    }
567
568    /// Creates lazy mutable state backed by a validated encoded message.
569    pub fn from_words(words: &'a [u32]) -> Option<Self> {
570        MessageView::layout(words)?;
571        debug_assert_eq!(WORDS, N.div_ceil(64));
572        Some(Self {
573            words: Some(words),
574            accessed: [0; WORDS],
575        })
576    }
577
578    #[inline(always)]
579    fn field(&self, id: usize) -> Option<FieldView<'a>> {
580        let words = self.words?;
581        let layout = MessageView::layout(words)?;
582        MessageView::field_in(words, &layout, id)
583    }
584
585    #[inline(always)]
586    /// Returns whether a field exists in the source message or has been set.
587    pub fn has_field(&self, id: usize) -> bool {
588        self.field(id).is_some()
589    }
590
591    #[inline(always)]
592    /// Returns whether a generated accessor has materialized this field.
593    pub fn was_accessed(&self, id: usize) -> bool {
594        let word = id / 64;
595        let bit = id % 64;
596        (self.accessed[word] & (1u64 << bit)) != 0
597    }
598
599    pub fn has_any_accessed(&self) -> bool {
600        self.accessed.iter().any(|&word| word != 0)
601    }
602
603    /// Returns the untouched source words, or `None` after any field access.
604    pub fn clean_words(&self) -> Option<&[u32]> {
605        if self.has_any_accessed() {
606            None
607        } else {
608            self.words
609        }
610    }
611
612    /// Lazily decodes a field into its generated storage slot.
613    pub fn get_field<'b, T: MutableField<'a>>(&mut self, id: usize, slot: &'b mut T) -> &'b mut T {
614        if !self.was_accessed(id) {
615            let word = id / 64;
616            let bit = id % 64;
617            self.accessed[word] |= 1u64 << bit;
618            *slot = self.field(id).and_then(T::decode).unwrap_or_default();
619        }
620        slot
621    }
622
623    #[inline(always)]
624    /// Serializes one generated field, reusing untouched source words when safe.
625    pub fn serialize_field<T: MutableField<'a>>(
626        &self,
627        id: usize,
628        field: &T,
629        buffer: &mut Buffer,
630        unit: &mut Unit,
631    ) -> Result<(), MutableError> {
632        if !self.was_accessed(id) {
633            *unit = self
634                .field(id)
635                .and_then(T::detect)
636                .map(|words| copy_words(words, buffer, true))
637                .unwrap_or_else(Unit::empty);
638            return Ok(());
639        }
640
641        if field.is_empty_field() {
642            *unit = Unit::empty();
643            return Ok(());
644        }
645
646        *unit = field.encode(buffer)?;
647        if T::omits_default_after_encode() && should_omit_message_unit(unit) {
648            drop_present_unit(buffer, unit);
649        } else if T::folds_when_present() {
650            fold_field(buffer, unit);
651        } else {
652            debug_assert!(!T::omits_default_after_encode());
653            debug_assert!(!unit.is_segment());
654        }
655        Ok(())
656    }
657}
658
659fn should_omit_message_unit(unit: &Unit) -> bool {
660    unit.size() == 1
661}
662
663fn drop_present_unit(buffer: &mut Buffer, unit: &mut Unit) {
664    if unit.is_segment() {
665        let seg = unit.segment_info();
666        debug_assert_eq!(seg.pos, buffer.len());
667        buffer.shrink(seg.len);
668    }
669    *unit = Unit::empty();
670}
671
672#[inline(always)]
673/// Copies an already encoded field into `buffer`, optionally folding small data
674/// into the returned [`Unit`].
675pub fn copy_words(words: &[u32], buffer: &mut Buffer, fold: bool) -> Unit {
676    if fold && words.len() < 4 {
677        return Unit::inline(words);
678    }
679    let last = buffer.len();
680    buffer.put_words(words);
681    Unit::segment(last, buffer.len())
682}
683
684macro_rules! impl_scalar_field {
685    ($ty:ty) => {
686        impl<'a> MutableField<'a> for $ty {
687            fn decode(field: FieldView<'a>) -> Option<Self> {
688                field.scalar::<$ty>()
689            }
690
691            fn detect(field: FieldView<'a>) -> Option<&'a [u32]> {
692                field.detect_scalar()
693            }
694
695            fn folds_when_present() -> bool
696            where
697                Self: Sized,
698            {
699                false
700            }
701
702            fn is_empty_field(&self) -> bool {
703                *self == 0 as $ty
704            }
705
706            fn omits_default_after_encode() -> bool
707            where
708                Self: Sized,
709            {
710                false
711            }
712
713            fn encode(&self, _buffer: &mut Buffer) -> Result<Unit, MutableError> {
714                Ok(serialize_scalar::<$ty>(*self))
715            }
716        }
717
718        impl<'a> MutableArrayElement<'a> for $ty {
719            fn decode_array(words: &'a [u32]) -> Option<Vec<Self>> {
720                Some(
721                    ArrayView::new(words)?
722                        .scalars::<$ty>()?
723                        .iter()
724                        .collect::<Vec<_>>(),
725                )
726            }
727
728            fn encode_array(values: &[Self], buffer: &mut Buffer) -> Result<Unit, MutableError> {
729                let width = <$ty as Scalar>::WIDTH as u32;
730                if values.is_empty() {
731                    return Ok(Unit::inline(&[width]));
732                }
733                let last = buffer.len();
734                for value in values.iter().rev() {
735                    value
736                        .write_words(buffer.expand(<$ty as Scalar>::WIDTH))
737                        .expect("scalar width must match");
738                }
739                buffer.put(((values.len() as u32) << 2) | width);
740                Ok(Unit::segment(last, buffer.len()))
741            }
742        }
743    };
744}
745
746macro_rules! impl_scalar_map_key {
747    ($ty:ty, $map_kind:ident) => {
748        impl<'a> MutableMapKey<'a> for $ty {
749            fn decode_key(field: FieldView<'a>) -> Option<Self> {
750                field.scalar::<$ty>()
751            }
752
753            fn detect_key(field: FieldView<'a>) -> Option<&'a [u32]> {
754                field.detect_scalar()
755            }
756
757            fn encode_key(&self, _buffer: &mut Buffer) -> Result<Unit, MutableError> {
758                Ok(serialize_scalar::<$ty>(*self))
759            }
760
761            fn key_kind() -> MutableMapKeyKind {
762                MutableMapKeyKind::$map_kind
763            }
764
765            fn write_key_bytes<'b>(&'b self, scratch: &'b mut [u8; 8]) -> &'b [u8] {
766                let bytes = MapKey::as_key_bytes(self);
767                let len = bytes.len();
768                scratch[..len].copy_from_slice(&bytes);
769                &scratch[..len]
770            }
771        }
772    };
773}
774
775impl<'a> MutableField<'a> for bool {
776    fn decode(field: FieldView<'a>) -> Option<Self> {
777        field.scalar::<bool>()
778    }
779
780    fn detect(field: FieldView<'a>) -> Option<&'a [u32]> {
781        field.detect_scalar()
782    }
783
784    fn folds_when_present() -> bool
785    where
786        Self: Sized,
787    {
788        false
789    }
790
791    fn is_empty_field(&self) -> bool {
792        !*self
793    }
794
795    fn omits_default_after_encode() -> bool
796    where
797        Self: Sized,
798    {
799        false
800    }
801
802    fn encode(&self, _buffer: &mut Buffer) -> Result<Unit, MutableError> {
803        Ok(serialize_bool(*self))
804    }
805}
806
807impl<'a> MutableArrayElement<'a> for bool {
808    fn decode_array(words: &'a [u32]) -> Option<Vec<Self>> {
809        Some(StringView::new(words)?.as_bool_array().iter().collect())
810    }
811
812    fn detect_array_field(field: FieldView<'a>) -> Option<&'a [u32]> {
813        field.detect_string()
814    }
815
816    fn detect_array_words(words: &'a [u32]) -> Option<&'a [u32]> {
817        StringView::detect(words)
818    }
819
820    fn encode_array(values: &[Self], buffer: &mut Buffer) -> Result<Unit, MutableError> {
821        let bytes = values
822            .iter()
823            .map(|value| u8::from(*value))
824            .collect::<Vec<_>>();
825        serialize_bytes(&bytes, buffer).ok_or_else(|| MutableError::SerializeFailed {
826            descriptor: "<array>".to_owned(),
827            field: "<bool-array>".to_owned(),
828        })
829    }
830}
831
832impl_scalar_field!(i32);
833impl_scalar_field!(u32);
834impl_scalar_field!(i64);
835impl_scalar_field!(u64);
836impl_scalar_field!(f32);
837impl_scalar_field!(f64);
838impl_scalar_map_key!(i32, I32);
839impl_scalar_map_key!(u32, U32);
840impl_scalar_map_key!(i64, I64);
841impl_scalar_map_key!(u64, U64);
842
843impl<'a> MutableField<'a> for String {
844    fn decode(field: FieldView<'a>) -> Option<Self> {
845        Some(field.string()?.as_str()?.to_owned())
846    }
847
848    fn detect(field: FieldView<'a>) -> Option<&'a [u32]> {
849        field.detect_string()
850    }
851
852    fn is_empty_field(&self) -> bool {
853        self.is_empty()
854    }
855
856    fn omits_default_after_encode() -> bool
857    where
858        Self: Sized,
859    {
860        false
861    }
862
863    fn encode(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
864        serialize_str(self, buffer).ok_or_else(|| MutableError::SerializeFailed {
865            descriptor: "<string>".to_owned(),
866            field: "<encode>".to_owned(),
867        })
868    }
869}
870
871impl<'a> MutableArrayElement<'a> for String {
872    fn decode_array(words: &'a [u32]) -> Option<Vec<Self>> {
873        let array = ArrayView::new(words)?;
874        let mut values = Vec::with_capacity(array.len());
875        for item in array.iter() {
876            values.push(Self::decode(item)?);
877        }
878        Some(values)
879    }
880
881    fn encode_array(values: &[Self], buffer: &mut Buffer) -> Result<Unit, MutableError> {
882        encode_object_array(values, buffer)
883    }
884}
885
886impl<'a> MutableMapKey<'a> for String {
887    fn decode_key(field: FieldView<'a>) -> Option<Self> {
888        Some(field.string()?.as_str()?.to_owned())
889    }
890
891    fn detect_key(field: FieldView<'a>) -> Option<&'a [u32]> {
892        field.detect_string()
893    }
894
895    fn encode_key(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
896        serialize_str(self, buffer).ok_or_else(|| MutableError::SerializeFailed {
897            descriptor: "<map>".to_owned(),
898            field: "<string-key>".to_owned(),
899        })
900    }
901
902    fn key_kind() -> MutableMapKeyKind {
903        MutableMapKeyKind::String
904    }
905
906    fn borrowed_key_bytes(&self) -> Option<&[u8]> {
907        Some(self.as_bytes())
908    }
909
910    fn write_key_bytes<'b>(&'b self, _scratch: &'b mut [u8; 8]) -> &'b [u8] {
911        self.as_bytes()
912    }
913}
914
915impl<'a> MutableField<'a> for Vec<u8> {
916    fn decode(field: FieldView<'a>) -> Option<Self> {
917        Some(field.string()?.as_bytes().to_vec())
918    }
919
920    fn detect(field: FieldView<'a>) -> Option<&'a [u32]> {
921        field.detect_string()
922    }
923
924    fn is_empty_field(&self) -> bool {
925        self.is_empty()
926    }
927
928    fn omits_default_after_encode() -> bool
929    where
930        Self: Sized,
931    {
932        false
933    }
934
935    fn encode(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
936        serialize_bytes(self, buffer).ok_or_else(|| MutableError::SerializeFailed {
937            descriptor: "<bytes>".to_owned(),
938            field: "<encode>".to_owned(),
939        })
940    }
941}
942
943impl<'a> MutableArrayElement<'a> for Vec<u8> {
944    fn decode_array(words: &'a [u32]) -> Option<Vec<Self>> {
945        let array = ArrayView::new(words)?;
946        let mut values = Vec::with_capacity(array.len());
947        for item in array.iter() {
948            values.push(Self::decode(item)?);
949        }
950        Some(values)
951    }
952
953    fn encode_array(values: &[Self], buffer: &mut Buffer) -> Result<Unit, MutableError> {
954        encode_object_array(values, buffer)
955    }
956}
957
958impl<'a, T: MutableArrayElement<'a>> MutableField<'a> for MutableArray<'a, T> {
959    fn decode(field: FieldView<'a>) -> Option<Self> {
960        Self::from_words(field.object_words()?)
961    }
962
963    #[inline(always)]
964    fn detect(field: FieldView<'a>) -> Option<&'a [u32]> {
965        Self::detect_array_field(field)
966    }
967
968    fn encode(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
969        self.encode_to_unit(buffer)
970    }
971
972    fn is_empty_field(&self) -> bool {
973        self.values.is_empty()
974    }
975
976    fn omits_default_after_encode() -> bool
977    where
978        Self: Sized,
979    {
980        false
981    }
982
983    fn is_dirty(&self) -> bool {
984        self.dirty || self.values.iter().any(MutableField::has_nested_dirty)
985    }
986
987    fn has_nested_dirty(&self) -> bool {
988        self.is_dirty()
989    }
990}
991
992impl<'a, K: MutableMapKey<'a>, V: MutableField<'a>> MutableField<'a> for MutableMap<'a, K, V> {
993    fn decode(field: FieldView<'a>) -> Option<Self> {
994        Self::from_words(field.object_words()?)
995    }
996
997    #[inline(always)]
998    fn detect(field: FieldView<'a>) -> Option<&'a [u32]> {
999        detect_map_words::<K, V>(field.object_words()?)
1000    }
1001
1002    fn encode(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
1003        self.encode_to_unit(buffer)
1004    }
1005
1006    fn is_empty_field(&self) -> bool {
1007        self.entries.is_empty()
1008    }
1009
1010    fn omits_default_after_encode() -> bool
1011    where
1012        Self: Sized,
1013    {
1014        false
1015    }
1016
1017    fn is_dirty(&self) -> bool {
1018        self.dirty
1019            || self
1020                .entries
1021                .iter()
1022                .any(|(_, value)| value.has_nested_dirty())
1023    }
1024
1025    fn has_nested_dirty(&self) -> bool {
1026        self.is_dirty()
1027    }
1028}
1029
1030impl<'a, T: MutableArrayElement<'a>> MutableArrayElement<'a> for MutableArray<'a, T> {
1031    fn decode_array(words: &'a [u32]) -> Option<Vec<Self>> {
1032        let array = ArrayView::new(words)?;
1033        let mut values = Vec::with_capacity(array.len());
1034        for item in array.iter() {
1035            values.push(Self::from_words(item.object_words()?)?);
1036        }
1037        Some(values)
1038    }
1039
1040    #[inline(always)]
1041    fn detect_array_field(field: FieldView<'a>) -> Option<&'a [u32]> {
1042        field
1043            .object_words()
1044            .and_then(detect_array_words::<T>)
1045            .or_else(|| T::detect_array_field(field))
1046    }
1047
1048    fn encode_array(values: &[Self], buffer: &mut Buffer) -> Result<Unit, MutableError> {
1049        encode_object_array(values, buffer)
1050    }
1051}
1052
1053impl<'a, K: MutableMapKey<'a>, V: MutableField<'a>> MutableArrayElement<'a>
1054    for MutableMap<'a, K, V>
1055{
1056    fn decode_array(words: &'a [u32]) -> Option<Vec<Self>> {
1057        let array = ArrayView::new(words)?;
1058        let mut values = Vec::with_capacity(array.len());
1059        for item in array.iter() {
1060            values.push(Self::from_words(item.object_words()?)?);
1061        }
1062        Some(values)
1063    }
1064
1065    fn encode_array(values: &[Self], buffer: &mut Buffer) -> Result<Unit, MutableError> {
1066        encode_object_array(values, buffer)
1067    }
1068}
1069
1070impl<'a, T: MutableField<'a>> MutableField<'a> for Box<T> {
1071    fn decode(field: FieldView<'a>) -> Option<Self> {
1072        Some(Box::new(T::decode(field)?))
1073    }
1074
1075    #[inline(always)]
1076    fn detect(field: FieldView<'a>) -> Option<&'a [u32]> {
1077        T::detect(field)
1078    }
1079
1080    #[inline(always)]
1081    fn encode(&self, buffer: &mut Buffer) -> Result<Unit, MutableError> {
1082        self.as_ref().encode(buffer)
1083    }
1084
1085    #[inline(always)]
1086    fn is_dirty(&self) -> bool {
1087        self.as_ref().is_dirty()
1088    }
1089
1090    #[inline(always)]
1091    fn has_nested_dirty(&self) -> bool {
1092        self.as_ref().has_nested_dirty()
1093    }
1094}
1095
1096fn encode_object_array<'a, T: MutableField<'a>>(
1097    values: &[T],
1098    buffer: &mut Buffer,
1099) -> Result<Unit, MutableError> {
1100    const STACK_UNITS: usize = 32;
1101
1102    if values.is_empty() {
1103        return Ok(Unit::inline(&[1]));
1104    }
1105    let last = buffer.len();
1106    if values.len() <= STACK_UNITS {
1107        let mut units = array::from_fn::<_, STACK_UNITS, _>(|_| Unit::empty());
1108        for i in (0..values.len()).rev() {
1109            units[i] = values[i].encode(buffer)?;
1110        }
1111        return serialize_array_at_mut(&mut units[..values.len()], buffer, last).ok_or_else(|| {
1112            MutableError::SerializeFailed {
1113                descriptor: "<array>".to_owned(),
1114                field: "<encode>".to_owned(),
1115            }
1116        });
1117    }
1118
1119    let mut units = vec![Unit::empty(); values.len()];
1120    for i in (0..values.len()).rev() {
1121        units[i] = values[i].encode(buffer)?;
1122    }
1123    serialize_array_at_mut(&mut units, buffer, last).ok_or_else(|| MutableError::SerializeFailed {
1124        descriptor: "<array>".to_owned(),
1125        field: "<encode>".to_owned(),
1126    })
1127}
1128
1129#[cfg(test)]
1130mod tests {
1131    use super::{MutableArray, MutableMap, drop_present_unit, should_omit_message_unit};
1132    use crate::mutable::MutableField;
1133    use crate::{ArrayView, Buffer, MapView, Unit};
1134
1135    #[test]
1136    fn array_ex_iter_mut_marks_collection_dirty() {
1137        let mut array = MutableArray::from(vec![1u32, 2u32]);
1138        assert!(!array.is_dirty());
1139
1140        for value in &mut array {
1141            *value += 10;
1142        }
1143
1144        assert!(array.is_dirty());
1145        assert_eq!(array.as_slice(), &[11, 12]);
1146    }
1147
1148    #[test]
1149    fn map_ex_get_mut_marks_collection_dirty() {
1150        let mut map = MutableMap::from_iter([("alpha".to_owned(), 1u32)]);
1151        assert!(!map.is_dirty());
1152
1153        *map.get_mut("alpha").unwrap() = 7;
1154
1155        assert!(map.is_dirty());
1156        assert_eq!(map.get("alpha"), Some(&7));
1157    }
1158
1159    #[test]
1160    fn map_ex_mut_into_iter_marks_collection_dirty() {
1161        let mut map =
1162            MutableMap::from_iter([("alpha".to_owned(), 1u32), ("beta".to_owned(), 2u32)]);
1163        assert!(!map.is_dirty());
1164
1165        for (_, value) in &mut map {
1166            *value *= 2;
1167        }
1168
1169        assert!(map.is_dirty());
1170        assert_eq!(map.get("alpha"), Some(&2));
1171        assert_eq!(map.get("beta"), Some(&4));
1172    }
1173
1174    #[test]
1175    fn map_ex_supports_borrowed_string_lookup() {
1176        let mut map =
1177            MutableMap::from_iter([("alpha".to_owned(), 1u32), ("beta".to_owned(), 2u32)]);
1178
1179        assert!(map.contains_key("alpha"));
1180        assert_eq!(map.get("beta"), Some(&2));
1181        assert_eq!(map.remove("alpha"), Some(1));
1182        assert!(!map.contains_key("alpha"));
1183    }
1184
1185    #[test]
1186    fn default_present_units_are_omitted_by_shape() {
1187        assert!(should_omit_message_unit(&Unit::inline(&[0])));
1188        assert!(should_omit_message_unit(&Unit::inline(&[1])));
1189        assert!(!should_omit_message_unit(&Unit::inline(&[0, 0])));
1190        assert!(!should_omit_message_unit(&Unit::inline(&[2, 0])));
1191    }
1192
1193    #[test]
1194    fn dropping_segment_present_unit_rewinds_buffer() {
1195        let mut buffer = Buffer::new();
1196        buffer.put(0);
1197        let mut unit = Unit::segment(0, buffer.len());
1198
1199        assert!(should_omit_message_unit(&unit));
1200        drop_present_unit(&mut buffer, &mut unit);
1201
1202        assert!(buffer.is_empty());
1203        assert!(unit.is_empty());
1204    }
1205
1206    #[test]
1207    fn mutable_nested_float_arrays_roundtrip() {
1208        let mut rows = MutableArray::new();
1209        rows.push(MutableArray::new());
1210        rows.push(MutableArray::from(vec![7.0f32, 8.0, 9.0]));
1211
1212        let mut buffer = Buffer::new();
1213        let unit = rows.encode(&mut buffer).unwrap();
1214        assert!(unit.is_segment());
1215
1216        let view = ArrayView::new(buffer.view()).unwrap();
1217        assert_eq!(view.len(), 2);
1218
1219        let row0 = ArrayView::new(view.field(0).unwrap().object_words().unwrap()).unwrap();
1220        assert!(row0.scalars::<f32>().unwrap().is_empty());
1221
1222        let row1_words = view.field(1).unwrap().object_words().unwrap();
1223        let row1 = ArrayView::new(row1_words).unwrap();
1224        assert_eq!(row1.width(), 1, "row1 words: {:?}", row1_words);
1225        assert_eq!(
1226            row1.scalars::<f32>().unwrap().iter().collect::<Vec<_>>(),
1227            vec![7.0, 8.0, 9.0]
1228        );
1229    }
1230
1231    #[test]
1232    fn empty_mutable_map_encodes_as_inline_empty_map() {
1233        let map = MutableMap::<String, i32>::new();
1234        let mut buffer = Buffer::new();
1235
1236        let unit = map.encode_to_unit(&mut buffer).unwrap();
1237
1238        assert_eq!(unit.inline_words(), &[5u32 << 28]);
1239        assert_eq!(buffer.len(), 0);
1240        assert_eq!(MapView::new(unit.inline_words()).unwrap().len(), 0);
1241    }
1242
1243    #[test]
1244    fn mutable_array_with_empty_map_element_roundtrips() {
1245        let map = MutableMap::<String, i32>::new();
1246        let maps = MutableArray::from(vec![map]);
1247        let mut buffer = Buffer::new();
1248
1249        maps.encode_to_unit(&mut buffer).unwrap();
1250
1251        let array = ArrayView::new(buffer.view()).unwrap();
1252        assert_eq!(array.len(), 1);
1253        let map_words = array.field(0).unwrap().object_words().unwrap();
1254        assert_eq!(MapView::new(map_words).unwrap().len(), 0);
1255    }
1256
1257    #[test]
1258    fn mutable_string_key_float_array_map_roundtrip() {
1259        let mut map = MutableMap::new();
1260        map.insert(
1261            "lv5".to_owned(),
1262            MutableArray::from(vec![51.0f32, 52.0, 53.0]),
1263        );
1264        map.insert("lv9".to_owned(), MutableArray::from(vec![91.0f32, 92.0]));
1265
1266        let mut buffer = Buffer::new();
1267        let unit = map.encode(&mut buffer).unwrap();
1268        assert!(unit.is_segment());
1269
1270        let view = MapView::new(buffer.view()).unwrap();
1271        let available = view
1272            .iter()
1273            .filter_map(|pair| {
1274                pair.key()
1275                    .string()
1276                    .and_then(|key| key.as_str().map(str::to_owned))
1277            })
1278            .collect::<Vec<_>>();
1279        let lv5 = view
1280            .find_str("lv5")
1281            .unwrap_or_else(|| panic!("available keys: {available:?}, words: {:?}", buffer.view()))
1282            .value()
1283            .array()
1284            .unwrap();
1285        assert_eq!(
1286            lv5.scalars::<f32>().unwrap().iter().collect::<Vec<_>>(),
1287            vec![51.0, 52.0, 53.0]
1288        );
1289        let lv9 = view.find_str("lv9").unwrap().value().array().unwrap();
1290        assert_eq!(
1291            lv9.scalars::<f32>().unwrap().iter().collect::<Vec<_>>(),
1292            vec![91.0, 92.0]
1293        );
1294    }
1295}