use spacetimedb_sats::buffer::{BufReader, BufWriter, DecodeError};
#[inline]
pub fn encode_varint(mut value: usize, out: &mut impl BufWriter) {
loop {
if value < 0x80 {
out.put_u8(value as u8);
break;
} else {
out.put_u8(((value & 0x7f) | 0x80) as u8);
value >>= 7;
}
}
}
#[inline]
pub fn decode_varint<'a>(reader: &mut impl BufReader<'a>) -> Result<usize, DecodeError> {
let mut result = 0;
let mut shift = 0;
loop {
let byte = reader.get_u8()?;
if (byte & 0x80) == 0 {
result |= (byte as usize) << shift;
return Ok(result);
} else {
result |= ((byte & 0x7F) as usize) << shift;
}
shift += 7;
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn varint_roundtrip(val in any::<usize>()) {
let mut buf = Vec::new();
encode_varint(val, &mut buf);
assert_eq!(val, decode_varint(&mut buf.as_slice()).unwrap());
}
}
}