Skip to main content

miden_serde_utils/
lib.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6#![cfg_attr(not(feature = "std"), no_std)]
7
8extern crate alloc;
9
10use alloc::{
11    collections::{BTreeMap, BTreeSet},
12    format,
13    string::String,
14    sync::Arc,
15    vec::Vec,
16};
17use core::mem::size_of;
18
19// ERROR
20// ================================================================================================
21
22/// Defines errors which can occur during deserialization.
23#[derive(Clone, Debug, PartialEq, Eq)]
24pub enum DeserializationError {
25    /// Indicates that the deserialization failed because of insufficient data.
26    UnexpectedEOF,
27    /// Indicates that the deserialization failed because the value was not valid.
28    InvalidValue(String),
29    /// Indicates that deserialization failed for an unknown reason.
30    UnknownError(String),
31}
32
33#[cfg(feature = "std")]
34impl std::error::Error for DeserializationError {}
35
36impl core::fmt::Display for DeserializationError {
37    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38        match self {
39            Self::UnexpectedEOF => write!(f, "unexpected end of file"),
40            Self::InvalidValue(msg) => write!(f, "invalid value: {msg}"),
41            Self::UnknownError(msg) => write!(f, "unknown error: {msg}"),
42        }
43    }
44}
45
46mod byte_reader;
47#[cfg(feature = "std")]
48pub use byte_reader::ReadAdapter;
49pub use byte_reader::{BudgetedReader, ByteReader, ReadManyIter, SliceReader};
50
51mod byte_writer;
52pub use byte_writer::ByteWriter;
53
54// SERIALIZABLE TRAIT
55// ================================================================================================
56
57/// Defines how to serialize `Self` into bytes.
58pub trait Serializable {
59    // REQUIRED METHODS
60    // --------------------------------------------------------------------------------------------
61    /// Serializes `self` into bytes and writes these bytes into the `target`.
62    fn write_into<W: ByteWriter>(&self, target: &mut W);
63
64    // PROVIDED METHODS
65    // --------------------------------------------------------------------------------------------
66
67    /// Serializes `self` into a vector of bytes.
68    fn to_bytes(&self) -> Vec<u8> {
69        let mut result = Vec::with_capacity(self.get_size_hint());
70        self.write_into(&mut result);
71        result
72    }
73
74    /// Returns an estimate of how many bytes are needed to represent self.
75    ///
76    /// The default implementation returns zero.
77    fn get_size_hint(&self) -> usize {
78        0
79    }
80}
81
82impl<T: Serializable> Serializable for &T {
83    fn write_into<W: ByteWriter>(&self, target: &mut W) {
84        (*self).write_into(target)
85    }
86
87    fn get_size_hint(&self) -> usize {
88        (*self).get_size_hint()
89    }
90}
91
92impl Serializable for () {
93    fn write_into<W: ByteWriter>(&self, _target: &mut W) {}
94
95    fn get_size_hint(&self) -> usize {
96        0
97    }
98}
99
100impl<T1> Serializable for (T1,)
101where
102    T1: Serializable,
103{
104    fn write_into<W: ByteWriter>(&self, target: &mut W) {
105        self.0.write_into(target);
106    }
107
108    fn get_size_hint(&self) -> usize {
109        self.0.get_size_hint()
110    }
111}
112
113impl<T1, T2> Serializable for (T1, T2)
114where
115    T1: Serializable,
116    T2: Serializable,
117{
118    fn write_into<W: ByteWriter>(&self, target: &mut W) {
119        self.0.write_into(target);
120        self.1.write_into(target);
121    }
122
123    fn get_size_hint(&self) -> usize {
124        self.0.get_size_hint() + self.1.get_size_hint()
125    }
126}
127
128impl<T1, T2, T3> Serializable for (T1, T2, T3)
129where
130    T1: Serializable,
131    T2: Serializable,
132    T3: Serializable,
133{
134    fn write_into<W: ByteWriter>(&self, target: &mut W) {
135        self.0.write_into(target);
136        self.1.write_into(target);
137        self.2.write_into(target);
138    }
139
140    fn get_size_hint(&self) -> usize {
141        self.0.get_size_hint() + self.1.get_size_hint() + self.2.get_size_hint()
142    }
143}
144
145impl<T1, T2, T3, T4> Serializable for (T1, T2, T3, T4)
146where
147    T1: Serializable,
148    T2: Serializable,
149    T3: Serializable,
150    T4: Serializable,
151{
152    fn write_into<W: ByteWriter>(&self, target: &mut W) {
153        self.0.write_into(target);
154        self.1.write_into(target);
155        self.2.write_into(target);
156        self.3.write_into(target);
157    }
158
159    fn get_size_hint(&self) -> usize {
160        self.0.get_size_hint()
161            + self.1.get_size_hint()
162            + self.2.get_size_hint()
163            + self.3.get_size_hint()
164    }
165}
166
167impl<T1, T2, T3, T4, T5> Serializable for (T1, T2, T3, T4, T5)
168where
169    T1: Serializable,
170    T2: Serializable,
171    T3: Serializable,
172    T4: Serializable,
173    T5: Serializable,
174{
175    fn write_into<W: ByteWriter>(&self, target: &mut W) {
176        self.0.write_into(target);
177        self.1.write_into(target);
178        self.2.write_into(target);
179        self.3.write_into(target);
180        self.4.write_into(target);
181    }
182
183    fn get_size_hint(&self) -> usize {
184        self.0.get_size_hint()
185            + self.1.get_size_hint()
186            + self.2.get_size_hint()
187            + self.3.get_size_hint()
188            + self.4.get_size_hint()
189    }
190}
191
192impl<T1, T2, T3, T4, T5, T6> Serializable for (T1, T2, T3, T4, T5, T6)
193where
194    T1: Serializable,
195    T2: Serializable,
196    T3: Serializable,
197    T4: Serializable,
198    T5: Serializable,
199    T6: Serializable,
200{
201    fn write_into<W: ByteWriter>(&self, target: &mut W) {
202        self.0.write_into(target);
203        self.1.write_into(target);
204        self.2.write_into(target);
205        self.3.write_into(target);
206        self.4.write_into(target);
207        self.5.write_into(target);
208    }
209
210    fn get_size_hint(&self) -> usize {
211        self.0.get_size_hint()
212            + self.1.get_size_hint()
213            + self.2.get_size_hint()
214            + self.3.get_size_hint()
215            + self.4.get_size_hint()
216            + self.5.get_size_hint()
217    }
218}
219
220impl Serializable for u8 {
221    fn write_into<W: ByteWriter>(&self, target: &mut W) {
222        target.write_u8(*self);
223    }
224
225    fn get_size_hint(&self) -> usize {
226        size_of::<u8>()
227    }
228}
229
230impl Serializable for u16 {
231    fn write_into<W: ByteWriter>(&self, target: &mut W) {
232        target.write_u16(*self);
233    }
234
235    fn get_size_hint(&self) -> usize {
236        size_of::<u16>()
237    }
238}
239
240impl Serializable for u32 {
241    fn write_into<W: ByteWriter>(&self, target: &mut W) {
242        target.write_u32(*self);
243    }
244
245    fn get_size_hint(&self) -> usize {
246        size_of::<u32>()
247    }
248}
249
250impl Serializable for u64 {
251    fn write_into<W: ByteWriter>(&self, target: &mut W) {
252        target.write_u64(*self);
253    }
254
255    fn get_size_hint(&self) -> usize {
256        size_of::<u64>()
257    }
258}
259
260impl Serializable for u128 {
261    fn write_into<W: ByteWriter>(&self, target: &mut W) {
262        target.write_u128(*self);
263    }
264
265    fn get_size_hint(&self) -> usize {
266        size_of::<u128>()
267    }
268}
269
270impl Serializable for usize {
271    fn write_into<W: ByteWriter>(&self, target: &mut W) {
272        target.write_usize(*self)
273    }
274
275    fn get_size_hint(&self) -> usize {
276        byte_writer::usize_encoded_len(*self as u64)
277    }
278}
279
280impl<T: Serializable> Serializable for Option<T> {
281    fn write_into<W: ByteWriter>(&self, target: &mut W) {
282        match self {
283            Some(v) => {
284                target.write_bool(true);
285                v.write_into(target);
286            },
287            None => target.write_bool(false),
288        }
289    }
290
291    fn get_size_hint(&self) -> usize {
292        size_of::<bool>() + self.as_ref().map(Serializable::get_size_hint).unwrap_or(0)
293    }
294}
295
296impl<T: Serializable, const C: usize> Serializable for [T; C] {
297    fn write_into<W: ByteWriter>(&self, target: &mut W) {
298        target.write_many(self)
299    }
300
301    fn get_size_hint(&self) -> usize {
302        let mut size = 0;
303        for item in self {
304            size += item.get_size_hint();
305        }
306        size
307    }
308}
309
310impl<T: Serializable> Serializable for [T] {
311    fn write_into<W: ByteWriter>(&self, target: &mut W) {
312        target.write_usize(self.len());
313        for element in self.iter() {
314            element.write_into(target);
315        }
316    }
317
318    fn get_size_hint(&self) -> usize {
319        let mut size = self.len().get_size_hint();
320        for element in self {
321            size += element.get_size_hint();
322        }
323        size
324    }
325}
326
327impl<T: Serializable> Serializable for Vec<T> {
328    fn write_into<W: ByteWriter>(&self, target: &mut W) {
329        target.write_usize(self.len());
330        target.write_many(self);
331    }
332
333    fn get_size_hint(&self) -> usize {
334        let mut size = self.len().get_size_hint();
335        for item in self {
336            size += item.get_size_hint();
337        }
338        size
339    }
340}
341
342impl<K: Serializable, V: Serializable> Serializable for BTreeMap<K, V> {
343    fn write_into<W: ByteWriter>(&self, target: &mut W) {
344        target.write_usize(self.len());
345        target.write_many(self);
346    }
347
348    fn get_size_hint(&self) -> usize {
349        let mut size = self.len().get_size_hint();
350        for item in self {
351            size += item.get_size_hint();
352        }
353        size
354    }
355}
356
357impl<T: Serializable> Serializable for BTreeSet<T> {
358    fn write_into<W: ByteWriter>(&self, target: &mut W) {
359        target.write_usize(self.len());
360        target.write_many(self);
361    }
362
363    fn get_size_hint(&self) -> usize {
364        let mut size = self.len().get_size_hint();
365        for item in self {
366            size += item.get_size_hint();
367        }
368        size
369    }
370}
371
372impl Serializable for str {
373    fn write_into<W: ByteWriter>(&self, target: &mut W) {
374        target.write_usize(self.len());
375        target.write_many(self.as_bytes());
376    }
377
378    fn get_size_hint(&self) -> usize {
379        self.len().get_size_hint() + self.len()
380    }
381}
382
383impl Serializable for String {
384    fn write_into<W: ByteWriter>(&self, target: &mut W) {
385        self.as_str().write_into(target);
386    }
387
388    fn get_size_hint(&self) -> usize {
389        self.as_str().get_size_hint()
390    }
391}
392
393impl Serializable for Arc<str> {
394    fn write_into<W: ByteWriter>(&self, target: &mut W) {
395        self.as_ref().write_into(target);
396    }
397
398    fn get_size_hint(&self) -> usize {
399        self.as_ref().get_size_hint()
400    }
401}
402
403// DESERIALIZABLE
404// ================================================================================================
405
406/// Defines how to deserialize `Self` from bytes.
407pub trait Deserializable: Sized {
408    // REQUIRED METHODS
409    // --------------------------------------------------------------------------------------------
410
411    /// Reads a sequence of bytes from the provided `source`, attempts to deserialize these bytes
412    /// into `Self`, and returns the result.
413    ///
414    /// # Errors
415    /// Returns an error if:
416    /// * The `source` does not contain enough bytes to deserialize `Self`.
417    /// * Bytes read from the `source` do not represent a valid value for `Self`.
418    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError>;
419
420    /// Returns the minimum serialized size for one instance of this type.
421    ///
422    /// This is used by [`ByteReader::max_alloc`] to estimate how many elements can be
423    /// deserialized from the remaining budget, preventing denial-of-service attacks from
424    /// malicious length prefixes.
425    ///
426    /// The default implementation returns `size_of::<Self>()`, which is conservative: it may
427    /// reject valid input for types where the serialized size is smaller than the in-memory
428    /// size (e.g., structs with computed/cached fields that aren't serialized).
429    ///
430    /// Override this method for types where the serialized representation is smaller than
431    /// the in-memory representation to allow more elements to be deserialized.
432    fn min_serialized_size() -> usize {
433        size_of::<Self>()
434    }
435
436    // PROVIDED METHODS
437    // --------------------------------------------------------------------------------------------
438
439    /// Attempts to deserialize the provided `bytes` into `Self` and returns the result.
440    ///
441    /// # Errors
442    /// Returns an error if:
443    /// * The `bytes` do not contain enough information to deserialize `Self`.
444    /// * The `bytes` do not represent a valid value for `Self`.
445    ///
446    /// Note: if `bytes` contains more data than needed to deserialize `self`, no error is
447    /// returned.
448    fn read_from_bytes(bytes: &[u8]) -> Result<Self, DeserializationError> {
449        Self::read_from(&mut SliceReader::new(bytes))
450    }
451
452    /// Deserializes `Self` from bytes with a byte budget limit.
453    ///
454    /// This is the recommended method for deserializing untrusted input. The budget limits
455    /// how many bytes can be consumed during deserialization, preventing denial-of-service
456    /// attacks that exploit length fields to cause huge allocations.
457    ///
458    /// # Errors
459    /// Returns an error if:
460    /// * The budget is exhausted before deserialization completes.
461    /// * The `bytes` do not contain enough information to deserialize `Self`.
462    /// * The `bytes` do not represent a valid value for `Self`.
463    fn read_from_bytes_with_budget(
464        bytes: &[u8],
465        budget: usize,
466    ) -> Result<Self, DeserializationError> {
467        Self::read_from(&mut BudgetedReader::new(SliceReader::new(bytes), budget))
468    }
469}
470
471impl Deserializable for () {
472    fn read_from<R: ByteReader>(_source: &mut R) -> Result<Self, DeserializationError> {
473        Ok(())
474    }
475}
476
477impl<T1> Deserializable for (T1,)
478where
479    T1: Deserializable,
480{
481    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
482        let v1 = T1::read_from(source)?;
483        Ok((v1,))
484    }
485
486    fn min_serialized_size() -> usize {
487        T1::min_serialized_size()
488    }
489}
490
491impl<T1, T2> Deserializable for (T1, T2)
492where
493    T1: Deserializable,
494    T2: Deserializable,
495{
496    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
497        let v1 = T1::read_from(source)?;
498        let v2 = T2::read_from(source)?;
499        Ok((v1, v2))
500    }
501
502    fn min_serialized_size() -> usize {
503        T1::min_serialized_size().saturating_add(T2::min_serialized_size())
504    }
505}
506
507impl<T1, T2, T3> Deserializable for (T1, T2, T3)
508where
509    T1: Deserializable,
510    T2: Deserializable,
511    T3: Deserializable,
512{
513    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
514        let v1 = T1::read_from(source)?;
515        let v2 = T2::read_from(source)?;
516        let v3 = T3::read_from(source)?;
517        Ok((v1, v2, v3))
518    }
519
520    fn min_serialized_size() -> usize {
521        T1::min_serialized_size()
522            .saturating_add(T2::min_serialized_size())
523            .saturating_add(T3::min_serialized_size())
524    }
525}
526
527impl<T1, T2, T3, T4> Deserializable for (T1, T2, T3, T4)
528where
529    T1: Deserializable,
530    T2: Deserializable,
531    T3: Deserializable,
532    T4: Deserializable,
533{
534    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
535        let v1 = T1::read_from(source)?;
536        let v2 = T2::read_from(source)?;
537        let v3 = T3::read_from(source)?;
538        let v4 = T4::read_from(source)?;
539        Ok((v1, v2, v3, v4))
540    }
541
542    fn min_serialized_size() -> usize {
543        T1::min_serialized_size()
544            .saturating_add(T2::min_serialized_size())
545            .saturating_add(T3::min_serialized_size())
546            .saturating_add(T4::min_serialized_size())
547    }
548}
549
550impl<T1, T2, T3, T4, T5> Deserializable for (T1, T2, T3, T4, T5)
551where
552    T1: Deserializable,
553    T2: Deserializable,
554    T3: Deserializable,
555    T4: Deserializable,
556    T5: Deserializable,
557{
558    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
559        let v1 = T1::read_from(source)?;
560        let v2 = T2::read_from(source)?;
561        let v3 = T3::read_from(source)?;
562        let v4 = T4::read_from(source)?;
563        let v5 = T5::read_from(source)?;
564        Ok((v1, v2, v3, v4, v5))
565    }
566
567    fn min_serialized_size() -> usize {
568        T1::min_serialized_size()
569            .saturating_add(T2::min_serialized_size())
570            .saturating_add(T3::min_serialized_size())
571            .saturating_add(T4::min_serialized_size())
572            .saturating_add(T5::min_serialized_size())
573    }
574}
575
576impl<T1, T2, T3, T4, T5, T6> Deserializable for (T1, T2, T3, T4, T5, T6)
577where
578    T1: Deserializable,
579    T2: Deserializable,
580    T3: Deserializable,
581    T4: Deserializable,
582    T5: Deserializable,
583    T6: Deserializable,
584{
585    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
586        let v1 = T1::read_from(source)?;
587        let v2 = T2::read_from(source)?;
588        let v3 = T3::read_from(source)?;
589        let v4 = T4::read_from(source)?;
590        let v5 = T5::read_from(source)?;
591        let v6 = T6::read_from(source)?;
592        Ok((v1, v2, v3, v4, v5, v6))
593    }
594
595    fn min_serialized_size() -> usize {
596        T1::min_serialized_size()
597            .saturating_add(T2::min_serialized_size())
598            .saturating_add(T3::min_serialized_size())
599            .saturating_add(T4::min_serialized_size())
600            .saturating_add(T5::min_serialized_size())
601            .saturating_add(T6::min_serialized_size())
602    }
603}
604
605impl Deserializable for u8 {
606    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
607        source.read_u8()
608    }
609}
610
611impl Deserializable for u16 {
612    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
613        source.read_u16()
614    }
615}
616
617impl Deserializable for u32 {
618    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
619        source.read_u32()
620    }
621}
622
623impl Deserializable for u64 {
624    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
625        source.read_u64()
626    }
627}
628
629impl Deserializable for u128 {
630    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
631        source.read_u128()
632    }
633}
634
635impl Deserializable for usize {
636    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
637        source.read_usize()
638    }
639
640    fn min_serialized_size() -> usize {
641        1 // vint64 encoding: minimum 1 byte for values 0-127
642    }
643}
644
645impl<T: Deserializable> Deserializable for Option<T> {
646    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
647        if source.read_bool()? {
648            Ok(Some(T::read_from(source)?))
649        } else {
650            Ok(None)
651        }
652    }
653
654    /// Returns 1 (just the bool discriminator).
655    ///
656    /// The `Some` variant would be `1 + T::min_serialized_size()`, but we use the minimum
657    /// to allow more elements through the early check.
658    fn min_serialized_size() -> usize {
659        1
660    }
661}
662
663impl<T: Deserializable, const C: usize> Deserializable for [T; C] {
664    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
665        let data: Vec<T> = source.read_many_iter(C)?.collect::<Result<_, _>>()?;
666
667        // The iterator yields exactly C elements (or fails early), so this always succeeds
668        Ok(data.try_into().unwrap_or_else(|v: Vec<T>| {
669            panic!("Expected a Vec of length {} but it was {}", C, v.len())
670        }))
671    }
672
673    fn min_serialized_size() -> usize {
674        C.saturating_mul(T::min_serialized_size())
675    }
676}
677
678impl<T: Deserializable> Deserializable for Vec<T> {
679    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
680        let len = source.read_usize()?;
681        source.read_many_iter(len)?.collect()
682    }
683
684    /// Returns 1 (the minimum vint length prefix size).
685    ///
686    /// The actual serialized size depends on the number of elements, which we don't know
687    /// at the point this is called. Using the minimum allows more elements through the
688    /// early check; budget enforcement during actual reads provides the real protection.
689    fn min_serialized_size() -> usize {
690        1
691    }
692}
693
694impl<K: Deserializable + Ord, V: Deserializable> Deserializable for BTreeMap<K, V> {
695    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
696        let len = source.read_usize()?;
697        let mut map = BTreeMap::new();
698        for entry in source.read_many_iter(len)? {
699            let (key, value) = entry?;
700            if map.insert(key, value).is_some() {
701                return Err(DeserializationError::InvalidValue(String::from(
702                    "duplicate key in BTreeMap encoding",
703                )));
704            }
705        }
706        Ok(map)
707    }
708
709    fn min_serialized_size() -> usize {
710        1 // minimum vint length prefix
711    }
712}
713
714impl<T: Deserializable + Ord> Deserializable for BTreeSet<T> {
715    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
716        let len = source.read_usize()?;
717        let mut set = BTreeSet::new();
718        for item in source.read_many_iter(len)? {
719            if !set.insert(item?) {
720                return Err(DeserializationError::InvalidValue(String::from(
721                    "duplicate item in BTreeSet encoding",
722                )));
723            }
724        }
725        Ok(set)
726    }
727
728    fn min_serialized_size() -> usize {
729        1 // minimum vint length prefix
730    }
731}
732
733impl Deserializable for String {
734    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
735        let len = source.read_usize()?;
736        let data: Vec<u8> = source.read_many_iter(len)?.collect::<Result<_, _>>()?;
737
738        String::from_utf8(data).map_err(|err| DeserializationError::InvalidValue(format!("{err}")))
739    }
740
741    fn min_serialized_size() -> usize {
742        1 // minimum vint length prefix
743    }
744}
745
746impl Deserializable for Arc<str> {
747    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
748        String::read_from(source).map(Arc::from)
749    }
750
751    fn min_serialized_size() -> usize {
752        1 // minimum vint length prefix
753    }
754}
755
756// GOLDILOCKS FIELD ELEMENT IMPLEMENTATIONS
757// ================================================================================================
758
759impl Serializable for p3_goldilocks::Goldilocks {
760    fn write_into<W: ByteWriter>(&self, target: &mut W) {
761        use p3_field::PrimeField64;
762        target.write_u64(self.as_canonical_u64());
763    }
764
765    fn get_size_hint(&self) -> usize {
766        size_of::<u64>()
767    }
768}
769
770impl Deserializable for p3_goldilocks::Goldilocks {
771    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
772        use p3_field::integers::QuotientMap;
773
774        let value = source.read_u64()?;
775        Self::from_canonical_checked(value).ok_or_else(|| {
776            DeserializationError::InvalidValue(format!(
777                "value {value} is not a valid Goldilocks field element"
778            ))
779        })
780    }
781}
782
783#[cfg(test)]
784mod tests {
785    use alloc::sync::Arc;
786
787    use super::*;
788
789    #[test]
790    fn arc_str_roundtrip() {
791        let original: Arc<str> = Arc::from("hello world");
792        let bytes = original.to_bytes();
793        let deserialized = Arc::<str>::read_from_bytes(&bytes).unwrap();
794        assert_eq!(original, deserialized);
795    }
796
797    #[test]
798    fn string_roundtrip() {
799        let original = String::from("hello world");
800        let bytes = original.to_bytes();
801        let deserialized = String::read_from_bytes(&bytes).unwrap();
802        assert_eq!(original, deserialized);
803    }
804
805    #[test]
806    fn empty_string_roundtrip() {
807        let arc: Arc<str> = Arc::from("");
808        let bytes = arc.to_bytes();
809        let deserialized = Arc::<str>::read_from_bytes(&bytes).unwrap();
810        assert_eq!(deserialized, Arc::from(""));
811
812        let string = String::from("");
813        let bytes = string.to_bytes();
814        let deserialized = String::read_from_bytes(&bytes).unwrap();
815        assert_eq!(deserialized, "");
816    }
817
818    #[test]
819    fn multibyte_utf8_roundtrip() {
820        let text = "héllo 🌍";
821
822        let arc: Arc<str> = Arc::from(text);
823        let bytes = arc.to_bytes();
824        let deserialized = Arc::<str>::read_from_bytes(&bytes).unwrap();
825        assert_eq!(&*deserialized, text);
826
827        let string = String::from(text);
828        let bytes = string.to_bytes();
829        let deserialized = String::read_from_bytes(&bytes).unwrap();
830        assert_eq!(deserialized, text);
831
832        // Cross-compat: Arc<str> bytes can be read as String and vice versa
833        let arc_bytes = Arc::<str>::from(text).to_bytes();
834        let string_bytes = String::from(text).to_bytes();
835        assert_eq!(arc_bytes, string_bytes);
836        assert_eq!(String::read_from_bytes(&arc_bytes).unwrap(), text);
837        assert_eq!(&*Arc::<str>::read_from_bytes(&string_bytes).unwrap(), text);
838    }
839
840    #[test]
841    fn arc_str_string_cross_compat() {
842        // Arc<str> -> bytes -> String
843        let arc: Arc<str> = Arc::from("cross type");
844        let bytes = arc.to_bytes();
845        let as_string = String::read_from_bytes(&bytes).unwrap();
846        assert_eq!(as_string, "cross type");
847
848        // String -> bytes -> Arc<str>
849        let string = String::from("other direction");
850        let bytes = string.to_bytes();
851        let as_arc = Arc::<str>::read_from_bytes(&bytes).unwrap();
852        assert_eq!(&*as_arc, "other direction");
853    }
854
855    #[test]
856    fn btree_map_rejects_duplicate_keys() {
857        let mut bytes = Vec::new();
858        bytes.extend_from_slice(&2usize.to_bytes());
859        bytes.extend_from_slice(&7u8.to_bytes());
860        bytes.extend_from_slice(&1u8.to_bytes());
861        bytes.extend_from_slice(&7u8.to_bytes());
862        bytes.extend_from_slice(&2u8.to_bytes());
863
864        let result = BTreeMap::<u8, u8>::read_from_bytes(&bytes);
865
866        assert!(matches!(result, Err(DeserializationError::InvalidValue(_))));
867    }
868
869    #[test]
870    fn btree_set_rejects_duplicate_items() {
871        let mut bytes = Vec::new();
872        bytes.extend_from_slice(&2usize.to_bytes());
873        bytes.extend_from_slice(&7u8.to_bytes());
874        bytes.extend_from_slice(&7u8.to_bytes());
875
876        let result = BTreeSet::<u8>::read_from_bytes(&bytes);
877
878        assert!(matches!(result, Err(DeserializationError::InvalidValue(_))));
879    }
880
881    #[test]
882    fn budgeted_vec_of_one_element_tuples_accepts_exact_budget() {
883        let values = Vec::<(usize,)>::from([(0,), (1,), (2,)]);
884        let bytes = values.to_bytes();
885
886        let decoded = Vec::<(usize,)>::read_from_bytes_with_budget(&bytes, bytes.len()).unwrap();
887
888        assert_eq!(decoded, values);
889    }
890}