irox_tools/codec/
vbyte.rs

1// SPDX-License-Identifier: MIT
2// Copyright 2025 IROX Contributors
3//
4
5use crate::buf::Buffer;
6use crate::buf::FixedBuf;
7use crate::{cfg_feature_alloc, IntegerValue};
8use irox_bits::{Bits, BitsError, Error, MutBits};
9
10macro_rules! round {
11    ($val:ident) => {{
12        let val = $val >> 7;
13        let a = ((val & 0x7F) | 0x80) as u8;
14        (a, val)
15    }};
16}
17macro_rules! one_byte_mask {
18    () => {
19        0x7F
20    };
21}
22macro_rules! two_byte_mask {
23    () => {
24        0x3FFF
25    };
26}
27macro_rules! three_byte_mask {
28    () => {
29        0x1F_FFFF
30    };
31}
32macro_rules! four_byte_mask {
33    () => {
34        0xFFF_FFFF
35    };
36}
37macro_rules! five_byte_mask {
38    () => {
39        0x7_FFFF_FFFF
40    };
41}
42macro_rules! six_byte_mask {
43    () => {
44        0x3FF_FFFF_FFFF
45    };
46}
47macro_rules! seven_byte_mask {
48    () => {
49        0x1_FFFF_FFFF_FFFF
50    };
51}
52macro_rules! eight_byte_mask {
53    () => {
54        0xFF_FFFF_FFFF_FFFF
55    };
56}
57macro_rules! nine_byte_mask {
58    () => {
59        0x7FFF_FFFF_FFFF_FFFF
60    };
61}
62
63///
64///
65/// ```text
66///  7       0
67/// |--------|
68///  01111111
69///
70/// ```
71pub fn encode_7bits(val: u8) -> [u8; 1] {
72    [val & 0x7F]
73}
74///
75///
76/// ```text
77///  7       0
78/// |--------|
79///  XXXXXXXX
80///
81/// 15        7       0
82/// |--------|--------|
83///  1000000X 0XXXXXXX
84///
85/// ```
86pub fn encode_8bits(val: u8) -> [u8; 2] {
87    let upper = (val & 0x80) >> 7;
88    [0x80 | upper, val & 0x7F]
89}
90
91///
92/// 14 bits = `0x3FFF`
93/// ```text
94/// 15        7       0
95/// |--------|--------|
96///  00111111 10000000
97///
98/// ```
99pub fn encode_14bits(val: u16) -> [u8; 2] {
100    let b = (val & 0x7F) as u8;
101    let (a, _) = round!(val);
102    [a, b]
103}
104
105///
106/// 16 bits => `0xFFFF`
107/// ```text
108/// 15        7       0
109/// |--------|--------|
110///  22111111 10000000
111///
112/// ```
113pub fn encode_16bits(val: u16) -> [u8; 3] {
114    let c = (val & 0x7F) as u8;
115    let (b, val) = round!(val);
116    let (a, _) = round!(val);
117    [a, b, c]
118}
119///
120/// 21 bits => `0x1F_FFFF`
121/// ```text
122/// 24       15        7       0
123/// |--------|--------|--------|
124///  33322222 22111111 10000000
125/// |--------|--------|--------|
126///  12222222 11111111 00000000
127/// ```
128pub fn encode_21bits(val: u32) -> [u8; 3] {
129    let c = (val & 0x7F) as u8;
130    let (b, val) = round!(val);
131    let (a, _) = round!(val);
132    [a, b, c]
133}
134///
135/// 28 bits => `0xFFF_FFFF`
136/// ```text
137/// 31       23       15        7       0
138/// |--------|--------|--------|--------|
139///  44443333 33322222 22111111 10000000
140/// |--------|--------|--------|--------|
141///  13333333 12222222 11111111 00000000
142///
143/// ```
144pub fn encode_28bits(val: u32) -> [u8; 4] {
145    let d = (val & 0x7F) as u8;
146    let (c, val) = round!(val);
147    let (b, val) = round!(val);
148    let (a, _) = round!(val);
149    [a, b, c, d]
150}
151
152///
153/// 32 bits => `0xFFFF_FFFF`
154/// ```text
155/// 31       23       15        7       0
156/// |--------|--------|--------|--------|
157///  44443333 33322222 22111111 10000000
158/// |--------|--------|--------|--------|
159///  13333333 12222222 11111111 00000000
160///
161/// 63       55       47       39       31
162/// |--------|--------|--------|--------|
163///                    66666655 55555444
164/// |--------|--------|--------|--------|
165///                             14444444
166/// ```
167pub fn encode_32bits(val: u32) -> [u8; 5] {
168    let e = (val & 0x7F) as u8;
169    let (d, val) = round!(val);
170    let (c, val) = round!(val);
171    let (b, val) = round!(val);
172    let (a, _) = round!(val);
173    [a, b, c, d, e]
174}
175
176///
177/// 35 bits => `0x7_FFFF_FFFF`
178/// ```text
179/// 31       23       15        7       0
180/// |--------|--------|--------|--------|
181///  44443333 33322222 22111111 10000000
182/// |--------|--------|--------|--------|
183///  13333333 12222222 11111111 00000000
184///
185/// 63       55       47       39       31
186/// |--------|--------|--------|--------|
187///  98888888 77777776 66666655 55555444
188/// |--------|--------|--------|--------|
189///  17777777 16666666 15555555 14444444
190/// ```
191pub fn encode_35bits(val: u64) -> [u8; 5] {
192    let e = (val & 0x7F) as u8;
193    let (d, val) = round!(val);
194    let (c, val) = round!(val);
195    let (b, val) = round!(val);
196    let (a, _) = round!(val);
197    [a, b, c, d, e]
198}
199
200///
201/// 42 bits => `0x3FF_FFFF_FFFF`
202/// ```text
203/// 31       23       15        7       0
204/// |--------|--------|--------|--------|
205///  44443333 33322222 22111111 10000000
206/// |--------|--------|--------|--------|
207///  13333333 12222222 11111111 00000000
208///
209/// 63       55       47       39       31
210/// |--------|--------|--------|--------|
211///  98888888 77777776 66666655 55555444
212/// |--------|--------|--------|--------|
213///  17777777 16666666 15555555 14444444
214/// ```
215pub fn encode_42bits(val: u64) -> [u8; 6] {
216    let f = (val & 0x7F) as u8;
217    let (e, val) = round!(val);
218    let (d, val) = round!(val);
219    let (c, val) = round!(val);
220    let (b, val) = round!(val);
221    let (a, _) = round!(val);
222    [a, b, c, d, e, f]
223}
224
225///
226/// 49 bits => `0x1_FFFF_FFFF_FFFF`
227/// ```text
228/// 31       23       15        7       0
229/// |--------|--------|--------|--------|
230///  44443333 33322222 22111111 10000000
231/// |--------|--------|--------|--------|
232///  13333333 12222222 11111111 00000000
233///
234/// 63       55       47       39       32
235/// |--------|--------|--------|--------|
236///  98888888 77777776 66666655 55555444
237/// |--------|--------|--------|--------|
238///  17777777 16666666 15555555 14444444
239/// ```
240pub fn encode_49bits(val: u64) -> [u8; 7] {
241    let g = (val & 0x7F) as u8;
242    let (f, val) = round!(val);
243    let (e, val) = round!(val);
244    let (d, val) = round!(val);
245    let (c, val) = round!(val);
246    let (b, val) = round!(val);
247    let (a, _) = round!(val);
248    [a, b, c, d, e, f, g]
249}
250///
251/// 56 bits => `0xFF_FFFF_FFFF_FFFF`
252/// ```text
253/// 32       23       15        7       0
254/// |--------|--------|--------|--------|
255///  44443333 33322222 22111111 10000000
256/// |--------|--------|--------|--------|
257///  13333333 12222222 11111111 00000000
258///
259/// 63       55       47       39       31
260/// |--------|--------|--------|--------|
261///  98888888 77777776 66666655 55555444
262/// |--------|--------|--------|--------|
263///  17777777 16666666 15555555 14444444
264/// ```
265pub fn encode_56bits(val: u64) -> [u8; 8] {
266    let h = (val & 0x7F) as u8;
267    let (g, val) = round!(val);
268    let (f, val) = round!(val);
269    let (e, val) = round!(val);
270    let (d, val) = round!(val);
271    let (c, val) = round!(val);
272    let (b, val) = round!(val);
273    let (a, _) = round!(val);
274    [a, b, c, d, e, f, g, h]
275}
276///
277/// 63 bits => `0x7FFF_FFFF_FFFF_FFFF`
278/// ```text
279/// 32       23       15        7       0
280/// |--------|--------|--------|--------|
281///  44443333 33322222 22111111 10000000
282/// |--------|--------|--------|--------|
283///  13333333 12222222 11111111 00000000
284///
285/// 63       55       47       39       31
286/// |--------|--------|--------|--------|
287///  98888888 77777776 66666655 55555444
288/// |--------|--------|--------|--------|
289///  17777777 16666666 15555555 14444444
290/// ```
291pub fn encode_63bits(val: u64) -> [u8; 9] {
292    let i = (val & 0x7F) as u8;
293    let (h, val) = round!(val);
294    let (g, val) = round!(val);
295    let (f, val) = round!(val);
296    let (e, val) = round!(val);
297    let (d, val) = round!(val);
298    let (c, val) = round!(val);
299    let (b, val) = round!(val);
300    let (a, _) = round!(val);
301    [a, b, c, d, e, f, g, h, i]
302}
303
304///
305/// 64 bits => 0xFFFF_FFFF_FFFF_FFFF
306/// ```text
307/// 32       23       15        7       0
308/// |--------|--------|--------|--------|
309///  44443333 33322222 22111111 10000000
310/// |--------|--------|--------|--------|
311///  13333333 12222222 11111111 00000000
312///
313/// 63       55       47       39       31
314/// |--------|--------|--------|--------|
315///  98888888 77777776 66666655 55555444
316/// |--------|--------|--------|--------|
317///  17777777 16666666 15555555 14444444
318/// ```
319pub fn encode_64bits(val: u64) -> [u8; 10] {
320    let j = (val & 0x7F) as u8;
321    let (i, val) = round!(val);
322    let (h, val) = round!(val);
323    let (g, val) = round!(val);
324    let (f, val) = round!(val);
325    let (e, val) = round!(val);
326    let (d, val) = round!(val);
327    let (c, val) = round!(val);
328    let (b, val) = round!(val);
329    let (a, _) = round!(val);
330    [a, b, c, d, e, f, g, h, i, j]
331}
332
333///
334/// 70 bits => 0x3F_FFFF_FFFF_FFFF_FFFF
335/// ```text
336///      8        7        6        5        4        3        2        1
337/// 64       56       48       40       32       24       16        8       0
338/// |--------|--------|--------|--------|--------|--------|--------|--------|
339///  98888888 77777776 66666655 55555444 44443333 33322222 22111111 10000000
340/// |--------|--------|--------|--------|--------|--------|--------|--------|
341///  17777777 16666666 15555555 14444444 13333333 12222222 11111111 00000000
342///
343///     16       15       14       13       12        11       10       9
344/// 128     120      112      104       96       88       80       72       64
345/// |--------|--------|--------|--------|--------|--------|--------|--------|
346///  IIHHHHHH HGGGGGGG FFFFFFFE EEEEEEDD DDDDDCCC CCCCBBBB BBBAAAAA AA999999
347/// |--------|--------|--------|--------|--------|--------|--------|--------|
348///  1FFFFFFF 1EEEEEEE 1DDDDDDD 1CCCCCCC 1BBBBBBB 1AAAAAAA 19999999 18888888
349///
350///      19       18       17
351/// 152     144      136      128
352/// |--------|--------|--------|
353///  100000II 1HHHHHHH 1GGGGGGG
354/// |--------|--------|--------|
355///
356/// ```
357pub fn encode_u128bits(val: u128) -> FixedBuf<19, u8> {
358    let mut out = FixedBuf::<19, u8>::new();
359    let j = (val & 0x7F) as u8;
360    let _ = out.push(j);
361    loop {
362        let (i, val) = round!(val);
363        let _ = out.push(i);
364        if val == 0 {
365            break;
366        }
367    }
368    out
369}
370
371macro_rules! zigzag_impl {
372    ($id:ident,$un:ident,$sig:ty,$usig:ty,$len:literal) => {
373        pub fn $id(n: $sig) -> $usig {
374            ((n << 1) ^ (n >> ($len - 1))) as $usig
375        }
376        pub fn $un(n: $usig) -> $sig {
377            let v = (n & 0x01) as $sig;
378            let v = (n >> 1) as $sig ^ -v;
379            v as $sig
380        }
381        impl ZigZag for $sig {
382            type Output = $usig;
383            fn zigzag(self) -> $usig {
384                $id(self)
385            }
386        }
387        impl ZagZig for $usig {
388            type Output = $sig;
389            fn zagzig(self) -> Self::Output {
390                $un(self)
391            }
392        }
393    };
394}
395zigzag_impl!(zigzag_i8, zagzig_u8, i8, u8, 8);
396zigzag_impl!(zigzag_i16, zagzig_u16, i16, u16, 16);
397zigzag_impl!(zigzag_i32, zagzig_u32, i32, u32, 32);
398zigzag_impl!(zigzag_i64, zagzig_u64, i64, u64, 64);
399zigzag_impl!(zigzag_i128, zagzig_u128, i128, u128, 128);
400
401pub trait ZigZag {
402    type Output;
403    fn zigzag(self) -> Self::Output;
404}
405pub trait ZagZig {
406    type Output;
407    fn zagzig(self) -> Self::Output;
408}
409
410pub fn encode_integer_to<T: MutBits + ?Sized>(
411    val: IntegerValue,
412    out: &mut T,
413) -> Result<usize, BitsError> {
414    match val {
415        IntegerValue::U8(v) => {
416            if v <= one_byte_mask!() {
417                out.write_all_bytes(&encode_7bits(v))?;
418                Ok(1)
419            } else {
420                out.write_all_bytes(&encode_8bits(v))?;
421                Ok(2)
422            }
423        }
424        IntegerValue::U16(v) => {
425            if v <= one_byte_mask!() {
426                out.write_all_bytes(&encode_7bits(v as u8))?;
427                Ok(1)
428            } else if v <= two_byte_mask!() {
429                out.write_all_bytes(&encode_14bits(v))?;
430                Ok(2)
431            } else {
432                out.write_all_bytes(&encode_16bits(v))?;
433                Ok(3)
434            }
435        }
436        IntegerValue::U32(v) => {
437            if v <= one_byte_mask!() {
438                out.write_all_bytes(&encode_7bits(v as u8))?;
439                Ok(1)
440            } else if v <= two_byte_mask!() {
441                out.write_all_bytes(&encode_14bits(v as u16))?;
442                Ok(2)
443            } else if v <= three_byte_mask!() {
444                out.write_all_bytes(&encode_21bits(v))?;
445                Ok(3)
446            } else if v <= four_byte_mask!() {
447                out.write_all_bytes(&encode_28bits(v))?;
448                Ok(4)
449            } else {
450                out.write_all_bytes(&encode_32bits(v))?;
451                Ok(5)
452            }
453        }
454        IntegerValue::U64(v) => {
455            if v <= one_byte_mask!() {
456                out.write_all_bytes(&encode_7bits(v as u8))?;
457                Ok(1)
458            } else if v <= two_byte_mask!() {
459                out.write_all_bytes(&encode_14bits(v as u16))?;
460                Ok(2)
461            } else if v <= three_byte_mask!() {
462                out.write_all_bytes(&encode_21bits(v as u32))?;
463                Ok(3)
464            } else if v <= four_byte_mask!() {
465                out.write_all_bytes(&encode_28bits(v as u32))?;
466                Ok(4)
467            } else if v <= five_byte_mask!() {
468                out.write_all_bytes(&encode_35bits(v))?;
469                Ok(5)
470            } else if v <= six_byte_mask!() {
471                out.write_all_bytes(&encode_42bits(v))?;
472                Ok(6)
473            } else if v <= seven_byte_mask!() {
474                out.write_all_bytes(&encode_49bits(v))?;
475                Ok(7)
476            } else if v <= eight_byte_mask!() {
477                out.write_all_bytes(&encode_56bits(v))?;
478                Ok(8)
479            } else if v <= nine_byte_mask!() {
480                out.write_all_bytes(&encode_63bits(v))?;
481                Ok(9)
482            } else {
483                out.write_all_bytes(&encode_64bits(v))?;
484                Ok(10)
485            }
486        }
487        IntegerValue::U128(v) => encode_u128bits(v).write_to(out),
488        IntegerValue::I8(v) => zigzag_i8(v).encode_vbyte_to(out),
489        IntegerValue::I16(v) => zigzag_i16(v).encode_vbyte_to(out),
490        IntegerValue::I32(v) => zigzag_i32(v).encode_vbyte_to(out),
491        IntegerValue::I64(v) => zigzag_i64(v).encode_vbyte_to(out),
492        IntegerValue::I128(v) => zigzag_i128(v).encode_vbyte_to(out),
493    }
494}
495pub trait EncodeVByteTo {
496    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError>;
497}
498impl EncodeVByteTo for u128 {
499    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
500        encode_integer_to(IntegerValue::U128(*self), out)
501    }
502}
503impl EncodeVByteTo for i128 {
504    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
505        encode_integer_to(IntegerValue::I128(*self), out)
506    }
507}
508impl EncodeVByteTo for u64 {
509    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
510        encode_integer_to(IntegerValue::U64(*self), out)
511    }
512}
513impl EncodeVByteTo for i64 {
514    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
515        encode_integer_to(IntegerValue::I64(*self), out)
516    }
517}
518impl EncodeVByteTo for u32 {
519    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
520        encode_integer_to(IntegerValue::U32(*self), out)
521    }
522}
523impl EncodeVByteTo for i32 {
524    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
525        encode_integer_to(IntegerValue::I32(*self), out)
526    }
527}
528impl EncodeVByteTo for u16 {
529    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
530        encode_integer_to(IntegerValue::U16(*self), out)
531    }
532}
533impl EncodeVByteTo for i16 {
534    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
535        encode_integer_to(IntegerValue::I16(*self), out)
536    }
537}
538impl EncodeVByteTo for u8 {
539    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
540        encode_integer_to(IntegerValue::U8(*self), out)
541    }
542}
543impl EncodeVByteTo for i8 {
544    fn encode_vbyte_to<T: MutBits + ?Sized>(&self, out: &mut T) -> Result<usize, BitsError> {
545        encode_integer_to(IntegerValue::I8(*self), out)
546    }
547}
548cfg_feature_alloc! {
549    pub fn encode_integer(val: IntegerValue) -> alloc::boxed::Box<[u8]> {
550        use alloc::boxed::Box;
551        match val {
552            IntegerValue::U8(v) => {
553                if v <= one_byte_mask!() {
554                    Box::new(encode_7bits(v))
555                } else {
556                    Box::new(encode_8bits(v))
557                }
558            }
559            IntegerValue::U16(v) => {
560                if v <= one_byte_mask!() {
561                    Box::new(encode_7bits(v as u8))
562                } else if v <= two_byte_mask!() {
563                    Box::new(encode_14bits(v))
564                } else {
565                    Box::new(encode_16bits(v))
566                }
567            }
568            IntegerValue::U32(v) => {
569                if v <= one_byte_mask!() {
570                    Box::new(encode_7bits(v as u8))
571                } else if v <= two_byte_mask!() {
572                    Box::new(encode_14bits(v as u16))
573                } else if v <= three_byte_mask!() {
574                    Box::new(encode_21bits(v))
575                } else if v <= four_byte_mask!() {
576                    Box::new(encode_28bits(v))
577                } else {
578                    Box::new(encode_32bits(v))
579                }
580            }
581            IntegerValue::U64(v) => {
582                if v <= one_byte_mask!() {
583                    Box::new(encode_7bits(v as u8))
584                } else if v <= two_byte_mask!() {
585                    Box::new(encode_14bits(v as u16))
586                } else if v <= three_byte_mask!() {
587                    Box::new(encode_21bits(v as u32))
588                } else if v <= four_byte_mask!() {
589                    Box::new(encode_28bits(v as u32))
590                } else if v <= five_byte_mask!() {
591                    Box::new(encode_35bits(v))
592                } else if v <= six_byte_mask!() {
593                    Box::new(encode_42bits(v))
594                } else if v <= seven_byte_mask!() {
595                    Box::new(encode_49bits(v))
596                } else if v <= eight_byte_mask!() {
597                    Box::new(encode_56bits(v))
598                } else if v <= nine_byte_mask!() {
599                    Box::new(encode_63bits(v))
600                } else {
601                    Box::new(encode_64bits(v))
602                }
603            }
604            // IntegerValue::U128(_) => {}
605            // IntegerValue::I8(_) => {}
606            // IntegerValue::I16(_) => {}
607            // IntegerValue::I32(_) => {}
608            // IntegerValue::I64(_) => {}
609            // IntegerValue::I128(_) => {}
610            _ => {
611                todo!()
612            }
613        }
614    }
615}
616
617pub const fn resultant_length(value: IntegerValue) -> u8 {
618    let v = value.to_be_u64();
619    match v {
620        0x0000_0000_0000_0000..=0x0000_0000_0000_007F => 1,
621        0x0000_0000_0000_0080..=0x0000_0000_0000_3FFF => 2,
622        0x0000_0000_0000_4000..=0x0000_0000_001F_FFFF => 3,
623        0x0000_0000_0020_0000..=0x0000_0000_0FFF_FFFF => 4,
624        0x0000_0000_1000_0000..=0x0000_0007_FFFF_FFFF => 5,
625        0x0000_0008_0000_0000..=0x0000_03FF_FFFF_FFFF => 6,
626        0x0000_0400_0000_0000..=0x0001_FFFF_FFFF_FFFF => 7,
627        0x0002_0000_0000_0000..=0x00FF_FFFF_FFFF_FFFF => 8,
628        0x0100_0000_0000_0000..=0x7FFF_FFFF_FFFF_FFFF => 9,
629        _ => 10,
630    }
631}
632cfg_feature_alloc! {
633    extern crate alloc;
634    pub trait EncodeVByte {
635        fn encode_vbyte(&self) -> alloc::boxed::Box<[u8]>;
636    }
637}
638pub trait EncodeVByteLength {
639    fn vbyte_length(&self) -> u8;
640}
641impl<T> EncodeVByteLength for T
642where
643    T: Into<IntegerValue> + Copy,
644{
645    fn vbyte_length(&self) -> u8 {
646        resultant_length(Into::<IntegerValue>::into(*self))
647    }
648}
649cfg_feature_alloc! {
650    macro_rules! impl_encode {
651        ($typ:ty) => {
652            impl crate::codec::vbyte::EncodeVByte for $typ {
653                fn encode_vbyte(&self) -> alloc::boxed::Box<[u8]> {
654                    crate::codec::vbyte::encode_integer(self.into())
655                }
656            }
657            // impl EncodeVByte for [$typ] {
658            //     fn encode_vbyte(&self) -> Box<[u8]> {
659            //         crate::vbyte::encode(self.into())
660            //     }
661            // }
662            impl EncodeVByte for &$typ {
663                fn encode_vbyte(&self) -> alloc::boxed::Box<[u8]> {
664                    let v: IntegerValue = (*self).into();
665                    crate::codec::vbyte::encode_integer(v)
666                }
667            }
668            // impl EncodeVByte for &mut $typ {
669            //     fn encode_vbyte(&self) -> Box<[u8]> {
670            //         let v : IntegerValue = (*self).into();
671            //         crate::codec::vbyte::encode_integer(v)
672            //     }
673            // }
674        };
675    }
676
677    impl_encode!(u8);
678    impl_encode!(i8);
679    impl_encode!(u16);
680    impl_encode!(i16);
681    impl_encode!(u32);
682    impl_encode!(i32);
683    impl_encode!(u64);
684    impl_encode!(i64);
685}
686
687pub trait DecodeVByte {
688    fn decode_vbyte(&mut self) -> Result<u128, Error>;
689}
690
691pub fn decode_vbyte<T: Bits>(inp: &mut T) -> Result<u128, Error> {
692    let mut out: u128 = 0;
693    while let Some(val) = inp.next_u8()? {
694        let v = (val & 0x7F) as u128;
695        out = (out << 7) | v;
696        if val & 0x80 == 0 {
697            break;
698        }
699    }
700    Ok(out)
701}
702
703impl<T: Bits> DecodeVByte for T {
704    fn decode_vbyte(&mut self) -> Result<u128, Error> {
705        decode_vbyte(self)
706    }
707}
708
709#[cfg(all(test, feature = "alloc"))]
710mod tests {
711    use crate::codec::vbyte::{DecodeVByte, EncodeVByte};
712    use crate::codec::EncodeVByteLength;
713    use irox_bits::Error;
714
715    #[test]
716    pub fn test_encode() {
717        assert_eq!(0x00u8.encode_vbyte().as_ref(), &[0x00]);
718        assert_eq!(0x7Fu8.encode_vbyte().as_ref(), &[0x7F]);
719        assert_eq!(0x80u8.encode_vbyte().as_ref(), &[0x81, 0x00]);
720        assert_eq!(0x2000u16.encode_vbyte().as_ref(), &[0xC0, 0x00]);
721        assert_eq!(0x3FFFu16.encode_vbyte().as_ref(), &[0xFF, 0x7F]);
722        assert_eq!(0x4000u16.encode_vbyte().as_ref(), &[0x81, 0x80, 0x00]);
723        assert_eq!(0x1F_FFFFu32.encode_vbyte().as_ref(), &[0xFF, 0xFF, 0x7F]);
724        assert_eq!(
725            0x20_0000u32.encode_vbyte().as_ref(),
726            &[0x81, 0x80, 0x80, 0x00]
727        );
728        assert_eq!(
729            0x800_0000u32.encode_vbyte().as_ref(),
730            &[0xC0, 0x80, 0x80, 0x00]
731        );
732        assert_eq!(
733            0xFFF_FFFFu32.encode_vbyte().as_ref(),
734            &[0xFF, 0xFF, 0xFF, 0x7F]
735        );
736    }
737
738    #[test]
739    pub fn test_decode() -> Result<(), Error> {
740        assert_eq_hex!(0x0, [0x0].as_ref().decode_vbyte()?);
741        assert_eq_hex!(0x7F, [0x7F].as_ref().decode_vbyte()?);
742        assert_eq_hex!(0x80, [0x81, 0x00].as_ref().decode_vbyte()?);
743        assert_eq_hex!(0x2000, [0xC0, 0x00].as_ref().decode_vbyte()?);
744        assert_eq_hex!(0x3FFF, [0xFF, 0x7F].as_ref().decode_vbyte()?);
745        assert_eq_hex!(0x4000, [0x81, 0x80, 0x00].as_ref().decode_vbyte()?);
746        assert_eq_hex!(0x1F_FFFF, [0xFF, 0xFF, 0x7F].as_ref().decode_vbyte()?);
747        assert_eq_hex!(
748            0x800_0000,
749            [0xC0, 0x80, 0x80, 0x00].as_ref().decode_vbyte()?
750        );
751        assert_eq_hex!(
752            0xFFF_FFFF,
753            [0xFF, 0xFF, 0xFF, 0x7F].as_ref().decode_vbyte()?
754        );
755
756        Ok(())
757    }
758
759    #[test]
760    pub fn test_vbyte_length() -> Result<(), Error> {
761        assert_eq!(2, 0xCC.vbyte_length());
762        assert_eq!(3, 0xAAAA.vbyte_length());
763        Ok(())
764    }
765}