steel_utils/codec/
var_uint.rs1use std::io::{Cursor, Error, Write};
2
3use crate::serial::{ReadFrom, WriteTo};
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct VarUint(pub u32);
8
9impl VarUint {
10 const MAX_SIZE: usize = 5;
11
12 #[must_use]
15 pub const fn written_size(self) -> usize {
16 (32 - self.0.leading_zeros() as usize).max(1).div_ceil(7)
17 }
18
19 pub fn write(self, writer: &mut impl Write) -> Result<(), Error> {
24 let mut val = self.0;
25 loop {
26 let mut byte = (val & 0x7F) as u8;
27 val >>= 7;
28 if val != 0 {
29 byte |= 0x80;
30 }
31 byte.write(writer)?;
32 if val == 0 {
33 break;
34 }
35 }
36 Ok(())
37 }
38
39 pub fn read(read: &mut Cursor<&[u8]>) -> Result<u32, Error> {
44 let mut val = 0;
45 for i in 0..Self::MAX_SIZE {
46 let byte = u8::read(read)?;
47 val |= (u32::from(byte) & 0x7F) << (i * 7);
48 if byte & 0x80 == 0 {
49 return Ok(val);
50 }
51 }
52 Err(Error::other("Malformed VarUint"))
53 }
54}