Skip to main content

varing/arbitrary_int/
v2.rs

1use arbitrary_int_2::prelude::*;
2
3use core::num::NonZeroUsize;
4
5use crate::{utils::Buffer, *};
6
7macro_rules! generate {
8  ($($storage:ident($start:literal..=$end:literal)), +$(,)?) => {
9    $(
10      seq_macro::seq!(N in $start..=$end {
11        generate!($storage(
12          #(
13            u~N,
14          )*
15        ));
16      });
17    )*
18  };
19  ($($underlying:ident($($inner:ident), +$(,)?)),+$(,)?) => {
20    $(
21      $(
22        paste::paste! {
23          /// Returns the encoded length of the value in LEB128 variable length format.
24          #[doc = "The returned value will be in range of [`" $inner "::ENCODED_LEN_RANGE`]."]
25          #[inline]
26          pub const fn [< encoded_ $inner _varint_len >](value: $inner) -> NonZeroUsize {
27            [<encoded_ $underlying _varint_len>](value.value())
28          }
29
30          #[doc = "Encodes an `" $inner "` value into LEB128 variable length format, and writes it to the buffer."]
31          #[inline]
32          pub const fn [< encode_ $inner _varint >](x: $inner) -> $crate::utils::Buffer<{ $inner::MAX_ENCODED_LEN.get() + 1 }> {
33            let mut buf = [0; { $inner::MAX_ENCODED_LEN.get() + 1 }];
34            let len = match [< encode_ $inner _varint_to >](x, &mut buf) {
35              Ok(len) => len,
36              Err(_) => panic!("buffer should be large enough"),
37            };
38            buf[$crate::utils::Buffer::<{ $inner::MAX_ENCODED_LEN.get() + 1 }>::CAPACITY.get()] = len.get() as u8;
39            $crate::utils::Buffer::new(buf)
40          }
41
42          #[doc = "Encodes an `" $inner "` value into LEB128 variable length format, and writes it to the buffer."]
43          #[inline]
44          pub const fn [< encode_ $inner _varint_to >](value: $inner, buf: &mut [u8]) -> Result<NonZeroUsize, ConstEncodeError> {
45            [<encode_ $underlying _varint_to>](value.value(), buf)
46          }
47
48          #[doc = "Decodes an `" $inner "` in LEB128 encoded format from the buffer."]
49          ///
50          /// Returns the bytes read and the decoded value if successful.
51          #[inline]
52          pub const fn [< decode_ $inner _varint >](buf: &[u8]) -> Result<(NonZeroUsize, $inner), ConstDecodeError> {
53            match [<decode_ $underlying _varint>](buf) {
54              Ok((readed, val)) => {
55                match $inner::try_new(val) {
56                  Ok(val) => Ok((readed, val)),
57                  Err(_) => Err(ConstDecodeError::Overflow),
58                }
59              },
60              Err(err) => Err(err),
61            }
62          }
63
64          #[cfg(test)]
65          #[derive(Debug, Clone, Copy, PartialEq, Eq)]
66          struct [< Fuzzy $inner:camel >]($inner);
67
68          #[cfg(test)]
69          const _: () = {
70            use quickcheck::{Arbitrary, Gen};
71
72            impl Arbitrary for [< Fuzzy $inner:camel >] {
73              fn arbitrary(g: &mut Gen) -> Self {
74                let val = loop {
75                  let val = $underlying::arbitrary(g);
76                  if val >= $inner::MIN.[<as_ $underlying>]() && val <= $inner::MAX.[<as_ $underlying>]() {
77                    break val;
78                  }
79                };
80                Self($inner::try_new(val).unwrap())
81              }
82            }
83          };
84
85          #[cfg(test)]
86          quickcheck::quickcheck! {
87            fn [< fuzzy_ $inner _varint >](x: [< Fuzzy $inner:camel >]) -> bool {
88              let x = x.0;
89              let mut buf = [0; $inner::MAX_ENCODED_LEN.get()];
90              let len = [< encode_ $inner _varint_to >](x, &mut buf).unwrap();
91              let buffer = [< encode_ $inner _varint >](x);
92              assert_eq!(buffer.len(), len.get());
93              assert_eq!(buffer.as_slice(), &buf[..len.get()]);
94
95              let (readed, val) = [< decode_ $inner _varint >](&buf).unwrap();
96              assert_eq!(readed, len);
97              assert_eq!(val, x);
98
99              true
100            }
101          }
102
103          #[test]
104          fn [< test_ $inner _min_max_varint >]() {
105            let min = $inner::MIN;
106            let max = $inner::MAX;
107            let min_encoded_len = [< encoded_ $inner _varint_len >](min);
108            let max_encoded_len = [< encoded_ $inner _varint_len >](max);
109
110            assert_eq!(min_encoded_len, $inner::MIN_ENCODED_LEN);
111            assert_eq!(max_encoded_len, $inner::MAX_ENCODED_LEN);
112
113            let mut buf = [0; $inner::MAX_ENCODED_LEN.get()];
114            let len = [< encode_ $inner _varint_to >](min, &mut buf).unwrap();
115            assert_eq!(len, min_encoded_len);
116            let buffer = [< encode_ $inner _varint >](min);
117            assert_eq!(buffer.len(), min_encoded_len.get());
118            assert_eq!(buffer.as_slice(), &buf[..min_encoded_len.get()]);
119
120            let (readed, val) = [< decode_ $inner _varint >](&buf).unwrap();
121            assert_eq!(readed, len);
122            assert_eq!(val, min);
123
124            let len = [< encode_ $inner _varint_to >](max, &mut buf).unwrap();
125            assert_eq!(len, max_encoded_len);
126            let buffer = [< encode_ $inner _varint >](max);
127            assert_eq!(buffer.len(), max_encoded_len.get());
128            assert_eq!(buffer.as_slice(), &buf[..max_encoded_len.get()]);
129
130            let (readed, val) = [< decode_ $inner _varint >](&buf).unwrap();
131            assert_eq!(readed, len);
132            assert_eq!(val, max);
133          }
134        }
135      )*
136    )*
137  };
138  ($($storage:literal), +$(,)?) => {
139    paste::paste! {
140      $(
141        #[doc = "Returns the encoded length of the value in LEB128 variable length format."]
142        pub const fn [< encoded_uint_d $storage _len >]<const BITS: usize>(value: UInt<[< u $storage>], BITS>) -> NonZeroUsize {
143          [< encoded_u $storage _varint_len >](value.value())
144        }
145
146        #[doc = "Encodes an `Uint<u" $storage ", BITS>` value into LEB128 variable length format, and writes it to the buffer."]
147        pub const fn [< encode_uint_d $storage _to >]<const BITS: usize>(value: UInt<[< u $storage>], BITS>, buf: &mut [u8]) -> Result<NonZeroUsize, ConstEncodeError> {
148          [< encode_u $storage _varint_to >](value.value(), buf)
149        }
150
151        #[doc = "Encodes an `Uint<u" $storage ", BITS>` value into LEB128 variable length format, and writes it to the buffer."]
152        pub const fn [< encode_uint_d $storage>]<const BITS: usize>(value: UInt<[< u $storage>], BITS>) -> Buffer<{ [< u $storage>]::MAX_ENCODED_LEN.get() + 1 }> {
153          [< encode_u $storage _varint >](value.value())
154        }
155
156        #[doc = "Decodes an `Uint<u" $storage ", BITS>` in LEB128 encoded format from the buffer."]
157        pub const fn [< decode_uint_d $storage>]<const BITS: usize>(buf: &[u8]) -> Result<(NonZeroUsize, UInt<[< u $storage>], BITS>), ConstDecodeError> {
158          match [< decode_u $storage _varint >](buf) {
159            Ok((readed, val)) => {
160              match UInt::<[< u $storage>], BITS>::try_new(val) {
161                Ok(val) => Ok((readed, val)),
162                Err(_) => Err(ConstDecodeError::Overflow),
163              }
164            }
165            Err(err) => Err(err),
166          }
167        }
168
169        impl<const BITS: usize> Varint for UInt<[< u $storage>], BITS> {
170          const MIN_ENCODED_LEN: NonZeroUsize = [< encoded_uint_d $storage _len >](UInt::<[< u $storage>], BITS>::MIN);
171          const MAX_ENCODED_LEN: NonZeroUsize = [< encoded_uint_d $storage _len >](UInt::<[< u $storage>], BITS>::MAX);
172
173          fn encoded_len(&self) -> NonZeroUsize {
174            [< encoded_uint_d $storage _len >](*self)
175          }
176
177          fn encode(&self, buf: &mut [u8]) -> Result<NonZeroUsize, crate::EncodeError> {
178            [< encode_uint_d $storage _to >](*self, buf).map_err(Into::into)
179          }
180
181          fn decode(buf: &[u8]) -> Result<(NonZeroUsize, Self), crate::DecodeError>
182          where
183            Self: Sized,
184          {
185            [< decode_uint_d $storage >](buf).map_err(Into::into)
186          }
187        }
188      )*
189    }
190  };
191}
192
193generate!(
194  u8(1..=7),
195  u16(9..=15),
196  u32(17..=31),
197  u64(33..=63),
198  u128(65..=127),
199);
200
201generate!(8, 16, 32, 64, 128,);
202
203// --- Signed type support (arbitrary-int v2) ---
204
205macro_rules! generate_signed {
206  ($($storage:ident($start:literal..=$end:literal)), +$(,)?) => {
207    $(
208      seq_macro::seq!(N in $start..=$end {
209        generate_signed!($storage(
210          #(
211            i~N,
212          )*
213        ));
214      });
215    )*
216  };
217  ($($underlying:ident($($inner:ident), +$(,)?)),+$(,)?) => {
218    $(
219      $(
220        paste::paste! {
221          /// Returns the encoded length of the value in LEB128 variable length format.
222          #[doc = "The returned value will be in range of [`" $inner "::ENCODED_LEN_RANGE`]."]
223          #[inline]
224          pub const fn [< encoded_ $inner _varint_len >](value: $inner) -> NonZeroUsize {
225            [<encoded_ $underlying _varint_len>](value.value())
226          }
227
228          #[doc = "Encodes an `" $inner "` value into LEB128 variable length format, and writes it to the buffer."]
229          #[inline]
230          pub const fn [< encode_ $inner _varint >](x: $inner) -> $crate::utils::Buffer<{ <$inner as Varint>::MAX_ENCODED_LEN.get() + 1 }> {
231            let mut buf = [0; { <$inner as Varint>::MAX_ENCODED_LEN.get() + 1 }];
232            let len = match [< encode_ $inner _varint_to >](x, &mut buf) {
233              Ok(len) => len,
234              Err(_) => panic!("buffer should be large enough"),
235            };
236            buf[$crate::utils::Buffer::<{ <$inner as Varint>::MAX_ENCODED_LEN.get() + 1 }>::CAPACITY.get()] = len.get() as u8;
237            $crate::utils::Buffer::new(buf)
238          }
239
240          #[doc = "Encodes an `" $inner "` value into LEB128 variable length format, and writes it to the buffer."]
241          #[inline]
242          pub const fn [< encode_ $inner _varint_to >](value: $inner, buf: &mut [u8]) -> Result<NonZeroUsize, ConstEncodeError> {
243            [<encode_ $underlying _varint_to>](value.value(), buf)
244          }
245
246          #[doc = "Decodes an `" $inner "` in LEB128 encoded format from the buffer."]
247          ///
248          /// Returns the bytes read and the decoded value if successful.
249          #[inline]
250          pub const fn [< decode_ $inner _varint >](buf: &[u8]) -> Result<(NonZeroUsize, $inner), ConstDecodeError> {
251            match [<decode_ $underlying _varint>](buf) {
252              Ok((readed, val)) => {
253                match $inner::try_new(val) {
254                  Ok(val) => Ok((readed, val)),
255                  Err(_) => Err(ConstDecodeError::Overflow),
256                }
257              },
258              Err(err) => Err(err),
259            }
260          }
261
262          #[cfg(test)]
263          #[derive(Debug, Clone, Copy, PartialEq, Eq)]
264          struct [< FuzzySigned $inner:camel >]($inner);
265
266          #[cfg(test)]
267          const _: () = {
268            use quickcheck::{Arbitrary, Gen};
269            impl Arbitrary for [< FuzzySigned $inner:camel >] {
270              fn arbitrary(g: &mut Gen) -> Self {
271                let val = loop {
272                  let val = $underlying::arbitrary(g);
273                  if val >= $inner::MIN.value() && val <= $inner::MAX.value() {
274                    break val;
275                  }
276                };
277                Self($inner::try_new(val).unwrap())
278              }
279            }
280          };
281
282          #[cfg(test)]
283          quickcheck::quickcheck! {
284            fn [< fuzzy_ $inner _varint >](x: [< FuzzySigned $inner:camel >]) -> bool {
285              let x = x.0;
286              let mut buf = [0; <$inner as Varint>::MAX_ENCODED_LEN.get()];
287              let len = [< encode_ $inner _varint_to >](x, &mut buf).unwrap();
288              let buffer = [< encode_ $inner _varint >](x);
289              assert_eq!(buffer.len(), len.get());
290              assert_eq!(buffer.as_slice(), &buf[..len.get()]);
291
292              let (readed, val) = [< decode_ $inner _varint >](&buf).unwrap();
293              assert_eq!(readed, len);
294              assert_eq!(val, x);
295
296              true
297            }
298          }
299
300          #[test]
301          fn [< test_ $inner _min_max_varint >]() {
302            let min = $inner::MIN;
303            let max = $inner::MAX;
304            let min_encoded_len = [< encoded_ $inner _varint_len >](min);
305            let max_encoded_len = [< encoded_ $inner _varint_len >](max);
306
307            assert_eq!(min_encoded_len, <$inner as Varint>::MIN_ENCODED_LEN);
308            assert_eq!(max_encoded_len, <$inner as Varint>::MAX_ENCODED_LEN);
309
310            let mut buf = [0; <$inner as Varint>::MAX_ENCODED_LEN.get()];
311            let len = [< encode_ $inner _varint_to >](min, &mut buf).unwrap();
312            assert_eq!(len, min_encoded_len);
313            let buffer = [< encode_ $inner _varint >](min);
314            assert_eq!(buffer.len(), min_encoded_len.get());
315            assert_eq!(buffer.as_slice(), &buf[..min_encoded_len.get()]);
316
317            let (readed, val) = [< decode_ $inner _varint >](&buf).unwrap();
318            assert_eq!(readed, len);
319            assert_eq!(val, min);
320
321            let len = [< encode_ $inner _varint_to >](max, &mut buf).unwrap();
322            assert_eq!(len, max_encoded_len);
323            let buffer = [< encode_ $inner _varint >](max);
324            assert_eq!(buffer.len(), max_encoded_len.get());
325            assert_eq!(buffer.as_slice(), &buf[..max_encoded_len.get()]);
326
327            let (readed, val) = [< decode_ $inner _varint >](&buf).unwrap();
328            assert_eq!(readed, len);
329            assert_eq!(val, max);
330          }
331        }
332      )*
333    )*
334  };
335  (@generic $($storage:literal), +$(,)?) => {
336    paste::paste! {
337      $(
338        #[doc = "Returns the encoded length of the value in LEB128 variable length format."]
339        pub const fn [< encoded_int_d $storage _len >]<const BITS: usize>(value: Int<[< i $storage>], BITS>) -> NonZeroUsize {
340          [< encoded_i $storage _varint_len >](value.value())
341        }
342
343        #[doc = "Encodes an `Int<i" $storage ", BITS>` value into LEB128 variable length format, and writes it to the buffer."]
344        pub const fn [< encode_int_d $storage _to >]<const BITS: usize>(value: Int<[< i $storage>], BITS>, buf: &mut [u8]) -> Result<NonZeroUsize, ConstEncodeError> {
345          [< encode_i $storage _varint_to >](value.value(), buf)
346        }
347
348        #[doc = "Encodes an `Int<i" $storage ", BITS>` value into LEB128 variable length format, and writes it to the buffer."]
349        pub const fn [< encode_int_d $storage>]<const BITS: usize>(value: Int<[< i $storage>], BITS>) -> Buffer<{ [< i $storage>]::MAX_ENCODED_LEN.get() + 1 }> {
350          [< encode_i $storage _varint >](value.value())
351        }
352
353        #[doc = "Decodes an `Int<i" $storage ", BITS>` in LEB128 encoded format from the buffer."]
354        pub const fn [< decode_int_d $storage>]<const BITS: usize>(buf: &[u8]) -> Result<(NonZeroUsize, Int<[< i $storage>], BITS>), ConstDecodeError> {
355          match [< decode_i $storage _varint >](buf) {
356            Ok((readed, val)) => {
357              match Int::<[< i $storage>], BITS>::try_new(val) {
358                Ok(val) => Ok((readed, val)),
359                Err(_) => Err(ConstDecodeError::Overflow),
360              }
361            }
362            Err(err) => Err(err),
363          }
364        }
365
366        impl<const BITS: usize> Varint for Int<[< i $storage>], BITS> {
367          const MIN_ENCODED_LEN: NonZeroUsize = [< encoded_int_d $storage _len >](Int::<[< i $storage>], BITS>::MIN);
368          const MAX_ENCODED_LEN: NonZeroUsize = {
369            let min_len = [< encoded_int_d $storage _len >](Int::<[< i $storage>], BITS>::MIN);
370            let max_len = [< encoded_int_d $storage _len >](Int::<[< i $storage>], BITS>::MAX);
371            if min_len.get() > max_len.get() {
372              min_len
373            } else {
374              max_len
375            }
376          };
377
378          fn encoded_len(&self) -> NonZeroUsize {
379            [< encoded_int_d $storage _len >](*self)
380          }
381
382          fn encode(&self, buf: &mut [u8]) -> Result<NonZeroUsize, crate::EncodeError> {
383            [< encode_int_d $storage _to >](*self, buf).map_err(Into::into)
384          }
385
386          fn decode(buf: &[u8]) -> Result<(NonZeroUsize, Self), crate::DecodeError>
387          where
388            Self: Sized,
389          {
390            [< decode_int_d $storage >](buf).map_err(Into::into)
391          }
392        }
393      )*
394    }
395  };
396}
397
398generate_signed!(
399  i8(1..=7),
400  i16(9..=15),
401  i32(17..=31),
402  i64(33..=63),
403  i128(65..=127),
404);
405
406generate_signed!(@generic 8, 16, 32, 64, 128,);