pub(crate) trait TryMCType: std::marker::Sized { fn read(bytes: &mut impl Iterator) -> Option; fn try_write(&self) -> Option>; } pub(crate) trait MCType: TryMCType { fn write(&self) -> Vec { self.try_write().unwrap() } } pub(crate) struct VarIntMarker {} pub(crate) trait VarInt: std::marker::Sized {} impl VarInt for i32 {} impl TryMCType for i32 where i32: VarInt, { fn read(bytes: &mut impl Iterator) -> Option { let mut num_read: usize = 0; let mut result = 0u32; while { let read = bytes.next()? as u32; let value = read & 0b01111111; result |= value << (7 * num_read); num_read += 1; if num_read > 5 { return None; } (read & 0b10000000) != 0 } {} Some(i32::from_be_bytes(result.to_be_bytes())) } fn try_write(&self) -> Option> { let mut res_vec: Vec = vec![]; let mut value = u32::from_be_bytes(self.to_be_bytes()); while { let mut temp = (value & 0b01111111) as u8; value >>= 7; if value != 0 { temp |= 0b10000000; } res_vec.push(temp); value != 0 } {} Some(res_vec) } } impl MCType for i32 {} pub(crate) trait FixedInt: std::marker::Sized {} impl FixedInt for i32 {} impl TryMCType for i32 where i32: FixedInt, { fn read(_bytes: &mut impl Iterator) -> Option { unimplemented!() } fn try_write(&self) -> Option> { unimplemented!() } } impl MCType for i32 {} impl TryMCType for String { fn read(bytes: &mut impl Iterator) -> Option { let length = >::read(bytes)? as usize; let mut res = Vec::::with_capacity(length); for _ in 0..length { res.push(bytes.next().unwrap()); } Some(String::from_utf8(res).unwrap()) } fn try_write(&self) -> Option> { if self.len() > 32767 { return None; } let len = self.len(); let mut res = MCType::::write(&(len as i32)); res.extend_from_slice( self.as_bytes() .iter() .copied() .collect::>() .as_slice(), ); Some(res) } } impl TryMCType for u16 { fn read(bytes: &mut impl Iterator) -> Option { let a = bytes.next()?; let b = bytes.next()?; Some(u16::from_be_bytes([a, b])) } fn try_write(&self) -> Option> { Some(u16::to_be_bytes(*self).to_vec()) } } impl MCType for u16 {} impl TryMCType for i64 { fn read(bytes: &mut impl Iterator) -> Option { let mut v = vec![]; for _ in 0..8 { v.push(bytes.next()?); } Some(i64::from_be_bytes([ v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], ])) } fn try_write(&self) -> Option> { Some(i64::to_be_bytes(*self).to_vec()) } } impl MCType for i64 {} #[cfg(test)] mod tests { use crate::types::*; #[test] fn basic_read_var_int() { assert_eq!( >::read(&mut [0x00].iter().copied()).unwrap(), 0 ); assert_eq!( >::read(&mut [0x01].iter().copied()).unwrap(), 1 ); assert_eq!( >::read(&mut [0x02].iter().copied()).unwrap(), 2 ); assert_eq!( >::read(&mut [0x7f].iter().copied()).unwrap(), 127 ); assert_eq!( >::read(&mut [0x80, 0x01].iter().copied()).unwrap(), 128 ); assert_eq!( >::read(&mut [0xff, 0x01].iter().copied()).unwrap(), 255 ); assert_eq!( >::read( &mut [0xff, 0xff, 0xff, 0xff, 0x07].iter().copied() ) .unwrap(), 2147483647 ); assert_eq!( >::read( &mut [0xff, 0xff, 0xff, 0xff, 0x0f].iter().copied() ) .unwrap(), -1 ); assert_eq!( >::read( &mut [0x80, 0x80, 0x80, 0x80, 0x08].iter().copied() ) .unwrap(), -2147483648 ); } }