1use crate::{CONTINUE_BIT, SEGMENT_BITS, read_byte};
2use std::io::{self, Cursor, Write};
3
4pub trait VarInt {
6 fn read_varint(buffer: &mut Cursor<&[u8]>) -> Option<i32>;
8
9 fn write_varint(&self, buffer: &mut impl Write) -> io::Result<()>;
11}
12
13impl VarInt for i32 {
14 fn read_varint(buffer: &mut Cursor<&[u8]>) -> Option<i32> {
15 let mut value = 0i32;
16 let mut position = 0u32;
17
18 loop {
19 let byte = read_byte(buffer)?;
20 value |= (((byte & SEGMENT_BITS) as u32) << position) as i32;
21
22 if (byte & CONTINUE_BIT) == 0 {
23 break;
24 }
25
26 position += 7;
27
28 if position >= 32 {
29 return None;
30 }
31 }
32
33 Some(value)
34 }
35
36 fn write_varint(&self, buffer: &mut impl Write) -> io::Result<()> {
37 let mut array = [0];
38 let mut value = *self;
39
40 if value == 0 {
41 buffer.write_all(&array)?;
42 return Ok(());
43 }
44
45 while value != 0 {
46 array[0] = (value & SEGMENT_BITS as i32) as u8;
47 value = (value >> 7) & (i32::MAX >> 6);
48
49 if value != 0 {
50 array[0] |= CONTINUE_BIT;
51 }
52
53 buffer.write_all(&array)?;
54 }
55
56 Ok(())
57 }
58}