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}