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