use bytes::{Buf, BufMut}; use thiserror::Error; use crate::VarLongType; #[derive(Debug, Clone, PartialEq, Eq)] pub struct VarLong(pub VarLongType); impl VarLong { /// The maximum number of bytes a `VarLong` pub const MAX_SIZE: usize = 10; /// Returns the exact number of bytes this varlong will write when /// [`Encode::encode`] is called, assuming no error occurs. pub const fn written_size(self) -> usize { match self.0 { 0 => 1, n => (31 - n.leading_zeros() as usize) / 7 + 1, } } pub fn encode(&self, w: &mut impl BufMut) { let mut x = self.0; for _ in 0..Self::MAX_SIZE { let byte = (x & 0x7F) as u8; x >>= 7; if x == 0 { w.put_slice(&[byte]); break; } w.put_slice(&[byte | 0x80]); } } pub fn decode(r: &mut impl Buf) -> Result { let mut val = 0; for i in 0..Self::MAX_SIZE { if !r.has_remaining() { return Err(VarLongDecodeError::Incomplete); } let byte = r.get_u8(); val |= (i64::from(byte) & 0b01111111) << (i * 7); if byte & 0b10000000 == 0 { return Ok(VarLong(val)); } } Err(VarLongDecodeError::TooLarge) } } impl From for VarLong { fn from(value: i64) -> Self { VarLong(value) } } impl From for VarLong { fn from(value: u32) -> Self { VarLong(value as i64) } } impl From for VarLong { fn from(value: u8) -> Self { VarLong(value as i64) } } impl From for VarLong { fn from(value: usize) -> Self { VarLong(value as i64) } } impl From for i64 { fn from(value: VarLong) -> Self { value.0 } } #[derive(Copy, Clone, PartialEq, Eq, Debug, Error)] pub enum VarLongDecodeError { #[error("incomplete VarLong decode")] Incomplete, #[error("VarLong is too large")] TooLarge, }