massa_serialization/
lib.rs

1use std::{
2    collections::VecDeque,
3    fmt::{Debug, Display},
4};
5
6use displaydoc::Display;
7use nom::{
8    branch::alt,
9    bytes::complete::tag,
10    combinator::{map_opt, value},
11    error::{ContextError, ParseError},
12    sequence::preceded,
13    sequence::tuple,
14    IResult, Parser,
15};
16use num::rational::Ratio;
17use num::Integer;
18use thiserror::Error;
19
20#[non_exhaustive]
21#[derive(Display, Error, Debug, Clone)]
22pub enum SerializeError {
23    /// Number {0} is too big to be serialized
24    NumberTooBig(String),
25    /// General error {0}
26    GeneralError(String),
27    /// String too big {0},
28    StringTooBig(String),
29}
30
31#[derive(Clone, Error)]
32pub struct DeserializeError<'a> {
33    errors: VecDeque<(&'a [u8], String)>,
34}
35
36impl<'a> ContextError<&'a [u8]> for DeserializeError<'a> {
37    fn add_context(input: &'a [u8], ctx: &'static str, mut other: Self) -> Self {
38        other.errors.push_front((input, ctx.to_string()));
39        other
40    }
41}
42
43impl<'a> ParseError<&'a [u8]> for DeserializeError<'a> {
44    fn append(input: &'a [u8], kind: nom::error::ErrorKind, mut other: Self) -> Self {
45        other
46            .errors
47            .push_front((input, kind.description().to_string()));
48        other
49    }
50    fn from_error_kind(input: &'a [u8], kind: nom::error::ErrorKind) -> Self {
51        let mut errors = VecDeque::new();
52        errors.push_front((input, kind.description().to_string()));
53        Self { errors }
54    }
55    fn from_char(input: &'a [u8], _: char) -> Self {
56        Self::from_error_kind(input, nom::error::ErrorKind::Char)
57    }
58    fn or(self, other: Self) -> Self {
59        other
60    }
61}
62
63impl<'a> Display for DeserializeError<'a> {
64    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65        for error in &self.errors {
66            write!(f, "{} / ", error.1)?;
67        }
68        Ok(())
69    }
70}
71
72impl<'a> Debug for DeserializeError<'a> {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        let mut last_input = None;
75        for error in &self.errors {
76            write!(f, "{} / ", error.1)?;
77            last_input = Some(error.0);
78        }
79        if let Some(last_input) = last_input {
80            writeln!(f, "Input: {:?}", last_input)?;
81        }
82        Ok(())
83    }
84}
85
86/// Trait that define the deserialize method that must be implemented for all types have serialize form in Massa.
87///
88/// This trait must be implemented on deserializers that will be defined for each type and can contains constraints.
89/// Example:
90/// ```
91/// use std::ops::Bound;
92/// use unsigned_varint::nom as varint_nom;
93/// use nom::{IResult, error::{context, ContextError, ParseError}};
94/// use massa_serialization::Deserializer;
95/// use std::ops::RangeBounds;
96///
97/// pub struct U64VarIntDeserializer {
98///     range: (Bound<u64>, Bound<u64>)
99/// }
100///
101/// impl U64VarIntDeserializer {
102///     fn new(min: Bound<u64>, max: Bound<u64>) -> Self {
103///         Self {
104///             range: (min, max)
105///         }
106///     }
107/// }
108///
109/// impl Deserializer<u64> for U64VarIntDeserializer {
110///     fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(&self, buffer: &'a [u8]) -> IResult<&'a [u8], u64, E> {
111///         context(concat!("Failed u64 deserialization"), |input: &'a [u8]| {
112///             let (rest, value) = varint_nom::u64(input).map_err(|_| nom::Err::Error(ParseError::from_error_kind(input, nom::error::ErrorKind::Fail)))?;
113///             if !self.range.contains(&value) {
114///                 return Err(nom::Err::Error(ParseError::from_error_kind(input, nom::error::ErrorKind::Fail)));
115///             }
116///             Ok((rest, value))
117///         })(buffer)
118///     }
119/// }
120/// ```
121pub trait Deserializer<T> {
122    /// Deserialize a value `T` from a buffer of `u8`.
123    ///
124    /// ## Parameters
125    /// * buffer: the buffer that contains the whole serialized data.
126    ///
127    /// ## Returns
128    /// A nom result with the rest of the serialized data and the decoded value.
129    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
130        &self,
131        buffer: &'a [u8],
132    ) -> IResult<&'a [u8], T, E>;
133}
134
135/// This trait must be implemented to serializes all data in Massa.
136///
137/// Example:
138/// ```
139/// use std::ops::Bound;
140/// use unsigned_varint::nom as varint_nom;
141/// use nom::IResult;
142/// use massa_serialization::Serializer;
143/// use std::ops::RangeBounds;
144/// use unsigned_varint::encode::u64_buffer;
145/// use unsigned_varint::encode::u64;
146/// use massa_serialization::SerializeError;
147///
148/// pub struct U64VarIntSerializer {
149///     range: (Bound<u64>, Bound<u64>)
150/// }
151///
152/// impl U64VarIntSerializer {
153///     fn new(min: Bound<u64>, max: Bound<u64>) -> Self {
154///         Self {
155///             range: (min, max)
156///         }
157///     }
158/// }
159///
160/// impl Serializer<u64> for U64VarIntSerializer {
161///     fn serialize(&self, value: &u64, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
162///         if !self.range.contains(value) {
163///             return Err(SerializeError::NumberTooBig(format!("Value {:#?} is not in range {:#?}", value, self.range)));
164///         }
165///         buffer.extend_from_slice(u64(*value, &mut u64_buffer()));
166///         Ok(())
167///     }
168/// }
169/// ```
170pub trait Serializer<T> {
171    /// Serialize a value `T` into a buffer of `u8`.
172    ///
173    /// ## Parameters
174    /// * value: the value to be serialized.
175    ///
176    /// ## Returns
177    /// A Result with the serialized data.
178    fn serialize(&self, value: &T, buffer: &mut Vec<u8>) -> Result<(), SerializeError>;
179}
180
181macro_rules! gen_varint {
182    ($($type:ident, $s:ident, $bs:ident, $ds:ident, $d:expr);*) => {
183        use std::ops::{Bound, RangeBounds};
184        use nom::error::context;
185        use unsigned_varint::nom as unsigned_nom;
186        $(
187            use unsigned_varint::encode::{$type, $bs};
188            #[doc = " Serializer for "]
189            #[doc = $d]
190            #[doc = " in a varint form."]
191            #[derive(Clone)]
192            pub struct $s;
193
194            impl $s {
195                #[doc = "Create a basic serializer for "]
196                #[doc = $d]
197                #[doc = " in a varint form."]
198                #[allow(dead_code)]
199                pub const fn new() -> Self {
200                    Self
201                }
202            }
203
204            impl Default for $s {
205                fn default() -> $s {
206                    $s::new()
207                }
208            }
209
210            impl Serializer<$type> for $s {
211                fn serialize(&self, value: &$type, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
212                    buffer.extend_from_slice($type(*value, &mut $bs()));
213                    Ok(())
214                }
215            }
216
217            #[doc = " Deserializer for "]
218            #[doc = $d]
219            #[doc = " in a varint form."]
220            #[derive(Clone)]
221            pub struct $ds {
222                range: (Bound<$type>, Bound<$type>)
223            }
224
225            impl $ds {
226                #[doc = "Create a basic deserializer for "]
227                #[doc = $d]
228                #[doc = " in a varint form."]
229                #[allow(dead_code)]
230                pub const fn new(min: Bound<$type>, max: Bound<$type>) -> Self {
231                    Self {
232                        range: (min, max)
233                    }
234                }
235            }
236
237            impl Deserializer<$type> for $ds {
238                fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(&self, buffer: &'a [u8]) -> IResult<&'a [u8], $type, E> {
239                    context(concat!("Failed ", stringify!($type), " deserialization"), |input: &'a [u8]| {
240                        let (rest, value) = unsigned_nom::$type(input).map_err(|_| nom::Err::Error(ParseError::from_error_kind(input, nom::error::ErrorKind::Fail)))?;
241                        if !self.range.contains(&value) {
242                            return Err(nom::Err::Error(ParseError::from_error_kind(input, nom::error::ErrorKind::Fail)));
243                        }
244                        Ok((rest, value))
245                    })(buffer)
246                }
247            }
248        )*
249    };
250}
251
252gen_varint! {
253u16, U16VarIntSerializer, u16_buffer, U16VarIntDeserializer, "`u16`";
254u32, U32VarIntSerializer, u32_buffer, U32VarIntDeserializer, "`u32`";
255u64, U64VarIntSerializer, u64_buffer, U64VarIntDeserializer, "`u64`";
256u128, U128VarIntSerializer, u128_buffer, U128VarIntDeserializer, "`u128`"
257}
258
259#[derive(Clone)]
260pub struct OptionSerializer<T, ST>
261where
262    ST: Serializer<T>,
263{
264    data_serializer: ST,
265    phantom_t: std::marker::PhantomData<T>,
266}
267
268impl<T, ST> OptionSerializer<T, ST>
269where
270    ST: Serializer<T>,
271{
272    pub fn new(data_serializer: ST) -> Self {
273        OptionSerializer {
274            data_serializer,
275            phantom_t: std::marker::PhantomData,
276        }
277    }
278}
279
280impl<T, ST> Serializer<Option<T>> for OptionSerializer<T, ST>
281where
282    ST: Serializer<T>,
283{
284    fn serialize(&self, opt_value: &Option<T>, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
285        if let Some(value) = opt_value {
286            buffer.push(b'1');
287            self.data_serializer.serialize(value, buffer)?;
288        } else {
289            buffer.push(b'0');
290        }
291        Ok(())
292    }
293}
294
295#[derive(Clone)]
296pub struct OptionDeserializer<T, DT>
297where
298    T: Clone,
299    DT: Deserializer<T>,
300{
301    data_deserializer: DT,
302    phantom_t: std::marker::PhantomData<T>,
303}
304
305impl<T, DT> OptionDeserializer<T, DT>
306where
307    T: Clone,
308    DT: Deserializer<T>,
309{
310    pub const fn new(data_deserializer: DT) -> Self {
311        OptionDeserializer {
312            data_deserializer,
313            phantom_t: std::marker::PhantomData,
314        }
315    }
316}
317
318impl<T, DT> Deserializer<Option<T>> for OptionDeserializer<T, DT>
319where
320    T: Clone,
321    DT: Deserializer<T>,
322{
323    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
324        &self,
325        buffer: &'a [u8],
326    ) -> IResult<&'a [u8], Option<T>, E> {
327        context(
328            "Option<_> deserializer failed",
329            alt((
330                context("None", value(None, tag(b"0"))),
331                context(
332                    "Some(_)",
333                    preceded(tag(b"1"), |input| {
334                        self.data_deserializer
335                            .deserialize(input)
336                            .map(|(rest, data)| (rest, Some(data)))
337                    }),
338                ),
339            )),
340        )
341        .parse(buffer)
342    }
343}
344
345/// Serializer for bool
346#[derive(Clone, Debug, Default)]
347pub struct BoolSerializer {}
348
349impl BoolSerializer {
350    /// ctor
351    pub fn new() -> Self {
352        Self {}
353    }
354}
355
356impl Serializer<bool> for BoolSerializer {
357    fn serialize(&self, value: &bool, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
358        buffer.push(*value as u8);
359        Ok(())
360    }
361}
362
363/// Deserializer for bool
364#[derive(Clone, Debug, Default)]
365pub struct BoolDeserializer {}
366
367impl BoolDeserializer {
368    /// ctor
369    pub fn new() -> Self {
370        Self {}
371    }
372}
373
374impl Deserializer<bool> for BoolDeserializer {
375    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
376        &self,
377        buffer: &'a [u8],
378    ) -> IResult<&'a [u8], bool, E> {
379        context("Failed bool deserialization", |input: &'a [u8]| {
380            let Some((first, rest)) = input.split_first() else {
381                return Err(nom::Err::Error(ParseError::from_error_kind(
382                    input,
383                    nom::error::ErrorKind::Fail,
384                )));
385            };
386            Ok((rest, {
387                match first {
388                    1 => Ok(true),
389                    0 => Ok(false),
390                    _ => Err(nom::Err::Error(ParseError::from_error_kind(
391                        input,
392                        nom::error::ErrorKind::Fail,
393                    ))),
394                }
395            }?))
396        })(buffer)
397    }
398}
399
400/// Serializer for Ratio
401#[derive(Clone, Debug, Default)]
402pub struct RatioSerializer<T, ST>
403where
404    T: Integer + Clone,
405    ST: Serializer<T>,
406{
407    data_serializer: ST,
408    phantom_data: std::marker::PhantomData<T>,
409}
410
411impl<T, ST> RatioSerializer<T, ST>
412where
413    T: Integer + Clone,
414    ST: Serializer<T>,
415{
416    pub fn new(data_serializer: ST) -> Self {
417        Self {
418            data_serializer,
419            phantom_data: std::marker::PhantomData,
420        }
421    }
422}
423
424impl<T, ST> Serializer<Ratio<T>> for RatioSerializer<T, ST>
425where
426    T: Integer + Clone,
427    ST: Serializer<T>,
428{
429    fn serialize(&self, value: &Ratio<T>, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
430        self.data_serializer.serialize(value.numer(), buffer)?;
431        self.data_serializer.serialize(value.denom(), buffer)?;
432        Ok(())
433    }
434}
435
436#[derive(Clone)]
437pub struct RatioDeserializer<T, DT>
438where
439    T: Integer + Clone,
440    DT: Deserializer<T>,
441{
442    data_deserializer: DT,
443    phantom_data: std::marker::PhantomData<T>,
444}
445
446impl<T, DT> RatioDeserializer<T, DT>
447where
448    T: Integer + Clone,
449    DT: Deserializer<T>,
450{
451    pub fn new(data_deserializer: DT) -> Self {
452        Self {
453            data_deserializer,
454            phantom_data: std::marker::PhantomData,
455        }
456    }
457}
458
459impl<T, DT> Deserializer<Ratio<T>> for RatioDeserializer<T, DT>
460where
461    T: Integer + Clone,
462    DT: Deserializer<T>,
463{
464    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
465        &self,
466        buffer: &'a [u8],
467    ) -> IResult<&'a [u8], Ratio<T>, E> {
468        context(
469            "Ratio<_> deserializer failed",
470            map_opt(
471                tuple((
472                    context("numer deser failed", |input| {
473                        self.data_deserializer.deserialize(input)
474                    }),
475                    context("denom deser failed", |input| {
476                        self.data_deserializer.deserialize(input)
477                    }),
478                )),
479                |(numer, denom)| {
480                    // A zero denominator is not a representable ratio: reject it as a
481                    // parse error instead of letting `Ratio::new` panic (which could
482                    // abort DB/bootstrap validation paths).
483                    if num::Zero::is_zero(&denom) {
484                        None
485                    } else {
486                        Some(Ratio::new(numer, denom))
487                    }
488                },
489            ),
490        )
491        .parse(buffer)
492    }
493}
494
495// Helper function to convert a slice to an array of a given size, if possible,
496// and then returning it with the rest of the slice.
497pub fn buf_to_array_ctr<F: Fn(&[u8; N]) -> V, V, const N: usize>(
498    buf: &[u8],
499    ctr: F,
500) -> Option<(&[u8], V)> {
501    Some((&buf[N..], ctr(&buf.get(..N)?.try_into().ok()?)))
502}
503
504#[cfg(test)]
505mod tests {
506    use crate::{DeserializeError, Deserializer, Serializer};
507    use num::rational::Ratio;
508    use paste::paste;
509
510    // This macro creates a suite of tests for all types of numbers declared as parameters. This list of the
511    // tests for each type :
512    // - Test with a normal case that everything works
513    // - Test with a normal case but a more bigger number that everything works
514    // - Test with a number that is out of the range of the deserializer
515    // - Test to give an empty buffer to the deserializer
516    macro_rules! gen_test_varint {
517        ($($type:ident, $bs:ident, $ds:ident);*) => {
518            $(
519                paste! {
520                    #[test]
521                    fn [<test_ $type _serializer_deserializer_works>]() {
522                        let [< $type _serializer >] = super::$bs::new();
523                        let number = [<3 $type >];
524                        let mut buffer = Vec::new();
525                        [< $type _serializer >].serialize(&number, &mut buffer).expect(concat!("Failed to serialize ", stringify!($type), " 3"));
526                        assert_eq!(buffer, vec![3]);
527                        let [< $type _deserializer >] = super::$ds::new(std::ops::Bound::Included([<0 $type >]), std::ops::Bound::Included(number));
528                        let result = [< $type _deserializer >].deserialize::<DeserializeError>(&buffer);
529                        assert!(result.is_ok());
530                        let (rest, value) = result.unwrap();
531                        assert!(rest.is_empty());
532                        assert_eq!(value, number);
533                    }
534
535                    #[test]
536                    fn [<test $type _serializer_deserializer_works_big_number>]() {
537                        let [< $type _serializer >] = super::$bs::new();
538                        let number = [<60_500 $type>];
539                        let mut buffer = Vec::new();
540                        [< $type _serializer >].serialize(&number, &mut buffer).expect(concat!("Failed to serialize ", stringify!($type), " 10_000_000"));
541                        assert_eq!(buffer, vec![212, 216, 3]);
542                        let [< $type _deserializer >] = super::$ds::new(std::ops::Bound::Included([<0 $type >]), std::ops::Bound::Included(number));
543                        let result = [< $type _deserializer >].deserialize::<DeserializeError>(&buffer);
544                        assert!(result.is_ok());
545                        let (rest, value) = result.unwrap();
546                        assert!(rest.is_empty());
547                        assert_eq!(value, number);
548                    }
549
550                    #[test]
551                    fn [<test_ $type _serializer_deserializer_bad_limits>]() {
552                        let [< $type _serializer >] = super::$bs::new();
553                        let number = [<3 $type >];
554                        let mut buffer = Vec::new();
555                        [< $type _serializer >].serialize(&number, &mut buffer).expect(concat!("Failed to serialize ", stringify!($type), " 3"));
556                        assert_eq!(buffer, vec![3]);
557                        let [< $type _deserializer >] = super::$ds::new(std::ops::Bound::Included([<0 $type >]), std::ops::Bound::Excluded(number));
558                        let result = [< $type _deserializer >].deserialize::<DeserializeError>(&buffer);
559                        assert!(result.is_err());
560                        let err = result.unwrap_err();
561                        assert_eq!(format!("{}", err), concat!("Parsing Error: Failed ", stringify!($type), " deserialization / Fail / Input: [3]\n"));
562                    }
563
564                    #[test]
565                    fn [<test_ $type _serializer_deserializer_empty_vec>]() {
566                        let buffer = vec![];
567                        let [< $type _deserializer >] = super::$ds::new(std::ops::Bound::Included([<0 $type >]), std::ops::Bound::Included($type::MAX));
568                        let result = [< $type _deserializer >].deserialize::<DeserializeError>(&buffer);
569                        assert!(result.is_err());
570                        let err = result.unwrap_err();
571                        assert_eq!(format!("{}", err), concat!("Parsing Error: Failed ", stringify!($type), " deserialization / Fail / Input: []\n"));
572                    }
573                }
574            )*
575        };
576    }
577
578    gen_test_varint!(
579        u16, U16VarIntSerializer, U16VarIntDeserializer;
580        u32, U32VarIntSerializer, U32VarIntDeserializer;
581        u64, U64VarIntSerializer, U64VarIntDeserializer
582    );
583
584    #[test]
585    fn test_u64_empty_vec() {
586        let buffer = vec![];
587        let u64_deserializer = super::U64VarIntDeserializer::new(
588            std::ops::Bound::Included(0),
589            std::ops::Bound::Included(3),
590        );
591        let result = u64_deserializer.deserialize::<DeserializeError>(&buffer);
592        assert!(result.is_err());
593        let err = result.unwrap_err();
594        assert_eq!(
595            format!("{}", err),
596            "Parsing Error: Failed u64 deserialization / Fail / Input: []\n"
597        );
598    }
599
600    #[test]
601    fn test_option_serializer_value_works() {
602        let option_serializer = super::OptionSerializer::new(super::U64VarIntSerializer::new());
603        let mut buffer = Vec::new();
604        option_serializer
605            .serialize(&Some(3u64), &mut buffer)
606            .expect("Failed to serialize Some(3)");
607        assert_eq!(buffer, vec![b'1', 3]);
608        let option_deserializer =
609            super::OptionDeserializer::new(super::U64VarIntDeserializer::new(
610                std::ops::Bound::Included(0),
611                std::ops::Bound::Included(3),
612            ));
613        let result = option_deserializer.deserialize::<DeserializeError>(&buffer);
614        assert!(result.is_ok());
615        let (rest, value) = result.unwrap();
616        assert!(rest.is_empty());
617        assert_eq!(value, Some(3u64));
618    }
619
620    #[test]
621    fn test_option_serializer_none_works() {
622        let option_serializer = super::OptionSerializer::new(super::U64VarIntSerializer::new());
623        let mut buffer = Vec::new();
624        option_serializer
625            .serialize(&None, &mut buffer)
626            .expect("Failed to serialize None");
627        assert_eq!(buffer, vec![b'0']);
628        let option_deserializer =
629            super::OptionDeserializer::new(super::U64VarIntDeserializer::new(
630                std::ops::Bound::Included(0),
631                std::ops::Bound::Included(3),
632            ));
633        let result = option_deserializer.deserialize::<DeserializeError>(&buffer);
634        assert!(result.is_ok());
635        let (rest, value) = result.unwrap();
636        assert!(rest.is_empty());
637        assert_eq!(value, None);
638    }
639
640    #[test]
641    fn test_option_bad_serialized_vec() {
642        let buffer = vec![2];
643        let option_deserializer =
644            super::OptionDeserializer::new(super::U64VarIntDeserializer::new(
645                std::ops::Bound::Included(0),
646                std::ops::Bound::Included(3),
647            ));
648        let result = option_deserializer.deserialize::<DeserializeError>(&buffer);
649        assert!(result.is_err());
650        let err = result.unwrap_err();
651        assert_eq!(format!("{}", err), "Parsing Error: Option<_> deserializer failed / Alternative / Some(_) / Tag / Input: [2]\n");
652    }
653
654    #[test]
655    fn test_option_empty_vec() {
656        let buffer = vec![];
657        let option_deserializer =
658            super::OptionDeserializer::new(super::U64VarIntDeserializer::new(
659                std::ops::Bound::Included(0),
660                std::ops::Bound::Included(3),
661            ));
662        let result = option_deserializer.deserialize::<DeserializeError>(&buffer);
663        assert!(result.is_err());
664        let err = result.unwrap_err();
665        assert_eq!(format!("{}", err), "Parsing Error: Option<_> deserializer failed / Alternative / Some(_) / Tag / Input: []\n");
666    }
667
668    #[test]
669    fn test_bool_serializer_deserializer_works() {
670        let bool_serializer = super::BoolSerializer::new();
671        let mut buffer = Vec::new();
672        bool_serializer
673            .serialize(&true, &mut buffer)
674            .expect("Failed to serialize true");
675        assert_eq!(buffer, vec![1]);
676        let bool_deserializer = super::BoolDeserializer::new();
677        let result = bool_deserializer.deserialize::<DeserializeError>(&buffer);
678        assert!(result.is_ok());
679        let (rest, value) = result.unwrap();
680        assert!(rest.is_empty());
681        assert!(value);
682    }
683
684    #[test]
685    fn test_bool_bad_serialized_vec() {
686        let buffer = vec![2];
687        let bool_deserializer = super::BoolDeserializer::new();
688        let result = bool_deserializer.deserialize::<DeserializeError>(&buffer);
689        assert!(result.is_err());
690        let err = result.unwrap_err();
691        assert_eq!(
692            format!("{}", err),
693            "Parsing Error: Failed bool deserialization / Fail / Input: [2]\n"
694        );
695    }
696
697    #[test]
698    fn test_bool_empty_vec() {
699        let buffer = vec![];
700        let bool_deserializer = super::BoolDeserializer::new();
701        let result = bool_deserializer.deserialize::<DeserializeError>(&buffer);
702        assert!(result.is_err());
703        let err = result.unwrap_err();
704        assert_eq!(
705            format!("{}", err),
706            "Parsing Error: Failed bool deserialization / Fail / Input: []\n"
707        );
708    }
709
710    #[test]
711    fn test_ratio_serializer_deserializer_works() {
712        let ratio_serializer = super::RatioSerializer::new(super::U64VarIntSerializer::new());
713        let mut buffer = Vec::new();
714        ratio_serializer
715            .serialize(&Ratio::new(3u64, 4u64), &mut buffer)
716            .expect("Failed to serialize Ratio(3, 4)");
717        assert_eq!(buffer, vec![3, 4]);
718        let ratio_deserializer = super::RatioDeserializer::new(super::U64VarIntDeserializer::new(
719            std::ops::Bound::Included(0),
720            std::ops::Bound::Included(4),
721        ));
722        let result = ratio_deserializer.deserialize::<DeserializeError>(&buffer);
723        assert!(result.is_ok());
724        let (rest, value) = result.unwrap();
725        assert!(rest.is_empty());
726        assert_eq!(value, Ratio::new(3u64, 4u64));
727    }
728
729    #[test]
730    fn test_ratio_serializer_deserializer_bad_limits() {
731        let ratio_serializer = super::RatioSerializer::new(super::U64VarIntSerializer::new());
732        let mut buffer = Vec::new();
733        ratio_serializer
734            .serialize(&Ratio::new(3u64, 4u64), &mut buffer)
735            .expect("Failed to serialize Ratio(3, 4)");
736        assert_eq!(buffer, vec![3, 4]);
737        let ratio_deserializer = super::RatioDeserializer::new(super::U64VarIntDeserializer::new(
738            std::ops::Bound::Included(0),
739            std::ops::Bound::Included(3),
740        ));
741        let result = ratio_deserializer.deserialize::<DeserializeError>(&buffer);
742        assert!(result.is_err());
743        let err = result.unwrap_err();
744        assert_eq!(format!("{}", err), "Parsing Error: Ratio<_> deserializer failed / denom deser failed / Failed u64 deserialization / Fail / Input: [4]\n");
745    }
746
747    #[test]
748    fn test_ratio_deserializer_rejects_zero_denominator() {
749        // numer = 1, denom = 0, each encoded as a single-byte u64 varint.
750        // A zero denominator must be rejected as a parse error instead of
751        // panicking inside `Ratio::new`.
752        let buffer = vec![1u8, 0u8];
753        let ratio_deserializer = super::RatioDeserializer::new(super::U64VarIntDeserializer::new(
754            std::ops::Bound::Included(0),
755            std::ops::Bound::Included(u64::MAX),
756        ));
757        let result = ratio_deserializer.deserialize::<DeserializeError>(&buffer);
758        assert!(
759            result.is_err(),
760            "a zero denominator must produce a deserialization error, not a panic"
761        );
762    }
763}