Skip to main content

snarkvm_utilities/
bytes.rs

1// Copyright (c) 2019-2026 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use std::{
17    cell::Cell,
18    fmt,
19    io::{Read, Result as IoResult, Write},
20    marker::PhantomData,
21    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
22};
23
24use serde::{
25    Deserializer,
26    Serializer,
27    de::{self, Error, SeqAccess, Visitor},
28    ser::{self, SerializeTuple},
29};
30use smol_str::SmolStr;
31
32thread_local! {
33    static UNCHECKED_DESERIALIZE: Cell<bool> = const { Cell::new(false) };
34}
35
36/// Performs a bincode deserialization without any checks of the data.
37///
38/// Important: This should only be used when deserializing from local storage.
39#[inline(always)]
40pub fn unchecked_deserialize<T: de::DeserializeOwned>(data: &[u8]) -> Result<T, bincode::Error> {
41    UNCHECKED_DESERIALIZE.set(true);
42    let result = bincode::deserialize(data);
43    UNCHECKED_DESERIALIZE.set(false);
44    result
45}
46
47/// Takes as input a sequence of structs, and converts them to a series of little-endian bytes.
48/// All traits that implement `ToBytes` can be automatically converted to bytes in this manner.
49#[macro_export]
50macro_rules! to_bytes_le {
51    ($($x:expr),*) => ({
52        let mut buffer = vec![];
53        buffer.reserve(64);
54        {$crate::push_bytes_to_vec!(buffer, $($x),*)}.map(|_| buffer)
55    });
56}
57
58#[macro_export]
59macro_rules! push_bytes_to_vec {
60    ($buffer:expr, $y:expr, $($x:expr),*) => ({
61        {ToBytes::write_le(&$y, &mut $buffer)}.and({$crate::push_bytes_to_vec!($buffer, $($x),*)})
62    });
63
64    ($buffer:expr, $x:expr) => ({
65        ToBytes::write_le(&$x, &mut $buffer)
66    })
67}
68
69pub trait ToBytes {
70    /// Writes `self` into `writer` as little-endian bytes.
71    fn write_le<W: Write>(&self, writer: W) -> IoResult<()>
72    where
73        Self: Sized;
74
75    /// Returns `self` as a byte array in little-endian order.
76    fn to_bytes_le(&self) -> anyhow::Result<Vec<u8>>
77    where
78        Self: Sized,
79    {
80        Ok(to_bytes_le![self]?)
81    }
82}
83
84pub trait FromBytes {
85    /// Reads `Self` from `reader` as little-endian bytes.
86    fn read_le<R: Read>(reader: R) -> IoResult<Self>
87    where
88        Self: Sized;
89
90    /// Returns `Self` from a byte array in little-endian order.
91    fn from_bytes_le(bytes: &[u8]) -> anyhow::Result<Self>
92    where
93        Self: Sized,
94    {
95        Ok(Self::read_le(bytes)?)
96    }
97
98    /// Same behavior as `Self::from_bytes_le` but avoids costly checks.
99    /// This shall only be called when deserializing from a trusted source, such as local storage.
100    ///
101    /// Returns `Self` from a byte array in little-endian order.
102    fn from_bytes_le_unchecked(bytes: &[u8]) -> anyhow::Result<Self>
103    where
104        Self: Sized,
105    {
106        Ok(Self::read_le_unchecked(bytes)?)
107    }
108
109    /// Same behavior as [`Self::read_le`] but avoids costly checks.
110    /// This shall only be called when deserializing from a trusted source, such as local storage.
111    ///
112    /// The default implementation simply calls [`Self::read_le`].
113    fn read_le_unchecked<R: Read>(reader: R) -> IoResult<Self>
114    where
115        Self: Sized,
116    {
117        Self::read_le(reader)
118    }
119
120    /// Helper function that deserializes either unchecked or checked based on the given boolean flag.
121    fn read_le_with_unchecked<R: Read>(reader: R, unchecked: bool) -> IoResult<Self>
122    where
123        Self: Sized,
124    {
125        if unchecked { Self::read_le_unchecked(reader) } else { Self::read_le(reader) }
126    }
127}
128
129/// Helper struct to serialize an object.
130pub struct ToBytesSerializer<T: ToBytes>(PhantomData<T>);
131
132impl<T: ToBytes> ToBytesSerializer<T> {
133    /// Serializes a static-sized object as a byte array (without length encoding).
134    pub fn serialize<S: Serializer>(object: &T, serializer: S) -> Result<S::Ok, S::Error> {
135        let bytes = object.to_bytes_le().map_err(ser::Error::custom)?;
136        let mut tuple = serializer.serialize_tuple(bytes.len())?;
137        for byte in &bytes {
138            tuple.serialize_element(byte)?;
139        }
140        tuple.end()
141    }
142
143    /// Serializes a dynamically-sized object as a byte array with length encoding.
144    pub fn serialize_with_size_encoding<S: Serializer>(object: &T, serializer: S) -> Result<S::Ok, S::Error> {
145        let bytes = object.to_bytes_le().map_err(ser::Error::custom)?;
146        serializer.serialize_bytes(&bytes)
147    }
148}
149
150pub struct FromBytesDeserializer<T: FromBytes>(PhantomData<T>);
151
152impl<'de, T: FromBytes> FromBytesDeserializer<T> {
153    /// Deserializes a static-sized byte array (without length encoding).
154    ///
155    /// This method fails if `deserializer` is given an insufficient `size`.
156    pub fn deserialize<D: Deserializer<'de>>(deserializer: D, name: &str, size: usize) -> Result<T, D::Error> {
157        let mut buffer = Vec::with_capacity(size);
158        deserializer.deserialize_tuple(size, FromBytesVisitor::new(&mut buffer, name))?;
159        FromBytes::read_le(&*buffer).map_err(de::Error::custom)
160    }
161
162    /// Deserializes a static-sized byte array, with a u8 length encoding at the start.
163    pub fn deserialize_with_u8<D: Deserializer<'de>>(deserializer: D, name: &str) -> Result<T, D::Error> {
164        deserializer.deserialize_tuple(1usize << 8usize, FromBytesWithU8Visitor::<T>::new(name))
165    }
166
167    /// Deserializes a static-sized byte array, with a u16 length encoding at the start.
168    pub fn deserialize_with_u16<D: Deserializer<'de>>(deserializer: D, name: &str) -> Result<T, D::Error> {
169        deserializer.deserialize_tuple(1usize << 16usize, FromBytesWithU16Visitor::<T>::new(name))
170    }
171
172    /// Deserializes a dynamically-sized byte array.
173    pub fn deserialize_with_size_encoding<D: Deserializer<'de>>(deserializer: D, name: &str) -> Result<T, D::Error> {
174        deserializer.deserialize_bytes(FromBytesValueVisitor::new(name, false))
175    }
176
177    /// Attempts to deserialize a byte array (without length encoding).
178    ///
179    /// This method does *not* fail if `deserializer` is given an insufficient `size`,
180    /// however this method fails if `FromBytes` fails to read the value of `T`.
181    pub fn deserialize_extended<D: Deserializer<'de>>(
182        deserializer: D,
183        name: &str,
184        size_a: usize,
185        size_b: usize,
186    ) -> Result<T, D::Error> {
187        // Order the given sizes from smallest to largest.
188        let (size_a, size_b) = match size_a < size_b {
189            true => (size_a, size_b),
190            false => (size_b, size_a),
191        };
192
193        // Ensure 'size_b' is within bounds.
194        if size_b > i32::MAX as usize {
195            return Err(D::Error::custom(format!("size_b ({size_b}) exceeds maximum")));
196        }
197
198        // Reserve a new `Vec` with the larger size capacity.
199        let mut buffer = Vec::with_capacity(size_b);
200
201        // Attempt to deserialize on the larger size, to load up to the maximum buffer size.
202        match deserializer.deserialize_tuple(size_b, FromBytesVisitor::new(&mut buffer, name)) {
203            // Deserialized a full buffer, attempt to read up to `size_b`.
204            Ok(()) => FromBytes::read_le(&buffer[..size_b]).map_err(de::Error::custom),
205            // Deserialized a partial buffer, attempt to read up to `size_a`, if exactly `size_a` was read.
206            Err(error) => match buffer.len() == size_a {
207                true => FromBytes::read_le(&buffer[..size_a]).map_err(de::Error::custom),
208                false => Err(error),
209            },
210        }
211    }
212}
213
214pub struct FromBytesUncheckedDeserializer<T: FromBytes>(PhantomData<T>);
215
216impl<'de, T: FromBytes> FromBytesUncheckedDeserializer<T> {
217    /// Deserializes a dynamically-sized byte array.
218    pub fn deserialize_with_size_encoding<D: Deserializer<'de>>(deserializer: D, name: &str) -> Result<T, D::Error> {
219        deserializer.deserialize_bytes(FromBytesValueVisitor::new(name, UNCHECKED_DESERIALIZE.get()))
220    }
221}
222
223struct FromBytesValueVisitor<T: FromBytes>(SmolStr, bool, PhantomData<T>);
224
225impl<T: FromBytes> FromBytesValueVisitor<T> {
226    fn new(name: &str, unchecked: bool) -> Self {
227        Self(SmolStr::new(name), unchecked, PhantomData)
228    }
229
230    fn read<E: de::Error>(&self, bytes: &[u8]) -> Result<T, E> {
231        FromBytes::read_le_with_unchecked(bytes, self.1).map_err(de::Error::custom)
232    }
233}
234
235impl<'de, T: FromBytes> Visitor<'de> for FromBytesValueVisitor<T> {
236    type Value = T;
237
238    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
239        formatter.write_fmt(format_args!("a valid {} ", self.0))
240    }
241
242    fn visit_borrowed_bytes<E: de::Error>(self, bytes: &'de [u8]) -> Result<Self::Value, E> {
243        self.read(bytes)
244    }
245
246    fn visit_bytes<E: de::Error>(self, bytes: &[u8]) -> Result<Self::Value, E> {
247        self.read(bytes)
248    }
249
250    fn visit_byte_buf<E: de::Error>(self, bytes: Vec<u8>) -> Result<Self::Value, E> {
251        self.read(&bytes)
252    }
253
254    fn visit_seq<S: SeqAccess<'de>>(self, mut seq: S) -> Result<Self::Value, S::Error> {
255        let mut bytes = Vec::with_capacity(32);
256        while let Some(byte) = seq.next_element()? {
257            bytes.push(byte);
258        }
259        self.read(&bytes)
260    }
261}
262
263pub struct FromBytesVisitor<'a>(&'a mut Vec<u8>, SmolStr);
264
265impl<'a> FromBytesVisitor<'a> {
266    /// Initializes a new `FromBytesVisitor` with the given `buffer` and `name`.
267    pub fn new(buffer: &'a mut Vec<u8>, name: &str) -> Self {
268        Self(buffer, SmolStr::new(name))
269    }
270}
271
272impl<'de> Visitor<'de> for FromBytesVisitor<'_> {
273    type Value = ();
274
275    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
276        formatter.write_str(&format!("a valid {} ", self.1))
277    }
278
279    fn visit_borrowed_bytes<E: serde::de::Error>(self, bytes: &'de [u8]) -> Result<Self::Value, E> {
280        self.0.extend_from_slice(bytes);
281        Ok(())
282    }
283
284    fn visit_seq<S: SeqAccess<'de>>(self, mut seq: S) -> Result<Self::Value, S::Error> {
285        while let Some(byte) = seq.next_element()? {
286            self.0.push(byte);
287        }
288        Ok(())
289    }
290}
291
292struct FromBytesWithU8Visitor<T: FromBytes>(String, PhantomData<T>);
293
294impl<T: FromBytes> FromBytesWithU8Visitor<T> {
295    /// Initializes a new `FromBytesWithU8Visitor` with the given `name`.
296    pub fn new(name: &str) -> Self {
297        Self(name.to_string(), PhantomData)
298    }
299}
300
301impl<'de, T: FromBytes> Visitor<'de> for FromBytesWithU8Visitor<T> {
302    type Value = T;
303
304    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
305        formatter.write_str(&format!("a valid {} ", self.0))
306    }
307
308    fn visit_seq<V: SeqAccess<'de>>(self, mut seq: V) -> Result<Self::Value, V::Error> {
309        // Read the size of the object.
310        let length: u8 = seq.next_element()?.ok_or_else(|| Error::invalid_length(0, &self))?;
311
312        // Initialize the vector with the correct length.
313        let mut bytes: Vec<u8> = Vec::with_capacity((length as usize) + 1);
314        // Push the length into the vector.
315        bytes.push(length);
316        // Read the bytes.
317        for i in 0..length {
318            // Push the next byte into the vector.
319            bytes.push(seq.next_element()?.ok_or_else(|| Error::invalid_length((i as usize) + 1, &self))?);
320        }
321        // Deserialize the vector.
322        FromBytes::read_le(&*bytes).map_err(de::Error::custom)
323    }
324}
325
326struct FromBytesWithU16Visitor<T: FromBytes>(String, PhantomData<T>);
327
328impl<T: FromBytes> FromBytesWithU16Visitor<T> {
329    /// Initializes a new `FromBytesWithU16Visitor` with the given `name`.
330    pub fn new(name: &str) -> Self {
331        Self(name.to_string(), PhantomData)
332    }
333}
334
335impl<'de, T: FromBytes> Visitor<'de> for FromBytesWithU16Visitor<T> {
336    type Value = T;
337
338    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
339        formatter.write_str(&format!("a valid {} ", self.0))
340    }
341
342    fn visit_seq<V: SeqAccess<'de>>(self, mut seq: V) -> Result<Self::Value, V::Error> {
343        // Read the size of the object.
344        let length: u16 = seq.next_element()?.ok_or_else(|| Error::invalid_length(0, &self))?;
345
346        // Initialize the vector with the correct length.
347        let mut bytes: Vec<u8> = Vec::with_capacity((length as usize) + 2);
348        // Push the length into the vector.
349        bytes.extend(length.to_le_bytes());
350        // Read the bytes.
351        for i in 0..length {
352            // Push the next byte into the vector.
353            bytes.push(seq.next_element()?.ok_or_else(|| Error::invalid_length((i as usize) + 2, &self))?);
354        }
355        // Deserialize the vector.
356        FromBytes::read_le(&*bytes).map_err(de::Error::custom)
357    }
358}
359
360impl ToBytes for () {
361    #[inline]
362    fn write_le<W: Write>(&self, _writer: W) -> IoResult<()> {
363        Ok(())
364    }
365}
366
367impl FromBytes for () {
368    #[inline]
369    fn read_le<R: Read>(_bytes: R) -> IoResult<Self> {
370        Ok(())
371    }
372}
373
374impl ToBytes for bool {
375    #[inline]
376    fn write_le<W: Write>(&self, writer: W) -> IoResult<()> {
377        u8::write_le(&(*self as u8), writer)
378    }
379}
380
381impl FromBytes for bool {
382    #[inline]
383    fn read_le<R: Read>(reader: R) -> IoResult<Self> {
384        match u8::read_le(reader) {
385            Ok(0) => Ok(false),
386            Ok(1) => Ok(true),
387            Ok(_) => Err(std::io::Error::other("FromBytes::read failed")),
388            Err(err) => Err(err),
389        }
390    }
391}
392
393impl ToBytes for SocketAddr {
394    #[inline]
395    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
396        // Write the IP address.
397        match self.ip() {
398            IpAddr::V4(ipv4) => {
399                0u8.write_le(&mut writer)?;
400                u32::from(ipv4).write_le(&mut writer)?;
401            }
402            IpAddr::V6(ipv6) => {
403                1u8.write_le(&mut writer)?;
404                u128::from(ipv6).write_le(&mut writer)?;
405            }
406        }
407        // Write the port.
408        self.port().write_le(&mut writer)?;
409        Ok(())
410    }
411}
412
413impl FromBytes for SocketAddr {
414    #[inline]
415    fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
416        // Read the IP address.
417        let ip = match u8::read_le(&mut reader)? {
418            0 => IpAddr::V4(Ipv4Addr::from(u32::read_le(&mut reader)?)),
419            1 => IpAddr::V6(Ipv6Addr::from(u128::read_le(&mut reader)?)),
420            _ => return Err(std::io::Error::other("Invalid IP address")),
421        };
422        // Read the port.
423        let port = u16::read_le(&mut reader)?;
424        Ok(SocketAddr::new(ip, port))
425    }
426}
427
428macro_rules! impl_bytes_for_integer {
429    ($int:ty) => {
430        impl ToBytes for $int {
431            #[inline]
432            fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
433                writer.write_all(&self.to_le_bytes())
434            }
435        }
436
437        impl FromBytes for $int {
438            #[inline]
439            fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
440                let mut bytes = [0u8; core::mem::size_of::<$int>()];
441                reader.read_exact(&mut bytes)?;
442                Ok(<$int>::from_le_bytes(bytes))
443            }
444        }
445    };
446}
447
448impl_bytes_for_integer!(u8);
449impl_bytes_for_integer!(u16);
450impl_bytes_for_integer!(u32);
451impl_bytes_for_integer!(u64);
452impl_bytes_for_integer!(u128);
453
454impl_bytes_for_integer!(i8);
455impl_bytes_for_integer!(i16);
456impl_bytes_for_integer!(i32);
457impl_bytes_for_integer!(i64);
458impl_bytes_for_integer!(i128);
459
460impl<const N: usize> ToBytes for [u8; N] {
461    #[inline]
462    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
463        writer.write_all(self)
464    }
465}
466
467impl<const N: usize> FromBytes for [u8; N] {
468    #[inline]
469    fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
470        let mut arr = [0u8; N];
471        reader.read_exact(&mut arr)?;
472        Ok(arr)
473    }
474}
475
476macro_rules! impl_bytes_for_integer_array {
477    ($int:ty) => {
478        impl<const N: usize> ToBytes for [$int; N] {
479            #[inline]
480            fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
481                for num in self {
482                    writer.write_all(&num.to_le_bytes())?;
483                }
484                Ok(())
485            }
486        }
487
488        impl<const N: usize> FromBytes for [$int; N] {
489            #[inline]
490            fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
491                let mut res: [$int; N] = [0; N];
492                for num in res.iter_mut() {
493                    let mut bytes = [0u8; core::mem::size_of::<$int>()];
494                    reader.read_exact(&mut bytes)?;
495                    *num = <$int>::from_le_bytes(bytes);
496                }
497                Ok(res)
498            }
499        }
500    };
501}
502
503// u8 has a dedicated, faster implementation above
504impl_bytes_for_integer_array!(u16);
505impl_bytes_for_integer_array!(u32);
506impl_bytes_for_integer_array!(u64);
507
508impl<L: ToBytes, R: ToBytes> ToBytes for (L, R) {
509    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
510        self.0.write_le(&mut writer)?;
511        self.1.write_le(&mut writer)?;
512        Ok(())
513    }
514}
515
516impl<L: FromBytes, R: FromBytes> FromBytes for (L, R) {
517    #[inline]
518    fn read_le<Reader: Read>(mut reader: Reader) -> IoResult<Self> {
519        let left: L = FromBytes::read_le(&mut reader)?;
520        let right: R = FromBytes::read_le(&mut reader)?;
521        Ok((left, right))
522    }
523}
524
525impl<T: ToBytes> ToBytes for Vec<T> {
526    #[inline]
527    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
528        for item in self {
529            item.write_le(&mut writer)?;
530        }
531        Ok(())
532    }
533}
534
535impl<'a, T: 'a + ToBytes> ToBytes for &'a [T] {
536    #[inline]
537    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
538        for item in *self {
539            item.write_le(&mut writer)?;
540        }
541        Ok(())
542    }
543}
544
545impl<'a, T: 'a + ToBytes> ToBytes for &'a T {
546    #[inline]
547    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
548        (*self).write_le(&mut writer)
549    }
550}
551
552#[inline]
553pub fn bits_from_bytes_le(bytes: &[u8]) -> impl DoubleEndedIterator<Item = bool> + '_ {
554    bytes.iter().flat_map(|byte| (0..8).map(move |i| (*byte >> i) & 1 == 1))
555}
556
557#[inline]
558pub fn bytes_from_bits_le(bits: &[bool]) -> Vec<u8> {
559    let desired_size = if bits.len().is_multiple_of(8) { bits.len() / 8 } else { bits.len() / 8 + 1 };
560
561    let mut bytes = Vec::with_capacity(desired_size);
562    for bits in bits.chunks(8) {
563        let mut result = 0u8;
564        for (i, bit) in bits.iter().enumerate() {
565            let bit_value = *bit as u8;
566            result += bit_value << i as u8;
567        }
568
569        bytes.push(result);
570    }
571
572    bytes
573}
574
575/// A wrapper around a `Write` instance that limits the number of bytes that can be written.
576pub struct LimitedWriter<W: Write> {
577    writer: W,
578    limit: usize,
579    remaining: usize,
580}
581
582impl<W: Write> LimitedWriter<W> {
583    pub fn new(writer: W, limit: usize) -> Self {
584        Self { writer, limit, remaining: limit }
585    }
586}
587
588impl<W: Write> Write for LimitedWriter<W> {
589    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
590        if self.remaining == 0 && !buf.is_empty() {
591            return Err(std::io::Error::other(format!("Byte limit exceeded: {}", self.limit)));
592        }
593
594        let max_write = std::cmp::min(buf.len(), self.remaining);
595        match self.writer.write(&buf[..max_write]) {
596            Ok(n) => {
597                self.remaining -= n;
598                Ok(n)
599            }
600            Err(e) => Err(e),
601        }
602    }
603
604    fn flush(&mut self) -> IoResult<()> {
605        self.writer.flush()
606    }
607}
608
609#[cfg(test)]
610mod test {
611    use super::*;
612    use crate::TestRng;
613
614    use rand::RngExt;
615    use serde::{Deserialize, Serialize};
616
617    const ITERATIONS: usize = 1000;
618
619    #[derive(Debug, Deserialize, PartialEq)]
620    struct DeserializedBytes(#[serde(deserialize_with = "deserialize_bytes")] [u8; 4]);
621
622    #[derive(Serialize)]
623    struct SerializedBytes<'a>(#[serde(serialize_with = "serialize_bytes")] &'a [u8]);
624
625    #[derive(Debug, PartialEq)]
626    struct UncheckedBytes([u8; 4]);
627
628    impl FromBytes for UncheckedBytes {
629        fn read_le<R: Read>(_reader: R) -> IoResult<Self> {
630            Err(std::io::Error::other("checked deserialization"))
631        }
632
633        fn read_le_unchecked<R: Read>(reader: R) -> IoResult<Self> {
634            Ok(Self(FromBytes::read_le(reader)?))
635        }
636    }
637
638    #[derive(Debug, Deserialize, PartialEq)]
639    struct UncheckedDeserializedBytes(#[serde(deserialize_with = "deserialize_unchecked_bytes")] UncheckedBytes);
640
641    fn deserialize_bytes<'de, D: Deserializer<'de>>(deserializer: D) -> Result<[u8; 4], D::Error> {
642        FromBytesDeserializer::deserialize_with_size_encoding(deserializer, "bytes")
643    }
644
645    fn serialize_bytes<S: Serializer>(bytes: &&[u8], serializer: S) -> Result<S::Ok, S::Error> {
646        serializer.serialize_bytes(bytes)
647    }
648
649    fn deserialize_unchecked_bytes<'de, D: Deserializer<'de>>(deserializer: D) -> Result<UncheckedBytes, D::Error> {
650        FromBytesUncheckedDeserializer::deserialize_with_size_encoding(deserializer, "bytes")
651    }
652
653    #[test]
654    fn test_deserialize_with_size_encoding() -> anyhow::Result<()> {
655        let expected = [1, 2, 3, 4];
656
657        let bincode = bincode::serialize(&SerializedBytes(&expected))?;
658        assert_eq!(bincode::deserialize::<DeserializedBytes>(&bincode)?, DeserializedBytes(expected));
659
660        let json = serde_json::to_string(&SerializedBytes(&expected))?;
661        assert_eq!(serde_json::from_str::<DeserializedBytes>(&json)?, DeserializedBytes(expected));
662
663        Ok(())
664    }
665
666    #[test]
667    fn test_deserialize_with_size_encoding_unchecked() -> anyhow::Result<()> {
668        let expected = [1, 2, 3, 4];
669        let bincode = bincode::serialize(&SerializedBytes(&expected))?;
670
671        assert!(bincode::deserialize::<UncheckedDeserializedBytes>(&bincode).is_err());
672        assert_eq!(
673            unchecked_deserialize::<UncheckedDeserializedBytes>(&bincode)?,
674            UncheckedDeserializedBytes(UncheckedBytes(expected))
675        );
676
677        Ok(())
678    }
679
680    #[test]
681    fn test_macro_empty() {
682        let array: Vec<u8> = vec![];
683        let bytes_a: Vec<u8> = to_bytes_le![array].unwrap();
684        assert_eq!(&array, &bytes_a);
685        assert_eq!(0, bytes_a.len());
686
687        let bytes_b: Vec<u8> = array.to_bytes_le().unwrap();
688        assert_eq!(&array, &bytes_b);
689        assert_eq!(0, bytes_b.len());
690    }
691
692    #[test]
693    fn test_macro() {
694        let array1 = [1u8; 32];
695        let array2 = [2u8; 16];
696        let array3 = [3u8; 8];
697        let bytes = to_bytes_le![array1, array2, array3].unwrap();
698        assert_eq!(bytes.len(), 56);
699
700        let mut actual_bytes = Vec::new();
701        actual_bytes.extend_from_slice(&array1);
702        actual_bytes.extend_from_slice(&array2);
703        actual_bytes.extend_from_slice(&array3);
704        assert_eq!(bytes, actual_bytes);
705    }
706
707    #[test]
708    fn test_bits_from_bytes_le() {
709        assert_eq!(bits_from_bytes_le(&[204, 76]).collect::<Vec<bool>>(), [
710            false, false, true, true, false, false, true, true, // 204
711            false, false, true, true, false, false, true, false, // 76
712        ]);
713    }
714
715    #[test]
716    fn test_bytes_from_bits_le() {
717        let bits = [
718            false, false, true, true, false, false, true, true, // 204
719            false, false, true, true, false, false, true, false, // 76
720        ];
721        assert_eq!(bytes_from_bits_le(&bits), [204, 76]);
722    }
723
724    #[test]
725    fn test_from_bits_le_to_bytes_le_roundtrip() {
726        let mut rng = TestRng::default();
727
728        for _ in 0..ITERATIONS {
729            let given_bytes: [u8; 32] = rng.random();
730
731            let bits = bits_from_bytes_le(&given_bytes).collect::<Vec<_>>();
732            let recovered_bytes = bytes_from_bits_le(&bits);
733
734            assert_eq!(given_bytes.to_vec(), recovered_bytes);
735        }
736    }
737
738    #[test]
739    fn test_socketaddr_bytes() {
740        fn random_ipv4_address(rng: &mut TestRng) -> Ipv4Addr {
741            Ipv4Addr::new(rng.random(), rng.random(), rng.random(), rng.random())
742        }
743
744        fn random_ipv6_address(rng: &mut TestRng) -> Ipv6Addr {
745            Ipv6Addr::new(
746                rng.random(),
747                rng.random(),
748                rng.random(),
749                rng.random(),
750                rng.random(),
751                rng.random(),
752                rng.random(),
753                rng.random(),
754            )
755        }
756
757        fn random_port(rng: &mut TestRng) -> u16 {
758            rng.random_range(1025..=65535) // excluding well-known ports
759        }
760
761        let rng = &mut TestRng::default();
762
763        for _ in 0..1_000_000 {
764            let ipv4 = SocketAddr::new(IpAddr::V4(random_ipv4_address(rng)), random_port(rng));
765            let bytes = ipv4.to_bytes_le().unwrap();
766            let ipv4_2 = SocketAddr::read_le(&bytes[..]).unwrap();
767            assert_eq!(ipv4, ipv4_2);
768
769            let ipv6 = SocketAddr::new(IpAddr::V6(random_ipv6_address(rng)), random_port(rng));
770            let bytes = ipv6.to_bytes_le().unwrap();
771            let ipv6_2 = SocketAddr::read_le(&bytes[..]).unwrap();
772            assert_eq!(ipv6, ipv6_2);
773        }
774    }
775}