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 #[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 #[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
203macro_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 #[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 #[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,);