From d34b3eb3f70ec14ddbdfae30b1f7c4265dbf922d Mon Sep 17 00:00:00 2001 From: Liyan Zhao Date: Thu, 10 Jul 2025 16:52:28 +0800 Subject: [PATCH] Macroize serde (#1029) * macroize serde * fix --- pumpkin-nbt/src/deserializer.rs | 95 +++++--------------- pumpkin-nbt/src/serializer.rs | 68 +++++--------- pumpkin-protocol/src/ser/mod.rs | 153 ++++++++------------------------ 3 files changed, 81 insertions(+), 235 deletions(-) diff --git a/pumpkin-nbt/src/deserializer.rs b/pumpkin-nbt/src/deserializer.rs index 7859ef3ec..2eff84378 100644 --- a/pumpkin-nbt/src/deserializer.rs +++ b/pumpkin-nbt/src/deserializer.rs @@ -16,6 +16,19 @@ impl NbtReadHelper { } } +macro_rules! define_get_number_be { + ($name:ident, $type:ty) => { + pub fn $name(&mut self) -> Result<$type> { + let mut buf = [0u8; std::mem::size_of::<$type>()]; + self.reader + .read_exact(&mut buf) + .map_err(Error::Incomplete)?; + + Ok(<$type>::from_be_bytes(buf)) + } + }; +} + impl NbtReadHelper { pub fn skip_bytes(&mut self, count: u64) -> Result<()> { let _ = io::copy(&mut self.reader.by_ref().take(count), &mut io::sink()) @@ -23,78 +36,16 @@ impl NbtReadHelper { Ok(()) } - //TODO: Macroize this - pub fn get_u8_be(&mut self) -> Result { - let mut buf = [0u8]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(u8::from_be_bytes(buf)) - } - - pub fn get_i8_be(&mut self) -> Result { - let mut buf = [0u8]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(i8::from_be_bytes(buf)) - } - - pub fn get_i16_be(&mut self) -> Result { - let mut buf = [0u8; 2]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(i16::from_be_bytes(buf)) - } - - pub fn get_u16_be(&mut self) -> Result { - let mut buf = [0u8; 2]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(u16::from_be_bytes(buf)) - } - - pub fn get_i32_be(&mut self) -> Result { - let mut buf = [0u8; 4]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(i32::from_be_bytes(buf)) - } - - pub fn get_i64_be(&mut self) -> Result { - let mut buf = [0u8; 8]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(i64::from_be_bytes(buf)) - } - - pub fn get_f32_be(&mut self) -> Result { - let mut buf = [0u8; 4]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(f32::from_be_bytes(buf)) - } - - pub fn get_f64_be(&mut self) -> Result { - let mut buf = [0u8; 8]; - self.reader - .read_exact(&mut buf) - .map_err(Error::Incomplete)?; - - Ok(f64::from_be_bytes(buf)) - } + define_get_number_be!(get_u8_be, u8); + define_get_number_be!(get_i8_be, i8); + define_get_number_be!(get_u16_be, u16); + define_get_number_be!(get_i16_be, i16); + define_get_number_be!(get_u32_be, u32); + define_get_number_be!(get_i32_be, i32); + define_get_number_be!(get_u64_be, u64); + define_get_number_be!(get_i64_be, i64); + define_get_number_be!(get_f32_be, f32); + define_get_number_be!(get_f64_be, f64); pub fn read_boxed_slice(&mut self, count: usize) -> Result> { let mut buf = vec![0u8; count]; diff --git a/pumpkin-nbt/src/serializer.rs b/pumpkin-nbt/src/serializer.rs index 9257635b0..fb3e4f482 100644 --- a/pumpkin-nbt/src/serializer.rs +++ b/pumpkin-nbt/src/serializer.rs @@ -22,55 +22,27 @@ impl WriteAdaptor { } } +macro_rules! write_number_be { + ($name:ident, $type:ty) => { + pub fn $name(&mut self, value: $type) -> Result<()> { + let buf = value.to_be_bytes(); + self.writer.write_all(&buf).map_err(Error::Incomplete)?; + Ok(()) + } + }; +} + impl WriteAdaptor { - //TODO: Macroize this - pub fn write_u8_be(&mut self, value: u8) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } - - pub fn write_i8_be(&mut self, value: i8) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } - - pub fn write_u16_be(&mut self, value: u16) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } - - pub fn write_i16_be(&mut self, value: i16) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } - - pub fn write_i32_be(&mut self, value: i32) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } - - pub fn write_i64_be(&mut self, value: i64) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } - - pub fn write_f32_be(&mut self, value: f32) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } - - pub fn write_f64_be(&mut self, value: f64) -> Result<()> { - let buf = value.to_be_bytes(); - self.writer.write_all(&buf).map_err(Error::Incomplete)?; - Ok(()) - } + write_number_be!(write_u8_be, u8); + write_number_be!(write_i8_be, i8); + write_number_be!(write_u16_be, u16); + write_number_be!(write_i16_be, i16); + write_number_be!(write_u32_be, u32); + write_number_be!(write_i32_be, i32); + write_number_be!(write_u64_be, u64); + write_number_be!(write_i64_be, i64); + write_number_be!(write_f32_be, f32); + write_number_be!(write_f64_be, f64); pub fn write_slice(&mut self, value: &[u8]) -> Result<()> { self.writer.write_all(value).map_err(Error::Incomplete)?; diff --git a/pumpkin-protocol/src/ser/mod.rs b/pumpkin-protocol/src/ser/mod.rs index ce4651b6e..d0d2ebf57 100644 --- a/pumpkin-protocol/src/ser/mod.rs +++ b/pumpkin-protocol/src/ser/mod.rs @@ -85,6 +85,17 @@ pub trait NetworkReadExt { ) -> Result, ReadingError>; } +macro_rules! get_number_be { + ($name:ident, $type:ty) => { + fn $name(&mut self) -> Result<$type, ReadingError> { + let mut buf = [0u8; std::mem::size_of::<$type>()]; + self.read_exact(&mut buf) + .map_err(|err| ReadingError::Incomplete(err.to_string()))?; + Ok(<$type>::from_be_bytes(buf)) + } + }; +} + impl NetworkReadExt for R { //TODO: Macroize this fn get_i8(&mut self) -> Result { @@ -103,86 +114,20 @@ impl NetworkReadExt for R { Ok(buf[0]) } - fn get_i16_be(&mut self) -> Result { - let mut buf = [0u8; 2]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(i16::from_be_bytes(buf)) - } - - fn get_u16_be(&mut self) -> Result { - let mut buf = [0u8; 2]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(u16::from_be_bytes(buf)) - } - fn get_u24(&mut self) -> Result { U24::decode(self) } - fn get_i32_be(&mut self) -> Result { - let mut buf = [0u8; 4]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(i32::from_be_bytes(buf)) - } - - fn get_u32_be(&mut self) -> Result { - let mut buf = [0u8; 4]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(u32::from_be_bytes(buf)) - } - - fn get_i64_be(&mut self) -> Result { - let mut buf = [0u8; 8]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(i64::from_be_bytes(buf)) - } - - fn get_u64_be(&mut self) -> Result { - let mut buf = [0u8; 8]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(u64::from_be_bytes(buf)) - } - fn get_f32_be(&mut self) -> Result { - let mut buf = [0u8; 4]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(f32::from_be_bytes(buf)) - } - - fn get_f64_be(&mut self) -> Result { - let mut buf = [0u8; 8]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - - Ok(f64::from_be_bytes(buf)) - } - - fn get_i128_be(&mut self) -> Result { - let mut buf = [0u8; 16]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - Ok(i128::from_be_bytes(buf)) - } - - fn get_u128_be(&mut self) -> Result { - let mut buf = [0u8; 16]; - self.read_exact(&mut buf) - .map_err(|err| ReadingError::Incomplete(err.to_string()))?; - Ok(u128::from_be_bytes(buf)) - } + get_number_be!(get_i16_be, i16); + get_number_be!(get_u16_be, u16); + get_number_be!(get_i32_be, i32); + get_number_be!(get_u32_be, u32); + get_number_be!(get_i64_be, i64); + get_number_be!(get_u64_be, u64); + get_number_be!(get_i128_be, i128); + get_number_be!(get_u128_be, u128); + get_number_be!(get_f32_be, f32); + get_number_be!(get_f64_be, f64); fn read_boxed_slice(&mut self, count: usize) -> Result, ReadingError> { let mut buf = vec![0u8; count]; @@ -362,6 +307,15 @@ pub trait NetworkWriteExt { fn write_nbt(&mut self, data: &NbtTag) -> Result<(), WritingError>; } +macro_rules! write_number_be { + ($name:ident, $type:ty) => { + fn $name(&mut self, data: $type) -> Result<(), WritingError> { + self.write_all(&data.to_be_bytes()) + .map_err(WritingError::IoError) + } + }; +} + impl NetworkWriteExt for W { fn write_i8(&mut self, data: i8) -> Result<(), WritingError> { self.write_all(&data.to_be_bytes()) @@ -373,49 +327,18 @@ impl NetworkWriteExt for W { .map_err(WritingError::IoError) } - fn write_i16_be(&mut self, data: i16) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } - - fn write_u16_be(&mut self, data: u16) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } - fn write_u24_be(&mut self, data: U24) -> Result<(), WritingError> { data.encode(self) } - fn write_i32_be(&mut self, data: i32) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } - - fn write_u32_be(&mut self, data: u32) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } - - fn write_i64_be(&mut self, data: i64) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } - - fn write_u64_be(&mut self, data: u64) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } - - fn write_f32_be(&mut self, data: f32) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } - - fn write_f64_be(&mut self, data: f64) -> Result<(), WritingError> { - self.write_all(&data.to_be_bytes()) - .map_err(WritingError::IoError) - } + write_number_be!(write_i16_be, i16); + write_number_be!(write_u16_be, u16); + write_number_be!(write_i32_be, i32); + write_number_be!(write_u32_be, u32); + write_number_be!(write_i64_be, i64); + write_number_be!(write_u64_be, u64); + write_number_be!(write_f32_be, f32); + write_number_be!(write_f64_be, f64); fn write_slice(&mut self, data: &[u8]) -> Result<(), WritingError> { self.write_all(data).map_err(WritingError::IoError)