const_varint/
non_zero.rs

1use core::num::*;
2
3macro_rules! impl_for_non_zero {
4  ($($ty:ident), +$(,)?) => {
5    $(
6      paste::paste! {
7        impl $crate::Varint for [< NonZero $ty:camel >] {
8          const MIN_ENCODED_LEN: usize = $ty::MIN_ENCODED_LEN;
9
10          const MAX_ENCODED_LEN: usize = $ty::MAX_ENCODED_LEN;
11
12          fn encoded_len(&self) -> usize {
13            self.get().encoded_len()
14          }
15
16          fn encode(&self, buf: &mut [u8]) -> Result<usize, crate::EncodeError> {
17            self.get().encode(buf)
18          }
19
20          fn decode(buf: &[u8]) -> Result<(usize, Self), crate::DecodeError>
21          where
22            Self: Sized,
23          {
24            $ty::decode(buf).and_then(|(n, x)| {
25              if x == 0 {
26                Err(crate::DecodeError::custom(concat!(stringify!([< NonZero $ty:camel >]), "cannot be zero")))
27              } else {
28                Ok((n, unsafe { Self::new_unchecked(x) }))
29              }
30            })
31          }
32        }
33      }
34    )*
35  };
36}
37
38impl_for_non_zero!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128,);
39
40#[cfg(test)]
41mod tests {
42  use crate::{consume_varint, Varint};
43  use core::num::*;
44
45  macro_rules! fuzzy {
46    ($($ty:ty), +$(,)?) => {
47      $(
48        paste::paste! {
49          #[quickcheck_macros::quickcheck]
50          fn [< fuzzy_non_zero_ $ty _varint>](value: $ty) -> bool {
51            if value == 0 {
52              return true;
53            }
54
55            let value = [< NonZero $ty:camel >]::new(value).unwrap();
56
57            let mut buf = [0; <[< NonZero $ty:camel >]>::MAX_ENCODED_LEN];
58            let Ok(encoded_len) = value.encode(&mut buf) else { return false; };
59            if encoded_len != value.encoded_len() || !(value.encoded_len() <= <[< NonZero $ty:camel >]>::MAX_ENCODED_LEN) {
60              return false;
61            }
62
63            let Ok(consumed) = consume_varint(&buf) else {
64              return false;
65            };
66            if consumed != encoded_len {
67              return false;
68            }
69
70            if let Ok((bytes_read, decoded)) = <[< NonZero $ty:camel >]>::decode(&buf) {
71              value == decoded && encoded_len == bytes_read
72            } else {
73              false
74            }
75          }
76        }
77      )*
78    };
79  }
80
81  fuzzy!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128,);
82}