1use core::num::{NonZeroU64, NonZeroUsize};
2
3use super::{
4 ConstDecodeError, ConstEncodeError, DecodeError, EncodeError, Varint,
5 utils::{self, zigzag_encode_i64},
6};
7
8macro_rules! impl_varint {
9 ($($ty:literal), +$(,)?) => {
10 $(
11 paste::paste! {
12 impl Varint for [< u $ty >] {
13 const MIN_ENCODED_LEN: ::core::num::NonZeroUsize = [< encoded_ u $ty _varint_len >](0);
14 const MAX_ENCODED_LEN: ::core::num::NonZeroUsize = [< encoded_ u $ty _varint_len >](<[< u $ty >]>::MAX);
15
16 #[inline]
17 fn encoded_len(&self) -> ::core::num::NonZeroUsize {
18 [< encoded_ u $ty _varint_len >](*self)
19 }
20
21 fn encode(&self, buf: &mut [u8]) -> Result<::core::num::NonZeroUsize, EncodeError> {
22 [< encode_ u $ty _varint_to >](*self, buf).map_err(Into::into)
23 }
24
25 #[inline]
26 fn decode(buf: &[u8]) -> Result<(::core::num::NonZeroUsize, Self), DecodeError> {
27 [< decode_ u $ty _varint >](buf).map_err(Into::into)
28 }
29 }
30
31 impl Varint for [< i $ty >] {
32 const MIN_ENCODED_LEN: ::core::num::NonZeroUsize = [< encoded_ i $ty _varint_len >](0);
33 const MAX_ENCODED_LEN: ::core::num::NonZeroUsize = [< encoded_ i $ty _varint_len >](<[< i $ty >]>::MAX);
34
35 #[inline]
36 fn encoded_len(&self) -> ::core::num::NonZeroUsize {
37 [< encoded_ i $ty _varint_len >](*self)
38 }
39
40 fn encode(&self, buf: &mut [u8]) -> Result<::core::num::NonZeroUsize, EncodeError> {
41 [< encode_ i $ty _varint_to >](*self, buf).map_err(Into::into)
42 }
43
44 #[inline]
45 fn decode(buf: &[u8]) -> Result<(::core::num::NonZeroUsize, Self), DecodeError> {
46 [< decode_ i $ty _varint >](buf).map_err(Into::into)
47 }
48 }
49 }
50 )*
51 };
52}
53
54macro_rules! decode_varint {
55 (|$buf:ident| $ty:ident) => {{
56 const MAX_ENCODED_LEN: usize = <$ty as Varint>::MAX_ENCODED_LEN.get();
57
58 let mut result = 0;
59 let mut shift = 0;
60 let mut index = 0;
61
62 loop {
63 if index == MAX_ENCODED_LEN {
64 return Err(ConstDecodeError::Overflow);
65 }
66
67 if index >= $buf.len() {
68 return Err(ConstDecodeError::insufficient_data($buf.len()));
69 }
70
71 let next = $buf[index] as $ty;
72
73 let v = $ty::BITS as usize / 7 * 7;
74 let has_overflow = if shift < v {
75 false
76 } else if shift == v {
77 next & ((u8::MAX << (::core::mem::size_of::<$ty>() % 7)) as $ty) != 0
78 } else {
79 true
80 };
81
82 if has_overflow {
83 return Err(ConstDecodeError::Overflow);
84 }
85
86 result += (next & 0x7F) << shift;
87 if next & 0x80 == 0 {
88 break;
89 }
90 shift += 7;
91 index += 1;
92 }
93 Ok((
95 unsafe { ::core::num::NonZeroUsize::new_unchecked(index + 1) },
96 result,
97 ))
98 }};
99}
100
101macro_rules! encode_varint {
102 ($buf:ident[$x:ident]) => {{
103 let mut i = 0;
104
105 while $x >= 0x80 {
106 if i >= $buf.len() {
107 panic!("insufficient buffer capacity");
108 }
109
110 $buf[i] = ($x as u8) | 0x80;
111 $x >>= 7;
112 i += 1;
113 }
114
115 if i >= $buf.len() {
117 panic!("insufficient buffer capacity");
118 }
119
120 $buf[i] = $x as u8;
121 i + 1
122 }};
123 (@to_buf $ty:ident::$buf:ident[$x:ident]) => {{
124 paste::paste! {
125 let mut i = 0;
126 let orig = $x;
127
128 while $x >= 0x80 {
129 if i >= $buf.len() {
130 return Err(ConstEncodeError::insufficient_space([< encoded_ $ty _varint_len >](orig), $buf.len()));
131 }
132
133 $buf[i] = ($x as u8) | 0x80;
134 $x >>= 7;
135 i += 1;
136 }
137
138 if i >= $buf.len() {
140 return Err(ConstEncodeError::insufficient_space(unsafe { ::core::num::NonZeroUsize::new_unchecked(i + 1) }, $buf.len()));
142 }
143
144 $buf[i] = $x as u8;
145 Ok(unsafe { ::core::num::NonZeroUsize::new_unchecked(i + 1) })
147 }
148 }};
149}
150
151macro_rules! varint_len {
152 ($($ty:ident),+$(,)?) => {
153 $(
154 paste::paste! {
155 #[doc = "The returned value will be in range of [`" $ty "::ENCODED_LEN_RANGE`]."]
157 #[inline]
158 pub const fn [< encoded_ $ty _varint_len >](value: $ty) -> ::core::num::NonZeroUsize {
159 encoded_u64_varint_len(value as u64)
160 }
161 }
162 )*
163 };
164 (@zigzag $($ty:ident),+$(,)?) => {
165 $(
166 paste::paste! {
167 #[doc = "The returned value will be in range of [`" $ty "::ENCODED_LEN_RANGE`]."]
169 #[inline]
170 pub const fn [< encoded_ $ty _varint_len >](value: $ty) -> ::core::num::NonZeroUsize {
171 encoded_i64_varint_len(value as i64)
172 }
173 }
174 )*
175 };
176}
177
178macro_rules! encode {
179 ($($ty:literal), +$(,)?) => {
180 $(
181 paste::paste! {
182 #[doc = "Encodes an `u" $ty "` value into LEB128 variable length format, and writes it to the buffer."]
183 #[inline]
184 pub const fn [< encode_ u $ty _varint >](mut x: [< u $ty >]) -> $crate::utils::Buffer<{ [<u $ty>]::MAX_ENCODED_LEN.get() + 1 }> {
185 let mut buf = [0; { [<u $ty>]::MAX_ENCODED_LEN.get() + 1 }];
186 let mut_buf = &mut buf;
187 let len = encode_varint!(mut_buf[x]);
188 buf[$crate::utils::Buffer::<{ [<u $ty>]::MAX_ENCODED_LEN.get() + 1 }>::CAPACITY.get()] = len as u8;
189 $crate::utils::Buffer::new(buf)
190 }
191
192 #[doc = "Encodes an `i" $ty "` value into LEB128 variable length format, and writes it to the buffer."]
193 #[inline]
194 pub const fn [< encode_ i $ty _varint >](x: [< i $ty >]) -> $crate::utils::Buffer<{ [<u $ty>]::MAX_ENCODED_LEN.get() + 1 }> {
195 let x = utils::[< zigzag_encode_i $ty>](x);
196 [< encode_ u $ty _varint >](x as [< u $ty >])
197 }
198
199 #[doc = "Encodes an `u" $ty "` value into LEB128 variable length format, and writes it to the buffer."]
200 #[inline]
201 pub const fn [< encode_ u $ty _varint_to >](mut x: [< u $ty >], buf: &mut [u8]) -> Result<::core::num::NonZeroUsize, ConstEncodeError> {
202 encode_varint!(@to_buf [< u $ty >]::buf[x])
203 }
204
205 #[doc = "Returns the encoded length of a sequence of `u" $ty "` values"]
206 #[inline]
207 pub const fn [< encoded_ u $ty _sequence_len >](sequence: &[[< u $ty >]]) -> usize {
208 encode!(@sequence_encoded_len_impl sequence, [< encoded_ u $ty _varint_len >])
209 }
210
211 #[doc = "Encodes a sequence of `u" $ty "` to the buffer."]
212 #[inline]
213 pub const fn [< encode_ u $ty _sequence_to >](sequence: &[[< u $ty >]], buf: &mut [u8]) -> Result<usize, ConstEncodeError> {
214 encode!(@sequence_encode_to_impl buf, sequence, [< encode_ u $ty _varint_to >], [< encoded_ u $ty _sequence_len >])
215 }
216
217 #[doc = "Encodes an `i" $ty "` value into LEB128 variable length format, and writes it to the buffer."]
218 #[inline]
219 pub const fn [< encode_ i $ty _varint_to >](x: [< i $ty >], buf: &mut [u8]) -> Result<::core::num::NonZeroUsize, ConstEncodeError> {
220 let mut x = utils::[< zigzag_encode_i $ty>](x);
221 encode_varint!(@to_buf [<u $ty>]::buf[x])
222 }
223
224 #[doc = "Returns the encoded length of a sequence of `i" $ty "` values"]
225 #[inline]
226 pub const fn [< encoded_i $ty _sequence_len >](sequence: &[[< i $ty >]]) -> usize {
227 encode!(@sequence_encoded_len_impl sequence, [< encoded_ i $ty _varint_len >])
228 }
229
230 #[doc = "Encodes a sequence of `i" $ty "` to the buffer."]
231 #[inline]
232 pub const fn [< encode_i $ty _sequence_to >](sequence: &[[< i $ty >]], buf: &mut [u8]) -> Result<usize, ConstEncodeError> {
233 encode!(@sequence_encode_to_impl buf, sequence, [< encode_ i $ty _varint_to >], [< encoded_ i $ty _sequence_len >])
234 }
235 }
236 )*
237 };
238 (@sequence_encode_to_impl $buf:ident, $sequence:ident, $encode_to:ident, $encoded_sequence_len:ident) => {{
239 let mut total_bytes = 0;
240 let mut idx = 0;
241 let len = $sequence.len();
242 let buf_len = $buf.len();
243
244 while idx < len && total_bytes < buf_len {
245 let (_, buf) = $buf.split_at_mut(total_bytes);
246 let bytes_written = match $encode_to($sequence[idx], buf) {
247 Ok(bytes_written) => bytes_written,
248 Err(e) => return Err({
249 let encoded_len = $encoded_sequence_len($sequence);
250 match ::core::num::NonZeroUsize::new(encoded_len) {
251 None => e,
252 Some(encoded_len) => e.update(encoded_len, buf_len),
253 }
254 }),
255 };
256 total_bytes += bytes_written.get();
257 idx += 1;
258 }
259
260 Ok(total_bytes)
261 }};
262 (@sequence_encoded_len_impl $sequence:ident, $encoded_len:ident) => {{
263 let mut total_bytes = 0;
264 let mut idx = 0;
265 let len = $sequence.len();
266
267 while idx < len {
268 total_bytes += $encoded_len($sequence[idx]).get();
269 idx += 1;
270 }
271
272 total_bytes
273 }};
274}
275
276macro_rules! decode {
277 ($($ty:literal), + $(,)?) => {
278 $(
279 paste::paste! {
280 #[doc = "Decodes a `u" $ty "` in LEB128 encoded format from the buffer."]
281 pub const fn [< decode_ u $ty _varint >](buf: &[u8]) -> Result<(::core::num::NonZeroUsize, [< u $ty >]), ConstDecodeError> {
284 decode_varint!(|buf| [< u $ty >])
285 }
286
287 #[doc = "Decodes an `i" $ty "` in LEB128 encoded format from the buffer."]
288 pub const fn [< decode_ i $ty _varint >](buf: &[u8]) -> Result<(::core::num::NonZeroUsize, [< i $ty >]), ConstDecodeError> {
291 match [< decode_ u $ty _varint >](buf) {
292 Ok((bytes_read, value)) => {
293 let value = utils::[<zigzag_decode_i $ty>](value);
294 Ok((bytes_read, value))
295 },
296 Err(e) => Err(e),
297 }
298 }
299 }
300 )*
301 };
302}
303
304impl_varint!(8, 16, 32, 64, 128,);
305varint_len!(u8, u16, u32,);
306varint_len!(@zigzag i8, i16, i32,);
307encode!(128, 64, 32, 16, 8);
308decode!(128, 64, 32, 16, 8);
309
310#[inline]
313pub const fn encoded_u128_varint_len(value: u128) -> NonZeroUsize {
314 if value < 128 {
318 return super::NON_ZERO_USIZE_ONE;
319 }
320
321 let highest_bit = 128 - value.leading_zeros();
323 unsafe { NonZeroUsize::new_unchecked(highest_bit.div_ceil(7) as usize) }
327}
328
329#[inline]
332pub const fn encoded_i128_varint_len(x: i128) -> NonZeroUsize {
333 let x = utils::zigzag_encode_i128(x);
334 encoded_u128_varint_len(x)
335}
336
337#[inline]
340pub const fn encoded_i64_varint_len(x: i64) -> NonZeroUsize {
341 let x = zigzag_encode_i64(x);
342 encoded_u64_varint_len(x)
343}
344
345#[inline]
348pub const fn encoded_u64_varint_len(value: u64) -> NonZeroUsize {
349 unsafe {
354 let log2value = NonZeroU64::new_unchecked(value | 1).ilog2();
356 NonZeroUsize::new_unchecked(((log2value * 9 + (64 + 9)) / 64) as usize)
357 }
358}
359
360impl Varint for bool {
361 const MIN_ENCODED_LEN: NonZeroUsize = crate::NON_ZERO_USIZE_ONE;
362
363 const MAX_ENCODED_LEN: NonZeroUsize = crate::NON_ZERO_USIZE_ONE;
364
365 #[inline]
366 fn encoded_len(&self) -> NonZeroUsize {
367 encoded_u8_varint_len(*self as u8)
368 }
369
370 #[inline]
371 fn encode(&self, buf: &mut [u8]) -> Result<NonZeroUsize, EncodeError> {
372 encode_u8_varint_to(*self as u8, buf).map_err(Into::into)
373 }
374
375 #[inline]
376 fn decode(buf: &[u8]) -> Result<(NonZeroUsize, Self), DecodeError>
377 where
378 Self: Sized,
379 {
380 decode_u8_varint(buf)
381 .map_err(Into::into)
382 .and_then(|(bytes_read, value)| {
383 if value > 1 {
384 return Err(DecodeError::other("invalid boolean value"));
385 }
386 Ok((bytes_read, value != 0))
387 })
388 }
389}
390
391impl Varint for f32 {
392 const MIN_ENCODED_LEN: NonZeroUsize = u32::MIN_ENCODED_LEN;
393
394 const MAX_ENCODED_LEN: NonZeroUsize = u32::MAX_ENCODED_LEN;
395
396 #[inline]
397 fn encoded_len(&self) -> NonZeroUsize {
398 encoded_f32_varint_len(*self)
399 }
400
401 #[inline]
402 fn encode(&self, buf: &mut [u8]) -> Result<NonZeroUsize, EncodeError> {
403 encode_f32_varint_to(*self, buf).map_err(Into::into)
404 }
405
406 #[inline]
407 fn decode(buf: &[u8]) -> Result<(NonZeroUsize, Self), DecodeError>
408 where
409 Self: Sized,
410 {
411 decode_f32_varint(buf).map_err(Into::into)
412 }
413}
414
415impl Varint for f64 {
416 const MIN_ENCODED_LEN: NonZeroUsize = u64::MIN_ENCODED_LEN;
417
418 const MAX_ENCODED_LEN: NonZeroUsize = u64::MAX_ENCODED_LEN;
419
420 #[inline]
421 fn encoded_len(&self) -> NonZeroUsize {
422 encoded_f64_varint_len(*self)
423 }
424
425 #[inline]
426 fn encode(&self, buf: &mut [u8]) -> Result<NonZeroUsize, EncodeError> {
427 encode_f64_varint_to(*self, buf).map_err(Into::into)
428 }
429
430 #[inline]
431 fn decode(buf: &[u8]) -> Result<(NonZeroUsize, Self), DecodeError>
432 where
433 Self: Sized,
434 {
435 decode_f64_varint(buf).map_err(Into::into)
436 }
437}
438
439#[inline]
441pub const fn encoded_f32_varint_len(value: f32) -> NonZeroUsize {
442 crate::encoded_u32_varint_len(value.to_bits())
443}
444
445#[inline]
447pub const fn encode_f32_varint(
448 value: f32,
449) -> crate::utils::Buffer<{ f32::MAX_ENCODED_LEN.get() + 1 }> {
450 crate::encode_u32_varint(value.to_bits())
451}
452
453#[inline]
455pub const fn encode_f32_varint_to(
456 value: f32,
457 buf: &mut [u8],
458) -> Result<NonZeroUsize, crate::ConstEncodeError> {
459 crate::encode_u32_varint_to(value.to_bits(), buf)
460}
461
462#[inline]
466pub const fn decode_f32_varint(buf: &[u8]) -> Result<(NonZeroUsize, f32), crate::ConstDecodeError> {
467 match crate::decode_u32_varint(buf) {
468 Ok((len, bits)) => Ok((len, f32::from_bits(bits))),
469 Err(e) => Err(e),
470 }
471}
472
473#[inline]
475pub const fn encoded_f64_varint_len(value: f64) -> NonZeroUsize {
476 crate::encoded_u64_varint_len(value.to_bits())
477}
478
479#[inline]
481pub const fn encode_f64_varint(
482 value: f64,
483) -> crate::utils::Buffer<{ f64::MAX_ENCODED_LEN.get() + 1 }> {
484 crate::encode_u64_varint(value.to_bits())
485}
486
487#[inline]
489pub const fn encode_f64_varint_to(
490 value: f64,
491 buf: &mut [u8],
492) -> Result<NonZeroUsize, crate::ConstEncodeError> {
493 crate::encode_u64_varint_to(value.to_bits(), buf)
494}
495
496#[inline]
500pub const fn decode_f64_varint(buf: &[u8]) -> Result<(NonZeroUsize, f64), crate::ConstDecodeError> {
501 match crate::decode_u64_varint(buf) {
502 Ok((len, bits)) => Ok((len, f64::from_bits(bits))),
503 Err(e) => Err(e),
504 }
505}
506
507#[inline]
509pub const fn encoded_f32_sequence_len(sequence: &[f32]) -> usize {
510 encode!(@sequence_encoded_len_impl sequence, encoded_f32_varint_len)
511}
512
513#[inline]
515pub const fn encode_f32_sequence_to(
516 sequence: &[f32],
517 buf: &mut [u8],
518) -> Result<usize, ConstEncodeError> {
519 encode!(@sequence_encode_to_impl buf, sequence, encode_f32_varint_to, encoded_f32_sequence_len)
520}
521
522#[inline]
524pub const fn encoded_f64_sequence_len(sequence: &[f64]) -> usize {
525 encode!(@sequence_encoded_len_impl sequence, encoded_f64_varint_len)
526}
527
528#[inline]
530pub const fn encode_f64_sequence_to(
531 sequence: &[f64],
532 buf: &mut [u8],
533) -> Result<usize, ConstEncodeError> {
534 encode!(@sequence_encode_to_impl buf, sequence, encode_f64_varint_to, encoded_f64_sequence_len)
535}
536
537#[cfg(feature = "half_2")]
539mod half;
540#[cfg(feature = "half_2")]
541pub use half::*;
542
543#[cfg(feature = "float8_0_4")]
545mod float8;
546#[cfg(feature = "float8_0_4")]
547pub use float8::*;