zenoh_ext/
serialization.rs

1//
2// Copyright (c) 2024 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14use std::{
15    borrow::Cow,
16    collections::{BTreeMap, BTreeSet, HashMap, HashSet},
17    fmt,
18    hash::Hash,
19    io::{Read, Write},
20    marker::PhantomData,
21    mem::MaybeUninit,
22};
23
24use zenoh::bytes::{ZBytes, ZBytesReader, ZBytesWriter};
25
26/// Error occurring in deserialization.
27#[derive(Debug)]
28pub struct ZDeserializeError;
29impl fmt::Display for ZDeserializeError {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        write!(f, "deserialization error")
32    }
33}
34impl std::error::Error for ZDeserializeError {}
35
36fn default_serialize_n<T: Serialize>(slice: &[T], serializer: &mut ZSerializer) {
37    for t in slice {
38        t.serialize(serializer)
39    }
40}
41
42/// Serialization implementation.
43///
44/// See [Zenoh serialization format RFC][1].
45///
46/// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md
47pub trait Serialize {
48    /// Serialize the given object into a [`ZSerializer`].
49    ///
50    /// User may prefer to use [`ZSerializer::serialize`] instead of this function.
51    fn serialize(&self, serializer: &mut ZSerializer);
52    #[doc(hidden)]
53    fn serialize_n(slice: &[Self], serializer: &mut ZSerializer)
54    where
55        Self: Sized,
56    {
57        default_serialize_n(slice, serializer);
58    }
59}
60impl<T: Serialize + ?Sized> Serialize for &T {
61    fn serialize(&self, serializer: &mut ZSerializer) {
62        T::serialize(*self, serializer)
63    }
64}
65
66fn default_deserialize_n<T: Deserialize>(
67    in_place: &mut [T],
68    deserializer: &mut ZDeserializer,
69) -> Result<(), ZDeserializeError> {
70    for t in in_place {
71        *t = T::deserialize(deserializer)?;
72    }
73    Ok(())
74}
75
76fn default_deserialize_n_uninit<'a, T: Deserialize>(
77    in_place: &'a mut [MaybeUninit<T>],
78    deserializer: &mut ZDeserializer,
79) -> Result<&'a mut [T], ZDeserializeError> {
80    for t in in_place.iter_mut() {
81        t.write(T::deserialize(deserializer)?);
82    }
83    // SAFETY: all members of the slices have been initialized
84    Ok(unsafe { &mut *(in_place as *mut [MaybeUninit<T>] as *mut [T]) })
85}
86
87/// Deserialization implementation.
88///
89/// See [Zenoh serialization format RFC][1].
90///
91/// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md
92pub trait Deserialize: Sized {
93    /// Deserialize the given type from a [`ZDeserializer`].
94    ///
95    /// User may prefer to use [`ZDeserializer::deserialize`] instead of this function.
96    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError>;
97    #[doc(hidden)]
98    fn deserialize_n(
99        in_place: &mut [Self],
100        deserializer: &mut ZDeserializer,
101    ) -> Result<(), ZDeserializeError> {
102        default_deserialize_n(in_place, deserializer)
103    }
104    #[doc(hidden)]
105    fn deserialize_n_uninit<'a>(
106        in_place: &'a mut [MaybeUninit<Self>],
107        deserializer: &mut ZDeserializer,
108    ) -> Result<&'a mut [Self], ZDeserializeError> {
109        default_deserialize_n_uninit(in_place, deserializer)
110    }
111}
112
113/// Serialize an object according to the [Zenoh serialization format][1].
114///
115/// Serialization doesn't take the ownership of the data.
116///
117/// This function takes any type implementing the [`Serialize`] trait and
118/// creates [`ZBytes`] containing the serialized data.
119/// This trait is implemented for all the primitive types (integers, floats, bool) and
120/// standard collections (arrays, slices, `Vec`, `String`, `HashMap`, `HashSet`, etc)
121/// and could be implemented for user-defined types.
122///
123/// # Examples
124///
125/// ```rust
126/// use zenoh_ext::*;
127/// let zbytes = z_serialize(&(42i32, vec![1u8, 2, 3]));
128/// assert_eq!(z_deserialize::<(i32, Vec<u8>)>(&zbytes).unwrap(), (42i32, vec![1u8, 2, 3]));
129/// ```
130///
131/// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md
132pub fn z_serialize<T: Serialize + ?Sized>(t: &T) -> ZBytes {
133    let mut serializer = ZSerializer::new();
134    serializer.serialize(t);
135    serializer.finish()
136}
137
138/// Deserialize an object according to the [Zenoh serialization format][1].
139///
140/// The destination type is given as a type parameter. If the data cannot be
141/// deserialized into the given type, an error is returned.
142///
143/// # Examples
144///
145/// ```rust
146/// use zenoh_ext::*;
147/// let zbytes = z_serialize(&(42i32, vec![1u8, 2, 3]));
148/// assert_eq!(z_deserialize::<(i32, Vec<u8>)>(&zbytes).unwrap(), (42i32, vec![1u8, 2, 3]));
149/// ```
150///
151/// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md
152pub fn z_deserialize<T: Deserialize>(zbytes: &ZBytes) -> Result<T, ZDeserializeError> {
153    let mut deserializer = ZDeserializer::new(zbytes);
154    let t = T::deserialize(&mut deserializer)?;
155    if !deserializer.done() {
156        return Err(ZDeserializeError);
157    }
158    Ok(t)
159}
160
161/// Serializer implementing the [Zenoh serialization format][1].
162///
163/// Serializing objects one after the other is equivalent to serialize a tuple of these objects.
164///
165/// # Examples
166///
167/// ```rust
168/// use zenoh_ext::*;
169/// let mut serializer = ZSerializer::new();
170/// serializer.serialize(42i32);
171/// serializer.serialize(vec![1u8, 2, 3]);
172/// let zbytes = serializer.finish();
173/// assert_eq!(z_deserialize::<(i32, Vec<u8>)>(&zbytes).unwrap(), (42i32, vec![1u8, 2, 3]));
174/// ```
175///
176/// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md
177#[derive(Debug)]
178pub struct ZSerializer(ZBytesWriter);
179
180impl ZSerializer {
181    /// Instantiate a [`ZSerializer`].
182    pub fn new() -> Self {
183        Self(ZBytes::writer())
184    }
185
186    /// Serialize the given object into a [`ZSerializer`].
187    ///
188    /// Serialization doesn't take the ownership of the data.
189    pub fn serialize<T: Serialize>(&mut self, t: T) {
190        t.serialize(self)
191    }
192
193    /// Serialize the given iterator into a [`ZSerializer`].
194    ///
195    /// Sequence serialized with this method may be deserialized with [`ZDeserializer::deserialize_iter`].
196    /// See [Zenoh serialization format RFC][1].
197    ///
198    /// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md#sequences
199    pub fn serialize_iter<T: Serialize, I: IntoIterator<Item = T>>(&mut self, iter: I)
200    where
201        I::IntoIter: ExactSizeIterator,
202    {
203        let iter = iter.into_iter();
204        self.serialize(VarInt(iter.len()));
205        for t in iter {
206            t.serialize(self);
207        }
208    }
209
210    /// Finish serialization by returning a [`ZBytes`].
211    pub fn finish(self) -> ZBytes {
212        self.0.finish()
213    }
214}
215
216impl Default for ZSerializer {
217    fn default() -> Self {
218        Self::new()
219    }
220}
221
222impl From<ZSerializer> for ZBytes {
223    fn from(value: ZSerializer) -> Self {
224        value.finish()
225    }
226}
227
228/// Deserializer implementing the [Zenoh serialization format][1].
229///
230/// Deserializing objects one after the other is equivalent to serialize a tuple of these objects.
231///
232/// # Examples
233///
234/// ```rust
235/// use zenoh_ext::*;
236/// let zbytes = z_serialize(&(42i32, vec![1u8, 2, 3]));
237/// let mut deserializer = ZDeserializer::new(&zbytes);
238/// assert_eq!(deserializer.deserialize::<i32>().unwrap(), 42i32);
239/// assert_eq!(deserializer.deserialize::<Vec<u8>>().unwrap(), vec![1u8, 2, 3]);
240/// assert!(deserializer.done())
241/// ```
242///
243/// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md
244#[derive(Debug)]
245pub struct ZDeserializer<'a>(ZBytesReader<'a>);
246
247impl<'a> ZDeserializer<'a> {
248    /// Instantiate a [`ZDeserializer`] from a [`ZBytes`].
249    pub fn new(zbytes: &'a ZBytes) -> Self {
250        Self(zbytes.reader())
251    }
252
253    /// Return true if there is no data left to deserialize.
254    pub fn done(&self) -> bool {
255        self.0.is_empty()
256    }
257
258    /// Deserialize the given type from a [`ZDeserializer`].
259    pub fn deserialize<T: Deserialize>(&mut self) -> Result<T, ZDeserializeError> {
260        T::deserialize(self)
261    }
262
263    /// Deserialize an iterator into a [`ZDeserializer`].
264    ///
265    /// Sequence deserialized with this method may have been serialized with [`ZSerializer::serialize_iter`].
266    /// See [Zenoh serialization format RFC][1].
267    ///
268    /// [1]: https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Serialization.md#sequences
269    pub fn deserialize_iter<'b, T: Deserialize>(
270        &'b mut self,
271    ) -> Result<ZReadIter<'a, 'b, T>, ZDeserializeError> {
272        let len = <VarInt<usize>>::deserialize(self)?.0;
273        Ok(ZReadIter {
274            deserializer: self,
275            len,
276            _phantom: PhantomData,
277        })
278    }
279}
280
281/// Iterator returned by [`ZDeserializer::deserialize_iter`].
282pub struct ZReadIter<'a, 'b, T: Deserialize> {
283    deserializer: &'b mut ZDeserializer<'a>,
284    len: usize,
285    _phantom: PhantomData<T>,
286}
287
288impl<T: Deserialize> Iterator for ZReadIter<'_, '_, T> {
289    type Item = Result<T, ZDeserializeError>;
290    fn next(&mut self) -> Option<Self::Item> {
291        if self.len == 0 {
292            return None;
293        }
294        self.len -= 1;
295        Some(T::deserialize(self.deserializer))
296    }
297
298    fn size_hint(&self) -> (usize, Option<usize>) {
299        (self.len, Some(self.len))
300    }
301}
302
303impl<T: Deserialize> ExactSizeIterator for ZReadIter<'_, '_, T> {}
304
305impl<T: Deserialize> Drop for ZReadIter<'_, '_, T> {
306    fn drop(&mut self) {
307        self.by_ref().for_each(drop);
308    }
309}
310
311impl Serialize for ZBytes {
312    fn serialize(&self, serializer: &mut ZSerializer) {
313        serializer.serialize(VarInt(self.len()));
314        serializer.0.append(self.clone());
315    }
316}
317
318macro_rules! impl_num {
319    ($($ty:ty),* $(,)?) => {$(
320        impl Serialize for $ty {
321            fn serialize(&self, serializer: &mut ZSerializer) {
322                serializer.0.write_all(&(*self).to_le_bytes()).unwrap();
323            }
324            fn serialize_n(slice: &[Self], serializer: &mut ZSerializer) where Self: Sized {
325                if cfg!(target_endian = "little") || std::mem::size_of::<Self>() == 1 {
326                    // SAFETY: transmuting numeric types to their little endian bytes is safe
327                    serializer.0.write_all(unsafe { slice.align_to().1 }).unwrap();
328                } else {
329                    default_serialize_n(slice, serializer)
330                }
331            }
332        }
333        impl Deserialize for $ty {
334            fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
335                let mut buf = [0; { std::mem::size_of::<Self>() }];
336                deserializer.0.read_exact(&mut buf).or(Err(ZDeserializeError))?;
337                Ok(<$ty>::from_le_bytes(buf))
338            }
339            fn deserialize_n(in_place: &mut [Self], deserializer: &mut ZDeserializer) -> Result<(), ZDeserializeError> {
340                let size = std::mem::size_of::<Self>();
341                if cfg!(target_endian = "little") || size == 1 {
342                    // SAFETY: transmuting numeric types to their little endian bytes is safe
343                    let buf = unsafe {in_place.align_to_mut().1};
344                    deserializer.0.read_exact(buf).or(Err(ZDeserializeError))?;
345                    Ok(())
346                } else {
347                    default_deserialize_n(in_place, deserializer)
348                }
349            }
350            fn deserialize_n_uninit<'a>(in_place: &'a mut [MaybeUninit<Self>], deserializer: &mut ZDeserializer) -> Result<&'a mut [Self], ZDeserializeError> {
351                if cfg!(target_endian = "little") ||  std::mem::size_of::<Self>() == 1 {
352                    // need to initialize the slice because of std::io::Read interface
353                    in_place.fill(MaybeUninit::new(Self::default()));
354                    // SAFETY: all members of the slices have been initialized
355                    let initialized = unsafe { &mut *(in_place as *mut [MaybeUninit<Self>] as *mut [Self]) };
356                    Self::deserialize_n(initialized, deserializer)?;
357                    Ok(initialized)
358                } else {
359                    default_deserialize_n_uninit(in_place, deserializer)
360                }
361            }
362        }
363    )*};
364}
365impl_num!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64);
366
367impl Serialize for bool {
368    fn serialize(&self, serializer: &mut ZSerializer) {
369        (*self as u8).serialize(serializer);
370    }
371}
372impl Deserialize for bool {
373    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
374        match u8::deserialize(deserializer)? {
375            0 => Ok(false),
376            1 => Ok(true),
377            _ => Err(ZDeserializeError),
378        }
379    }
380}
381
382fn serialize_slice<T: Serialize>(slice: &[T], serializer: &mut ZSerializer) {
383    serializer.serialize(VarInt(slice.len()));
384    T::serialize_n(slice, serializer);
385}
386
387fn deserialize_slice<T: Deserialize>(
388    deserializer: &mut ZDeserializer,
389) -> Result<Box<[T]>, ZDeserializeError> {
390    let len = <VarInt<usize>>::deserialize(deserializer)?.0;
391    let mut vec = Vec::with_capacity(len);
392    let slice = T::deserialize_n_uninit(&mut vec.spare_capacity_mut()[..len], deserializer)?;
393    let (slice_ptr, slice_len) = (slice.as_ptr(), slice.len());
394    assert_eq!((slice_ptr, slice_len), (vec.as_ptr(), len));
395    // SAFETY: assertion checks the returned slice is vector's one, and it's returned initialized
396    unsafe { vec.set_len(len) };
397    Ok(vec.into_boxed_slice())
398}
399
400impl<T: Serialize> Serialize for [T] {
401    fn serialize(&self, serializer: &mut ZSerializer) {
402        serialize_slice(self, serializer);
403    }
404}
405impl<T: Serialize, const N: usize> Serialize for [T; N] {
406    fn serialize(&self, serializer: &mut ZSerializer) {
407        serialize_slice(self.as_slice(), serializer);
408    }
409}
410impl<'a, T: Serialize + 'a> Serialize for Cow<'a, [T]>
411where
412    [T]: ToOwned,
413{
414    fn serialize(&self, serializer: &mut ZSerializer) {
415        serialize_slice(self, serializer);
416    }
417}
418impl<T: Serialize> Serialize for Box<[T]> {
419    fn serialize(&self, serializer: &mut ZSerializer) {
420        serialize_slice(self, serializer);
421    }
422}
423impl<T: Deserialize> Deserialize for Box<[T]> {
424    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
425        deserialize_slice(deserializer)
426    }
427}
428impl<T: Serialize> Serialize for Vec<T> {
429    fn serialize(&self, serializer: &mut ZSerializer) {
430        serialize_slice(self, serializer)
431    }
432}
433impl<T: Deserialize, const N: usize> Deserialize for [T; N] {
434    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
435        if <VarInt<usize>>::deserialize(deserializer)?.0 != N {
436            return Err(ZDeserializeError);
437        }
438        let mut array = std::array::from_fn(|_| MaybeUninit::uninit());
439        let slice = T::deserialize_n_uninit(&mut array, deserializer)?;
440        let (slice_ptr, slice_len) = (slice.as_ptr(), slice.len());
441        assert_eq!((slice_ptr, slice_len), (array.as_ptr().cast::<T>(), N));
442        // SAFETY: assertion checks the returned slice is array's one, and it's returned initialized
443        Ok(array.map(|t| unsafe { t.assume_init() }))
444    }
445}
446impl<T: Deserialize> Deserialize for Vec<T> {
447    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
448        Ok(deserialize_slice(deserializer)?.into_vec())
449    }
450}
451impl<T: Serialize + Eq + Hash> Serialize for HashSet<T> {
452    fn serialize(&self, serializer: &mut ZSerializer) {
453        serializer.serialize_iter(self);
454    }
455}
456impl<T: Deserialize + Eq + Hash> Deserialize for HashSet<T> {
457    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
458        deserializer.deserialize_iter()?.collect()
459    }
460}
461impl<T: Serialize + Ord> Serialize for BTreeSet<T> {
462    fn serialize(&self, serializer: &mut ZSerializer) {
463        serializer.serialize_iter(self);
464    }
465}
466impl<T: Deserialize + Ord> Deserialize for BTreeSet<T> {
467    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
468        deserializer.deserialize_iter()?.collect()
469    }
470}
471impl<K: Serialize + Eq + Hash, V: Serialize> Serialize for HashMap<K, V> {
472    fn serialize(&self, serializer: &mut ZSerializer) {
473        serializer.serialize_iter(self);
474    }
475}
476impl<K: Deserialize + Eq + Hash, V: Deserialize> Deserialize for HashMap<K, V> {
477    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
478        deserializer.deserialize_iter()?.collect()
479    }
480}
481impl<K: Serialize + Ord, V: Serialize> Serialize for BTreeMap<K, V> {
482    fn serialize(&self, serializer: &mut ZSerializer) {
483        serializer.serialize_iter(self);
484    }
485}
486impl<K: Deserialize + Ord, V: Deserialize> Deserialize for BTreeMap<K, V> {
487    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
488        deserializer.deserialize_iter()?.collect()
489    }
490}
491impl Serialize for str {
492    fn serialize(&self, serializer: &mut ZSerializer) {
493        self.as_bytes().serialize(serializer);
494    }
495}
496impl Serialize for Cow<'_, str> {
497    fn serialize(&self, serializer: &mut ZSerializer) {
498        self.as_bytes().serialize(serializer);
499    }
500}
501impl Serialize for String {
502    fn serialize(&self, serializer: &mut ZSerializer) {
503        self.as_bytes().serialize(serializer);
504    }
505}
506impl Deserialize for String {
507    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
508        String::from_utf8(Deserialize::deserialize(deserializer)?).or(Err(ZDeserializeError))
509    }
510}
511
512macro_rules! impl_tuple {
513    ($($ty:ident/$i:tt),* $(,)?) => {
514        impl_tuple!(@;$($ty/$i),*);
515    };
516    (@$($ty:ident/$i:tt),*; $next:ident/$next_i:tt $(, $remain:ident/$remain_i:tt)*) => {
517        impl_tuple!(@@$($ty/$i),*);
518        impl_tuple!(@$($ty/$i,)* $next/$next_i; $($remain/$remain_i),*);
519    };
520    (@$($ty:ident/$i:tt),*;) => {
521        impl_tuple!(@@$($ty/$i),*);
522    };
523    (@@$($ty:ident/$i:tt),* $(,)?) => {
524        #[allow(unused)]
525        impl<$($ty: Serialize),*> Serialize for ($($ty,)*) {
526            fn serialize(&self, serializer: &mut ZSerializer) {
527                $(self.$i.serialize(serializer);)*
528            }
529        }
530        #[allow(unused)]
531        impl<$($ty: Deserialize),*> Deserialize for ($($ty,)*) {
532            fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
533                Ok(($($ty::deserialize(deserializer)?,)*))
534            }
535        }
536    };
537}
538impl_tuple!(
539    T0 / 0,
540    T1 / 1,
541    T2 / 2,
542    T3 / 3,
543    T4 / 4,
544    T5 / 5,
545    T6 / 6,
546    T7 / 7,
547    T8 / 8,
548    T9 / 9,
549    T10 / 10,
550    T11 / 11,
551    T12 / 12,
552    T13 / 13,
553    T14 / 14,
554    T15 / 15,
555);
556
557/// The [LEB128](https://en.wikipedia.org/wiki/LEB128) variable-length integer encoding.
558///
559/// The `zenoh-ext` implements serialization and deserialization of integers in variable-length `LEB128` format.
560/// Currently it's implemented for `usize` only using the wrapper struct `VarInt<usize>`:
561/// the traits [`Serialize`] and [`Deserialize`] are implemented for `VarInt<usize>` using
562/// [leb128](https://crates.io/crates/leb128) crate.
563///
564/// This is used internally for serializing lengths of sequences (slices, `Vec`, `String`, `HashMap`, etc)
565/// and could be used by users to serialize integer values in a more compact way.
566#[repr(transparent)]
567#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
568pub struct VarInt<T>(pub T);
569impl Serialize for VarInt<usize> {
570    fn serialize(&self, serializer: &mut ZSerializer) {
571        leb128::write::unsigned(&mut serializer.0, self.0 as u64).unwrap();
572    }
573}
574impl Deserialize for VarInt<usize> {
575    fn deserialize(deserializer: &mut ZDeserializer) -> Result<Self, ZDeserializeError> {
576        let n = leb128::read::unsigned(&mut deserializer.0).or(Err(ZDeserializeError))?;
577        Ok(VarInt(<usize>::try_from(n).or(Err(ZDeserializeError))?))
578    }
579}
580
581#[cfg(test)]
582mod tests {
583    use std::ops::Range;
584
585    use rand::{thread_rng, Rng};
586
587    use super::*;
588
589    macro_rules! serialize_deserialize {
590        ($ty:ty, $expr:expr) => {
591            let expr: &$ty = &$expr;
592            let payload = z_serialize(expr);
593            let output = z_deserialize::<$ty>(&payload).unwrap();
594            assert_eq!(*expr, output);
595        };
596    }
597
598    const RANDOM_TESTS: Range<usize> = 0..1_000;
599
600    #[test]
601    fn numeric_serialization() {
602        macro_rules! test_int {
603            ($($ty:ty),* $(,)?) => {$(
604                serialize_deserialize!($ty, <$ty>::MIN);
605                serialize_deserialize!($ty, <$ty>::MAX);
606                let mut rng = thread_rng();
607                for _ in RANDOM_TESTS {
608                    serialize_deserialize!($ty, rng.gen::<$ty>());
609                }
610            )*};
611        }
612        test_int!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64);
613    }
614
615    #[test]
616    fn varint_serialization() {
617        serialize_deserialize!(VarInt<usize>, VarInt(<usize>::MIN));
618        serialize_deserialize!(VarInt<usize>, VarInt(<usize>::MAX));
619        let mut rng = thread_rng();
620        for _ in RANDOM_TESTS {
621            serialize_deserialize!(VarInt<usize>, VarInt(rng.gen::<usize>()));
622        }
623    }
624
625    #[test]
626    fn primitive_slice_serialization() {
627        let vec = vec![42.0f64, 0.15];
628        serialize_deserialize!(Vec<f64>, vec);
629        let payload = z_serialize(vec.as_slice());
630        assert_eq!(vec, z_deserialize::<Vec<f64>>(&payload).unwrap())
631    }
632
633    #[test]
634    fn slice_serialization() {
635        let vec = vec!["abc".to_string(), "def".to_string()];
636        serialize_deserialize!(Vec<String>, vec);
637        let payload = z_serialize(vec.as_slice());
638        assert_eq!(vec, z_deserialize::<Vec<String>>(&payload).unwrap())
639    }
640
641    #[test]
642    fn string_serialization() {
643        let s = "serialization".to_string();
644        serialize_deserialize!(String, s);
645        let payload = z_serialize(s.as_str());
646        assert_eq!(s, z_deserialize::<String>(&payload).unwrap())
647    }
648
649    #[test]
650    fn tuple_serialization() {
651        serialize_deserialize!(
652            (VarInt<usize>, f32, String),
653            (VarInt(42), 42.0f32, "42".to_string())
654        );
655    }
656
657    #[test]
658    fn hashmap_serialization() {
659        let mut map = HashMap::new();
660        map.insert("hello".to_string(), "world".to_string());
661        serialize_deserialize!(HashMap<String, String>, map);
662    }
663
664    macro_rules! check_binary_format {
665        ($expr:expr, $out:expr) => {
666            let payload = z_serialize(&$expr);
667            assert_eq!(payload.to_bytes(), $out);
668        };
669    }
670
671    #[test]
672    fn binary_format() {
673        let i1: i32 = 1234566;
674        check_binary_format!(i1, vec![134, 214, 18, 0]);
675        let i2: i32 = -49245;
676        check_binary_format!(i2, vec![163, 63, 255, 255]);
677        let s: &str = "test";
678        check_binary_format!(s, vec![4, 116, 101, 115, 116]);
679        let t: (u16, f32, &str) = (500, 1234.0, "test");
680        check_binary_format!(t, vec![244, 1, 0, 64, 154, 68, 4, 116, 101, 115, 116]);
681        let v: Vec<i64> = vec![-100, 500, 100000, -20000000];
682        check_binary_format!(
683            v,
684            vec![
685                4, 156, 255, 255, 255, 255, 255, 255, 255, 244, 1, 0, 0, 0, 0, 0, 0, 160, 134, 1,
686                0, 0, 0, 0, 0, 0, 211, 206, 254, 255, 255, 255, 255
687            ]
688        );
689        let vp: Vec<(&str, i16)> = vec![("s1", 10), ("s2", -10000)];
690        check_binary_format!(vp, vec![2, 2, 115, 49, 10, 0, 2, 115, 50, 240, 216]);
691    }
692}