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
487impl<T1, T2> Deserializable for (T1, T2)
488where
489    T1: Deserializable,
490    T2: Deserializable,
491{
492    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
493        let v1 = T1::read_from(source)?;
494        let v2 = T2::read_from(source)?;
495        Ok((v1, v2))
496    }
497
498    fn min_serialized_size() -> usize {
499        T1::min_serialized_size().saturating_add(T2::min_serialized_size())
500    }
501}
502
503impl<T1, T2, T3> Deserializable for (T1, T2, T3)
504where
505    T1: Deserializable,
506    T2: Deserializable,
507    T3: Deserializable,
508{
509    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
510        let v1 = T1::read_from(source)?;
511        let v2 = T2::read_from(source)?;
512        let v3 = T3::read_from(source)?;
513        Ok((v1, v2, v3))
514    }
515
516    fn min_serialized_size() -> usize {
517        T1::min_serialized_size()
518            .saturating_add(T2::min_serialized_size())
519            .saturating_add(T3::min_serialized_size())
520    }
521}
522
523impl<T1, T2, T3, T4> Deserializable for (T1, T2, T3, T4)
524where
525    T1: Deserializable,
526    T2: Deserializable,
527    T3: Deserializable,
528    T4: Deserializable,
529{
530    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
531        let v1 = T1::read_from(source)?;
532        let v2 = T2::read_from(source)?;
533        let v3 = T3::read_from(source)?;
534        let v4 = T4::read_from(source)?;
535        Ok((v1, v2, v3, v4))
536    }
537
538    fn min_serialized_size() -> usize {
539        T1::min_serialized_size()
540            .saturating_add(T2::min_serialized_size())
541            .saturating_add(T3::min_serialized_size())
542            .saturating_add(T4::min_serialized_size())
543    }
544}
545
546impl<T1, T2, T3, T4, T5> Deserializable for (T1, T2, T3, T4, T5)
547where
548    T1: Deserializable,
549    T2: Deserializable,
550    T3: Deserializable,
551    T4: Deserializable,
552    T5: Deserializable,
553{
554    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
555        let v1 = T1::read_from(source)?;
556        let v2 = T2::read_from(source)?;
557        let v3 = T3::read_from(source)?;
558        let v4 = T4::read_from(source)?;
559        let v5 = T5::read_from(source)?;
560        Ok((v1, v2, v3, v4, v5))
561    }
562
563    fn min_serialized_size() -> usize {
564        T1::min_serialized_size()
565            .saturating_add(T2::min_serialized_size())
566            .saturating_add(T3::min_serialized_size())
567            .saturating_add(T4::min_serialized_size())
568            .saturating_add(T5::min_serialized_size())
569    }
570}
571
572impl<T1, T2, T3, T4, T5, T6> Deserializable for (T1, T2, T3, T4, T5, T6)
573where
574    T1: Deserializable,
575    T2: Deserializable,
576    T3: Deserializable,
577    T4: Deserializable,
578    T5: Deserializable,
579    T6: Deserializable,
580{
581    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
582        let v1 = T1::read_from(source)?;
583        let v2 = T2::read_from(source)?;
584        let v3 = T3::read_from(source)?;
585        let v4 = T4::read_from(source)?;
586        let v5 = T5::read_from(source)?;
587        let v6 = T6::read_from(source)?;
588        Ok((v1, v2, v3, v4, v5, v6))
589    }
590
591    fn min_serialized_size() -> usize {
592        T1::min_serialized_size()
593            .saturating_add(T2::min_serialized_size())
594            .saturating_add(T3::min_serialized_size())
595            .saturating_add(T4::min_serialized_size())
596            .saturating_add(T5::min_serialized_size())
597            .saturating_add(T6::min_serialized_size())
598    }
599}
600
601impl Deserializable for u8 {
602    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
603        source.read_u8()
604    }
605}
606
607impl Deserializable for u16 {
608    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
609        source.read_u16()
610    }
611}
612
613impl Deserializable for u32 {
614    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
615        source.read_u32()
616    }
617}
618
619impl Deserializable for u64 {
620    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
621        source.read_u64()
622    }
623}
624
625impl Deserializable for u128 {
626    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
627        source.read_u128()
628    }
629}
630
631impl Deserializable for usize {
632    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
633        source.read_usize()
634    }
635
636    fn min_serialized_size() -> usize {
637        1 // vint64 encoding: minimum 1 byte for values 0-127
638    }
639}
640
641impl<T: Deserializable> Deserializable for Option<T> {
642    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
643        if source.read_bool()? {
644            Ok(Some(T::read_from(source)?))
645        } else {
646            Ok(None)
647        }
648    }
649
650    /// Returns 1 (just the bool discriminator).
651    ///
652    /// The `Some` variant would be `1 + T::min_serialized_size()`, but we use the minimum
653    /// to allow more elements through the early check.
654    fn min_serialized_size() -> usize {
655        1
656    }
657}
658
659impl<T: Deserializable, const C: usize> Deserializable for [T; C] {
660    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
661        let data: Vec<T> = source.read_many_iter(C)?.collect::<Result<_, _>>()?;
662
663        // The iterator yields exactly C elements (or fails early), so this always succeeds
664        Ok(data.try_into().unwrap_or_else(|v: Vec<T>| {
665            panic!("Expected a Vec of length {} but it was {}", C, v.len())
666        }))
667    }
668
669    fn min_serialized_size() -> usize {
670        C.saturating_mul(T::min_serialized_size())
671    }
672}
673
674impl<T: Deserializable> Deserializable for Vec<T> {
675    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
676        let len = source.read_usize()?;
677        source.read_many_iter(len)?.collect()
678    }
679
680    /// Returns 1 (the minimum vint length prefix size).
681    ///
682    /// The actual serialized size depends on the number of elements, which we don't know
683    /// at the point this is called. Using the minimum allows more elements through the
684    /// early check; budget enforcement during actual reads provides the real protection.
685    fn min_serialized_size() -> usize {
686        1
687    }
688}
689
690impl<K: Deserializable + Ord, V: Deserializable> Deserializable for BTreeMap<K, V> {
691    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
692        let len = source.read_usize()?;
693        source.read_many_iter(len)?.collect()
694    }
695
696    fn min_serialized_size() -> usize {
697        1 // minimum vint length prefix
698    }
699}
700
701impl<T: Deserializable + Ord> Deserializable for BTreeSet<T> {
702    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
703        let len = source.read_usize()?;
704        source.read_many_iter(len)?.collect()
705    }
706
707    fn min_serialized_size() -> usize {
708        1 // minimum vint length prefix
709    }
710}
711
712impl Deserializable for String {
713    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
714        let len = source.read_usize()?;
715        let data: Vec<u8> = source.read_many_iter(len)?.collect::<Result<_, _>>()?;
716
717        String::from_utf8(data).map_err(|err| DeserializationError::InvalidValue(format!("{err}")))
718    }
719
720    fn min_serialized_size() -> usize {
721        1 // minimum vint length prefix
722    }
723}
724
725impl Deserializable for Arc<str> {
726    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
727        String::read_from(source).map(Arc::from)
728    }
729
730    fn min_serialized_size() -> usize {
731        1 // minimum vint length prefix
732    }
733}
734
735// GOLDILOCKS FIELD ELEMENT IMPLEMENTATIONS
736// ================================================================================================
737
738impl Serializable for p3_goldilocks::Goldilocks {
739    fn write_into<W: ByteWriter>(&self, target: &mut W) {
740        use p3_field::PrimeField64;
741        target.write_u64(self.as_canonical_u64());
742    }
743
744    fn get_size_hint(&self) -> usize {
745        size_of::<u64>()
746    }
747}
748
749impl Deserializable for p3_goldilocks::Goldilocks {
750    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
751        use p3_field::integers::QuotientMap;
752
753        let value = source.read_u64()?;
754        Self::from_canonical_checked(value).ok_or_else(|| {
755            DeserializationError::InvalidValue(format!(
756                "value {value} is not a valid Goldilocks field element"
757            ))
758        })
759    }
760}
761
762#[cfg(test)]
763mod tests {
764    use alloc::sync::Arc;
765
766    use super::*;
767
768    #[test]
769    fn arc_str_roundtrip() {
770        let original: Arc<str> = Arc::from("hello world");
771        let bytes = original.to_bytes();
772        let deserialized = Arc::<str>::read_from_bytes(&bytes).unwrap();
773        assert_eq!(original, deserialized);
774    }
775
776    #[test]
777    fn string_roundtrip() {
778        let original = String::from("hello world");
779        let bytes = original.to_bytes();
780        let deserialized = String::read_from_bytes(&bytes).unwrap();
781        assert_eq!(original, deserialized);
782    }
783
784    #[test]
785    fn empty_string_roundtrip() {
786        let arc: Arc<str> = Arc::from("");
787        let bytes = arc.to_bytes();
788        let deserialized = Arc::<str>::read_from_bytes(&bytes).unwrap();
789        assert_eq!(deserialized, Arc::from(""));
790
791        let string = String::from("");
792        let bytes = string.to_bytes();
793        let deserialized = String::read_from_bytes(&bytes).unwrap();
794        assert_eq!(deserialized, "");
795    }
796
797    #[test]
798    fn multibyte_utf8_roundtrip() {
799        let text = "héllo 🌍";
800
801        let arc: Arc<str> = Arc::from(text);
802        let bytes = arc.to_bytes();
803        let deserialized = Arc::<str>::read_from_bytes(&bytes).unwrap();
804        assert_eq!(&*deserialized, text);
805
806        let string = String::from(text);
807        let bytes = string.to_bytes();
808        let deserialized = String::read_from_bytes(&bytes).unwrap();
809        assert_eq!(deserialized, text);
810
811        // Cross-compat: Arc<str> bytes can be read as String and vice versa
812        let arc_bytes = Arc::<str>::from(text).to_bytes();
813        let string_bytes = String::from(text).to_bytes();
814        assert_eq!(arc_bytes, string_bytes);
815        assert_eq!(String::read_from_bytes(&arc_bytes).unwrap(), text);
816        assert_eq!(&*Arc::<str>::read_from_bytes(&string_bytes).unwrap(), text);
817    }
818
819    #[test]
820    fn arc_str_string_cross_compat() {
821        // Arc<str> -> bytes -> String
822        let arc: Arc<str> = Arc::from("cross type");
823        let bytes = arc.to_bytes();
824        let as_string = String::read_from_bytes(&bytes).unwrap();
825        assert_eq!(as_string, "cross type");
826
827        // String -> bytes -> Arc<str>
828        let string = String::from("other direction");
829        let bytes = string.to_bytes();
830        let as_arc = Arc::<str>::read_from_bytes(&bytes).unwrap();
831        assert_eq!(&*as_arc, "other direction");
832    }
833}