1
2use crate::error::Error;
3use crate::traits::{VarInt, VarIntOps};
4
5pub fn encode<T: VarInt>(value: T, buf: &mut [u8]) -> Result<usize, Error> {
16 let mut val = value.to_unsigned();
17 let needed_size = value.varint_size();
18
19 if buf.len() < needed_size {
20 return Err(Error::BufferTooSmall {
21 needed: needed_size,
22 actual: buf.len(),
23 });
24 }
25
26 let mut i = 0;
27 while val.needs_another_byte() && i < buf.len() - 1 {
28 buf[i] = val.get_byte_with_continuation();
29 val = val.shift_right_7();
30 i += 1;
31 }
32
33 if i < buf.len() {
34 buf[i] = val.get_final_byte();
35 Ok(i + 1)
36 } else {
37 Err(Error::BufferTooSmall {
38 needed: i + 1,
39 actual: buf.len(),
40 })
41 }
42}
43
44pub fn decode<T: VarInt>(buf: &[u8]) -> Result<(T, usize), Error> {
56 let mut result = T::Unsigned::from_byte(0, 0);
57 let mut shift = 0;
58 let mut i = 0;
59
60 loop {
61 if i >= buf.len() {
62 return Err(Error::InputTooShort);
63 }
64
65 let byte = buf[i];
66 i += 1;
67
68 result = result.bitor(T::Unsigned::from_byte(byte & 0x7F, shift));
69
70 if byte & 0x80 == 0 {
72 break;
73 }
74
75 shift += 1;
76
77 if shift >= T::Unsigned::BITS / 7 + 1 {
79 return Err(Error::Overflow);
80 }
81 }
82
83 Ok((T::from_unsigned(result), i))
84}
85
86#[inline(always)]
91pub fn varint_size<T: VarInt>(value: T) -> usize {
92 value.varint_size()
93}