From 5e5de970f2a57671d3d7bdcdf7509c7b263a3419 Mon Sep 17 00:00:00 2001 From: JieningYu Date: Mon, 22 Jan 2024 21:09:31 +0800 Subject: [PATCH 1/3] edcode refactorings --- util/edcode/Cargo.toml | 1 - util/edcode/src/error.rs | 72 ++++++ util/edcode/src/imp.rs | 472 ++++++++++++--------------------------- util/edcode/src/lib.rs | 40 ++-- util/event/src/lib.rs | 8 +- 5 files changed, 241 insertions(+), 352 deletions(-) create mode 100644 util/edcode/src/error.rs diff --git a/util/edcode/Cargo.toml b/util/edcode/Cargo.toml index 46f1d82..7a4b670 100644 --- a/util/edcode/Cargo.toml +++ b/util/edcode/Cargo.toml @@ -12,7 +12,6 @@ categories = ["encoding"] maintenance = { status = "passively-maintained" } [dependencies] -anyhow = "1.0" bytes = "1.5" serde = { version = "1.0", optional = true } # custom formats diff --git a/util/edcode/src/error.rs b/util/edcode/src/error.rs new file mode 100644 index 0000000..54d3b89 --- /dev/null +++ b/util/edcode/src/error.rs @@ -0,0 +1,72 @@ +#[derive(Debug)] +pub struct VarI32TooBigError; + +impl std::fmt::Display for VarI32TooBigError { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "variable i32 too big") + } +} + +impl std::error::Error for VarI32TooBigError {} + +#[derive(Debug)] +pub enum ErrorWithVarI32Len { + Target(T), + Len(VarI32TooBigError), +} + +impl std::fmt::Display for ErrorWithVarI32Len { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ErrorWithVarI32Len::Target(e) => write!(f, "{}", e), + ErrorWithVarI32Len::Len(e) => write!(f, "variable length error: {}", e), + } + } +} + +impl std::error::Error for ErrorWithVarI32Len { + #[inline] + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + ErrorWithVarI32Len::Target(e) => Some(e), + ErrorWithVarI32Len::Len(e) => Some(e), + } + } +} + +impl From for ErrorWithVarI32Len { + #[inline] + fn from(value: VarI32TooBigError) -> Self { + Self::Len(value) + } +} + +#[derive(Debug)] +pub enum KvError { + Key(K), + Value(V), +} + +impl std::fmt::Display for KvError { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + KvError::Key(e) => write!(f, "key error: {}", e), + KvError::Value(e) => write!(f, "value error: {}", e), + } + } +} + +impl std::error::Error + for KvError +{ + #[inline] + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + KvError::Key(e) => Some(e), + KvError::Value(e) => Some(e), + } + } +} diff --git a/util/edcode/src/imp.rs b/util/edcode/src/imp.rs index aba9d96..753430e 100644 --- a/util/edcode/src/imp.rs +++ b/util/edcode/src/imp.rs @@ -1,10 +1,12 @@ -use std::hash::Hash; +use std::{convert::Infallible, hash::Hash, string::FromUtf8Error}; -use super::*; +use crate::{error::*, *}; impl Encode for bytes::Bytes { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -17,8 +19,10 @@ impl Encode for bytes::Bytes { impl<'de> Decode<'de> for bytes::Bytes { type Output = bytes::Bytes; + type Error = VarI32TooBigError; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -27,285 +31,50 @@ impl<'de> Decode<'de> for bytes::Bytes { } } -impl Encode for u8 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_u8(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for u8 { - type Output = u8; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_u8()) - } -} - -impl Encode for i8 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_i8(*self); - Ok(()) - } -} +macro_rules! edcode_primitive { + ($($t:ty => $fe:ident, $fd:ident),*) => { + $( + impl Encode for $t { + type Error = Infallible; -impl<'de> Decode<'de> for i8 { - type Output = i8; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_i8()) - } -} - -impl Encode for u16 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_u16(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for u16 { - type Output = u16; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_u16()) - } -} - -impl Encode for i16 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_i16(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for i16 { - type Output = i16; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_i16()) - } -} - -impl Encode for u32 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_u32(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for u32 { - type Output = u32; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_u32()) - } -} - -impl Encode for i32 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_i32(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for i32 { - type Output = i32; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_i32()) - } -} - -impl Encode for u64 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_u64(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for u64 { - type Output = u64; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_u64()) - } -} - -impl Encode for i64 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_i64(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for i64 { - type Output = i64; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_i64()) - } -} - -impl Encode for u128 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_u128(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for u128 { - type Output = u128; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_u128()) - } -} - -impl Encode for i128 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_i128(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for i128 { - type Output = i128; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_i128()) - } -} - -impl Encode for f32 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_f32(*self); - Ok(()) - } -} - -impl<'de> Decode<'de> for f32 { - type Output = f32; + #[inline] + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> { + buf.$fe(*self); + Ok(()) + } + } - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_f32()) - } -} + impl<'de> Decode<'de> for $t { + type Output = $t; + type Error = Infallible; -impl Encode for f64 { - #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> - where - B: bytes::BufMut, - { - buf.put_f64(*self); - Ok(()) - } + #[inline] + fn decode(buf: &'de mut B) -> Result{ + Ok(buf.$fd()) + } + } + )* + }; } -impl<'de> Decode<'de> for f64 { - type Output = f64; - - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_f64()) - } +edcode_primitive! { + u8 => put_u8, get_u8, + u16 => put_u16, get_u16, + u32 => put_u32, get_u32, + u64 => put_u64, get_u64, + i8 => put_i8, get_i8, + i16 => put_i16, get_i16, + i32 => put_i32, get_i32, + i64 => put_i64, get_i64, + f32 => put_f32, get_f32, + f64 => put_f64, get_f64 } impl Encode for bool { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -317,8 +86,10 @@ impl Encode for bool { impl<'de> Decode<'de> for bool { type Output = bool; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -331,8 +102,10 @@ impl Encode for Nbt<'_, T> where T: serde::Serialize, { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -365,8 +138,10 @@ where { type Output = T; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -391,8 +166,10 @@ impl Encode for Json<'_, T> where T: serde::Serialize, { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -407,7 +184,7 @@ where { type Output = T; - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -423,7 +200,9 @@ where } impl Encode for VarI32 { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = Infallible; + + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -446,7 +225,9 @@ impl Encode for VarI32 { impl<'de> Decode<'de> for VarI32 { type Output = i32; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = VarI32TooBigError; + + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -464,15 +245,17 @@ impl<'de> Decode<'de> for VarI32 { pos += 7; if pos >= 32 { - return Err(anyhow::anyhow!("VarI32 too big")); + return Err(VarI32TooBigError); } } } } impl Encode for str { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -484,8 +267,10 @@ impl Encode for str { } impl Encode for String { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -496,18 +281,16 @@ impl Encode for String { impl<'de> Decode<'de> for String { type Output = String; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = ErrorWithVarI32Len; + + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { let len = VarI32::decode(buf)? as usize; - let mut vec = Vec::with_capacity(len); - - for _ in 0..len { - vec.push(buf.get_u8()); - } - - Ok(String::from_utf8(vec)?) + let mut vec = vec![0; len]; + buf.copy_to_slice(&mut vec[..]); + Ok(String::from_utf8(vec).map_err(ErrorWithVarI32Len::Target)?) } } @@ -515,35 +298,38 @@ impl Encode for [T] where T: Encode, { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = ::Error; + + #[inline] + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { - VarI32(self.len() as i32).encode(buf)?; - + VarI32(self.len() as i32).encode(buf).unwrap(); for object in self.iter() { object.encode(buf)?; } - Ok(()) } } -impl<'de, T, O> Decode<'de> for Vec +impl<'de, T, O, Err> Decode<'de> for Vec where - T: for<'a> Decode<'a, Output = O>, + T: for<'a> Decode<'a, Output = O, Error = Err>, { type Output = Vec; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = ErrorWithVarI32Len; + + fn decode(mut buf: &'de mut B) -> Result where B: bytes::Buf, { - let len = VarI32::decode(buf)? as usize; + let len = VarI32::decode(&mut buf)? as usize; let mut vec = Vec::with_capacity(len); for _ in 0..len { - vec.push(T::decode(buf)?); + vec.push(T::decode(&mut buf).map_err(ErrorWithVarI32Len::Target)?); } Ok(vec) @@ -555,42 +341,43 @@ where K: Encode, V: Encode, { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = KvError<::Error, ::Error>; + + #[inline] + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { - VarI32(self.len() as i32).encode(buf)?; - + VarI32(self.len() as i32).encode(buf).unwrap(); for (key, value) in self.iter() { - key.encode(buf)?; - value.encode(buf)?; + key.encode(buf).map_err(KvError::Key)?; + value.encode(buf).map_err(KvError::Value)?; } - Ok(()) } } -impl<'de, K, V, OK, OV> Decode<'de> for std::collections::HashMap +impl<'de, K, V, OK, OV, ErrK, ErrV> Decode<'de> for std::collections::HashMap where - K: for<'a> Decode<'a, Output = OK>, - V: for<'a> Decode<'a, Output = OV>, + K: for<'a> Decode<'a, Output = OK, Error = ErrK>, + V: for<'a> Decode<'a, Output = OV, Error = ErrV>, OK: Hash + Eq, { type Output = std::collections::HashMap; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = ErrorWithVarI32Len>; + + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { let len = VarI32::decode(buf)? as usize; let mut map = std::collections::HashMap::with_capacity(len); - for _ in 0..len { - let obj = K::decode(buf)?; - let obj1 = V::decode(buf)?; + let obj = K::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(KvError::Key(e)))?; + let obj1 = V::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(KvError::Value(e)))?; map.insert(obj, obj1); } - Ok(map) } } @@ -599,15 +386,18 @@ impl Encode for Option where T: Encode, { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = ::Error; + + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { if let Some(value) = self { - true.encode(buf)?; + true.encode(buf).unwrap(); value.encode(buf) } else { - false.encode(buf) + false.encode(buf).unwrap(); + Ok(()) } } } @@ -618,11 +408,13 @@ where { type Output = Option; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = >::Error; + + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { - Ok(if bool::decode(buf)? { + Ok(if bool::decode(buf).unwrap() { Some(T::decode(buf)?) } else { None @@ -632,8 +424,10 @@ where #[cfg(feature = "uuid")] impl Encode for uuid::Uuid { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -648,8 +442,10 @@ impl Encode for uuid::Uuid { impl<'de> Decode<'de> for uuid::Uuid { type Output = uuid::Uuid; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -661,8 +457,10 @@ impl<'de> Decode<'de> for uuid::Uuid { #[cfg(feature = "nbt")] impl Encode for std::collections::HashMap { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -674,8 +472,10 @@ impl Encode for std::collections::HashMap { impl<'de> Decode<'de> for std::collections::HashMap { type Output = std::collections::HashMap; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -685,8 +485,10 @@ impl<'de> Decode<'de> for std::collections::HashMap { #[cfg(feature = "glam")] impl Encode for glam::Vec3 { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -701,8 +503,10 @@ impl Encode for glam::Vec3 { impl<'de> Decode<'de> for glam::Vec3 { type Output = glam::Vec3; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -715,8 +519,10 @@ impl<'de> Decode<'de> for glam::Vec3 { #[cfg(feature = "glam")] impl Encode for glam::Quat { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -732,8 +538,10 @@ impl Encode for glam::Quat { impl<'de> Decode<'de> for glam::Quat { type Output = glam::Quat; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -746,8 +554,10 @@ impl<'de> Decode<'de> for glam::Quat { } impl super::Encode for () { + type Error = Infallible; + #[inline] - fn encode(&self, _buf: &mut B) -> anyhow::Result<()> + fn encode(&self, _buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -758,8 +568,10 @@ impl super::Encode for () { impl<'de> super::Decode<'de> for () { type Output = (); + type Error = Infallible; + #[inline] - fn decode(_buf: &'de mut B) -> anyhow::Result + fn decode(_buf: &'de mut B) -> Result where B: bytes::Buf, { diff --git a/util/edcode/src/lib.rs b/util/edcode/src/lib.rs index 75fe96d..3719ea5 100644 --- a/util/edcode/src/lib.rs +++ b/util/edcode/src/lib.rs @@ -1,3 +1,4 @@ +pub mod error; mod imp; #[cfg(test)] @@ -5,24 +6,29 @@ mod tests; /// Describes types that can be encoded into a packet buffer. pub trait Encode { + type Error; + /// Encode into a buffer. - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut; } +type BoxedError = Box; + /// [`Encode`], but can be used as trait objects. pub trait BytesEncode { - fn encode_bytes(&self, bytes: &mut bytes::BytesMut) -> anyhow::Result<()>; + fn encode_bytes(&self, bytes: &mut bytes::BytesMut) -> Result<(), BoxedError>; } impl BytesEncode for T where T: Encode, + ::Error: std::error::Error + Send + Sync + 'static, { #[inline] - fn encode_bytes(&self, bytes: &mut bytes::BytesMut) -> anyhow::Result<()> { - self.encode(bytes) + fn encode_bytes(&self, bytes: &mut bytes::BytesMut) -> Result<(), BoxedError> { + self.encode(bytes).map_err(From::from) } } @@ -31,25 +37,32 @@ pub trait Decode<'de> { /// The resulting type. type Output; + type Error; + /// Decode from a buffer. - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf; } /// Represents types that can be updated from a buffer. pub trait Update: Encode { + type Error; + /// Update from a buffer. - fn update(&mut self, buf: &mut B) -> anyhow::Result<()> + fn update(&mut self, buf: &mut B) -> Result<(), ::Error> where B: bytes::Buf; } -impl Update for T +impl Update for T where - T: Encode + for<'de> Decode<'de, Output = T>, + T: Encode + for<'de> Decode<'de, Output = T, Error = E>, { - fn update(&mut self, buf: &mut B) -> anyhow::Result<()> + type Error = E; + + #[inline] + fn update(&mut self, buf: &mut B) -> Result<(), ::Error> where B: bytes::Buf, { @@ -71,14 +84,9 @@ pub struct VarI32(pub i32); impl VarI32 { /// Get the encoded bytes length of this integer. + #[inline] pub fn len(self) -> usize { - for i in 1..5 { - if (self.0 & -1 << (i * 7)) == 0 { - return i as usize; - } - } - - 5 + (1..5).find(|i| self.0 & -1 << (i * 7) == 0).unwrap_or(5) } /// Whether the encoded bytes is empty. diff --git a/util/event/src/lib.rs b/util/event/src/lib.rs index 39e614e..50a4540 100644 --- a/util/event/src/lib.rs +++ b/util/event/src/lib.rs @@ -22,11 +22,9 @@ where invoker_factory: fn(&'static [&'static T]) -> Box, - // 0: raw listeners with phases - // - // 1: cached invoker - // - // 2: cached listener references + /// 0: raw listeners with phases\ + /// 1: cached invoker\ + /// 2: cached listener references lis_cac: RwLock>, } From 86a6edeef84c321900270c8397f2b94676b84171 Mon Sep 17 00:00:00 2001 From: JieningYu Date: Mon, 22 Jan 2024 21:48:22 +0800 Subject: [PATCH 2/3] Fix related errors --- primitives/src/identifier.rs | 18 ++++++-- util/edcode/src/error.rs | 20 ++++----- util/edcode/src/imp.rs | 87 ++++++++++++------------------------ util/edcode/src/lib.rs | 4 +- 4 files changed, 55 insertions(+), 74 deletions(-) diff --git a/primitives/src/identifier.rs b/primitives/src/identifier.rs index 2459cf4..e00f9b3 100644 --- a/primitives/src/identifier.rs +++ b/primitives/src/identifier.rs @@ -1,4 +1,4 @@ -/// Used for caching namespaces in runtime. +/// Used for caching namespaces at runtime. #[cfg(feature = "caches")] static NAMESPACE_CACHES: once_cell::sync::Lazy> = once_cell::sync::Lazy::new(rimecraft_caches::Caches::new); @@ -254,8 +254,10 @@ impl<'de> serde::Deserialize<'de> for Identifier { #[cfg(feature = "edcode")] impl rimecraft_edcode::Encode for Identifier { + type Error = std::convert::Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -267,11 +269,19 @@ impl rimecraft_edcode::Encode for Identifier { impl<'de> rimecraft_edcode::Decode<'de> for Identifier { type Output = Self; + type Error = rimecraft_edcode::error::EitherError< + Error, + rimecraft_edcode::error::ErrorWithVarI32Len, + >; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { - Ok(Self::try_parse(&String::decode(buf)?)?) + use rimecraft_edcode::error::EitherError; + String::decode(buf) + .map_err(EitherError::B) + .and_then(|s| Self::try_parse(&s).map_err(EitherError::A)) } } diff --git a/util/edcode/src/error.rs b/util/edcode/src/error.rs index 54d3b89..33ab01d 100644 --- a/util/edcode/src/error.rs +++ b/util/edcode/src/error.rs @@ -44,29 +44,29 @@ impl From for ErrorWithVarI32Len { } #[derive(Debug)] -pub enum KvError { - Key(K), - Value(V), +pub enum EitherError { + A(T1), + B(T2), } -impl std::fmt::Display for KvError { +impl std::fmt::Display for EitherError { #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - KvError::Key(e) => write!(f, "key error: {}", e), - KvError::Value(e) => write!(f, "value error: {}", e), + EitherError::A(e) => write!(f, "A error: {}", e), + EitherError::B(e) => write!(f, "B error: {}", e), } } } -impl std::error::Error - for KvError +impl std::error::Error + for EitherError { #[inline] fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - KvError::Key(e) => Some(e), - KvError::Value(e) => Some(e), + EitherError::A(e) => Some(e), + EitherError::B(e) => Some(e), } } } diff --git a/util/edcode/src/imp.rs b/util/edcode/src/imp.rs index 753430e..13979fa 100644 --- a/util/edcode/src/imp.rs +++ b/util/edcode/src/imp.rs @@ -98,104 +98,75 @@ impl<'de> Decode<'de> for bool { } #[cfg(feature = "nbt")] -impl Encode for Nbt<'_, T> +impl Encode for Nbt where T: serde::Serialize, { - type Error = Infallible; + type Error = fastnbt::error::Error; #[inline] fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { - struct WriteAdapt<'a, T: 'a>(pub &'a mut T); - - impl std::io::Write for WriteAdapt<'_, T> - where - T: bytes::BufMut, - { - #[inline] - fn write(&mut self, buf: &[u8]) -> std::io::Result { - unsafe { &mut *(self.0 as *mut T as *mut bytes::buf::Writer) }.write(buf) - } - - #[inline] - fn flush(&mut self) -> std::io::Result<()> { - unsafe { &mut *(self.0 as *mut T as *mut bytes::buf::Writer) }.flush() - } - } - - fastnbt::to_writer(WriteAdapt(buf), self.0)?; - Ok(()) + fastnbt::to_writer(bytes::BufMut::writer(buf), &self.0) } } #[cfg(feature = "nbt")] -impl<'de, T> Decode<'de> for Nbt<'_, T> +impl<'de, T> Decode<'de> for Nbt where - T: serde::Deserialize<'de>, + T: for<'a> serde::Deserialize<'a>, { type Output = T; - type Error = Infallible; + type Error = fastnbt::error::Error; #[inline] fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { - struct ReadAdapt<'a, T: 'a>(pub &'a mut T); - - impl std::io::Read for ReadAdapt<'_, T> - where - T: bytes::Buf, - { - #[inline] - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - unsafe { &mut *(self.0 as *mut T as *mut bytes::buf::Reader) }.read(buf) - } - } - - Ok(fastnbt::from_reader(ReadAdapt(buf))?) + fastnbt::from_reader(bytes::Buf::reader(buf)) } } #[cfg(feature = "json")] -impl Encode for Json<'_, T> +impl Encode for Json where T: serde::Serialize, { - type Error = Infallible; + type Error = serde_json::Error; #[inline] - fn encode(&self, buf: &mut B) -> Result<(), Self::Error> + fn encode(&self, mut buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { - serde_json::to_string(&self.0)?.encode(buf) + let vec = serde_json::to_vec(&self.0)?; + VarI32(vec.len() as i32).encode(&mut buf).unwrap(); + buf.put_slice(&vec); + Ok(()) } } #[cfg(feature = "json")] -impl<'de, T> Decode<'de> for Json<'_, T> +impl<'de, T> Decode<'de> for Json where - T: serde::de::DeserializeOwned, + T: for<'a> serde::de::Deserialize<'a>, { type Output = T; + type Error = ErrorWithVarI32Len; + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { let len = VarI32::decode(buf)? as usize; - let mut vec = Vec::with_capacity(len); - - for _ in 0..len { - vec.push(buf.get_u8()); - } - - Ok(serde_json::from_reader(vec.as_slice())?) + use std::io::Read; + serde_json::from_reader(bytes::Buf::reader(buf).take(len as u64)) + .map_err(ErrorWithVarI32Len::Target) } } @@ -341,7 +312,7 @@ where K: Encode, V: Encode, { - type Error = KvError<::Error, ::Error>; + type Error = EitherError<::Error, ::Error>; #[inline] fn encode(&self, buf: &mut B) -> Result<(), Self::Error> @@ -350,8 +321,8 @@ where { VarI32(self.len() as i32).encode(buf).unwrap(); for (key, value) in self.iter() { - key.encode(buf).map_err(KvError::Key)?; - value.encode(buf).map_err(KvError::Value)?; + key.encode(buf).map_err(EitherError::A)?; + value.encode(buf).map_err(EitherError::B)?; } Ok(()) } @@ -365,7 +336,7 @@ where { type Output = std::collections::HashMap; - type Error = ErrorWithVarI32Len>; + type Error = ErrorWithVarI32Len>; fn decode(buf: &'de mut B) -> Result where @@ -374,8 +345,8 @@ where let len = VarI32::decode(buf)? as usize; let mut map = std::collections::HashMap::with_capacity(len); for _ in 0..len { - let obj = K::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(KvError::Key(e)))?; - let obj1 = V::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(KvError::Value(e)))?; + let obj = K::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(EitherError::A(e)))?; + let obj1 = V::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(EitherError::B(e)))?; map.insert(obj, obj1); } Ok(map) @@ -457,7 +428,7 @@ impl<'de> Decode<'de> for uuid::Uuid { #[cfg(feature = "nbt")] impl Encode for std::collections::HashMap { - type Error = Infallible; + type Error = fastnbt::error::Error; #[inline] fn encode(&self, buf: &mut B) -> Result<(), Self::Error> @@ -472,7 +443,7 @@ impl Encode for std::collections::HashMap { impl<'de> Decode<'de> for std::collections::HashMap { type Output = std::collections::HashMap; - type Error = Infallible; + type Error = fastnbt::error::Error; #[inline] fn decode(buf: &'de mut B) -> Result diff --git a/util/edcode/src/lib.rs b/util/edcode/src/lib.rs index 3719ea5..2e8b2da 100644 --- a/util/edcode/src/lib.rs +++ b/util/edcode/src/lib.rs @@ -73,11 +73,11 @@ where /// Layer for encoding and decoding in nbt binary format for packets. #[cfg(feature = "nbt")] -pub struct Nbt<'a, T>(pub &'a T); +pub struct Nbt(pub T); /// Layer for encoding and decoding in json utf8 for packets. #[cfg(feature = "json")] -pub struct Json<'a, T>(pub &'a T); +pub struct Json(pub T); /// Represents a variable integer. pub struct VarI32(pub i32); From d7d9ea20bd35403f64bff9c260dbe0a2cc61f23a Mon Sep 17 00:00:00 2001 From: JieningYu Date: Mon, 22 Jan 2024 22:49:31 +0800 Subject: [PATCH 3/3] fix more --- core/src/component.rs | 53 +++++++++++++------- core/src/net/packet.rs | 9 +++- core/src/net/packet/c2s.rs | 97 ++++++++++++++++++++++++------------ core/src/net/packet/error.rs | 25 ++++++++++ core/src/net/packet/s2c.rs | 65 ++++++++++++++++++------ core/src/util/mod.rs | 2 + core/src/world/palette.rs | 48 ++++++++++++------ primitives/src/identifier.rs | 2 +- util/edcode/src/error.rs | 20 ++++---- util/edcode/src/imp.rs | 18 +++---- 10 files changed, 237 insertions(+), 102 deletions(-) create mode 100644 core/src/net/packet/error.rs diff --git a/core/src/component.rs b/core/src/component.rs index be6b79c..fbace03 100644 --- a/core/src/component.rs +++ b/core/src/component.rs @@ -10,6 +10,8 @@ use rimecraft_event::Event; use rimecraft_primitives::{id, Id, SerDeUpdate}; use tracing::{trace_span, warn}; +use crate::BoxedError; + /// Represents a type of component that can be attached /// on [`Components`]. pub trait Attach { @@ -119,7 +121,9 @@ pub enum ComponentsError { } impl Encode for Components { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = BoxedError; + + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -127,12 +131,15 @@ impl Encode for Components { let mut hashmap = HashMap::new(); event.invoker()(&mut hashmap)?; - hashmap.encode(buf) + hashmap.encode(buf)?; + Ok(()) } } impl rimecraft_edcode::Update for Components { - fn update(&mut self, buf: &mut B) -> anyhow::Result<()> + type Error = BoxedError; + + fn update(&mut self, buf: &mut B) -> Result<(), ::Error> where B: bytes::Buf, { @@ -143,7 +150,9 @@ impl rimecraft_edcode::Update for Components { .unwrap(); let mut hashmap = HashMap::::decode(buf)?; - event.invoker()(&mut hashmap) + event.invoker()(&mut hashmap)?; + + Ok(()) } } @@ -269,8 +278,10 @@ impl Encode for Component where T: Encode, { + type Error = ::Error; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -282,8 +293,10 @@ impl rimecraft_edcode::Update for Component where T: rimecraft_edcode::Update, { + type Error = ::Error; + #[inline] - fn update(&mut self, buf: &mut B) -> anyhow::Result<()> + fn update(&mut self, buf: &mut B) -> Result<(), ::Error> where B: bytes::Buf, { @@ -329,13 +342,13 @@ static NET_RECV_ID: once_cell::sync::Lazy = once_cell::sync::Lazy::new(net_r /// The `1` field is the component id which is used /// to be registered into components. #[derive(Debug)] -pub struct Synced(pub T, pub Id) -where - T: Attach + rimecraft_edcode::Update + 'static; +pub struct Synced(pub T, pub Id); impl Attach for Synced where T: Attach + rimecraft_edcode::Update + 'static, + ::Error: std::error::Error + Send + Sync + 'static, + ::Error: std::error::Error + Send + Sync + 'static, { fn on_attach(&mut self, components: &mut Components) { self.0.on_attach(components); @@ -375,7 +388,7 @@ where let this = unsafe { &mut *ptr }; let mut bytes = map.remove(&this.1).unwrap(); - this.0.update(&mut bytes) + this.0.update(&mut bytes).map_err(From::from) })), Err(err) => { warn!("network receiving event not found: {err}"); @@ -410,8 +423,10 @@ impl Encode for Synced where T: Attach + rimecraft_edcode::Update + 'static, { + type Error = ::Error; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -423,8 +438,10 @@ impl rimecraft_edcode::Update for Synced where T: Attach + rimecraft_edcode::Update + 'static, { + type Error = ::Error; + #[inline] - fn update(&mut self, buf: &mut B) -> anyhow::Result<()> + fn update(&mut self, buf: &mut B) -> Result<(), ::Error> where B: bytes::Buf, { @@ -495,9 +512,7 @@ static NBT_READ_ID: once_cell::sync::Lazy = once_cell::sync::Lazy::new(nbt_r /// The `1` field is the component id which is used /// to be registered into components. #[derive(Debug)] -pub struct Stored(pub T, pub Id) -where - T: Attach + SerDeUpdate + 'static; +pub struct Stored(pub T, pub Id); impl Attach for Stored where @@ -571,8 +586,10 @@ impl Encode for Stored where T: Attach + SerDeUpdate + Encode + 'static, { + type Error = ::Error; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -584,8 +601,10 @@ impl rimecraft_edcode::Update for Stored where T: Attach + SerDeUpdate + rimecraft_edcode::Update + 'static, { + type Error = ::Error; + #[inline] - fn update(&mut self, buf: &mut B) -> anyhow::Result<()> + fn update(&mut self, buf: &mut B) -> Result<(), ::Error> where B: bytes::Buf, { diff --git a/core/src/net/packet.rs b/core/src/net/packet.rs index ee898be..a9d22d8 100644 --- a/core/src/net/packet.rs +++ b/core/src/net/packet.rs @@ -1,7 +1,10 @@ pub mod c2s; pub mod s2c; -use anyhow::Ok; +pub mod error; + +use std::convert::Infallible; + use rimecraft_edcode::Encode; use super::listener::*; @@ -93,8 +96,10 @@ impl Encode for Bundled where T: Listener + ?Sized, { + type Error = Infallible; + #[inline] - fn encode(&self, _buf: &mut B) -> anyhow::Result<()> + fn encode(&self, _buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { diff --git a/core/src/net/packet/c2s.rs b/core/src/net/packet/c2s.rs index ed21150..f05fc68 100644 --- a/core/src/net/packet/c2s.rs +++ b/core/src/net/packet/c2s.rs @@ -1,11 +1,17 @@ -use anyhow::Ok; +use std::convert::Infallible; use bytes::Bytes; -use rimecraft_edcode::{Decode, Encode, VarI32}; +use rimecraft_edcode::{ + error::{ErrorWithVarI32Err, VarI32TooBigError}, + Decode, Encode, VarI32, +}; use rsa::RsaPrivateKey; -use crate::net::listener; +use crate::{net::listener, BoxedError}; +use super::error::*; + +#[derive(Debug)] pub struct Handshake { proto_ver: i32, addr: String, @@ -33,7 +39,7 @@ impl Handshake { } #[inline] - pub fn address(&self) -> &str { + pub fn addr(&self) -> &str { &self.addr } @@ -49,8 +55,10 @@ impl Handshake { } impl Encode for Handshake { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -64,13 +72,15 @@ impl Encode for Handshake { impl<'de> Decode<'de> for Handshake { type Output = Self; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = BoxedError; + + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { let proto_ver = VarI32::decode(buf)?; let addr = String::decode(buf)?; - let port = i16::decode(buf)? as u16; + let port = i16::decode(buf).unwrap() as u16; let state = VarI32::decode(buf)?; Ok(Self { @@ -78,7 +88,7 @@ impl<'de> Decode<'de> for Handshake { addr, port, intended_state: ConnectionIntent::n(state) - .ok_or_else(|| anyhow::anyhow!("unknown connection intent: {state}"))?, + .ok_or(UnknownConnectionIntentError(state))?, }) } } @@ -94,7 +104,7 @@ where } #[repr(i32)] -#[derive(Clone, Copy, PartialEq, Eq, enumn::N)] +#[derive(Clone, Copy, PartialEq, Eq, enumn::N, Debug)] pub enum ConnectionIntent { Status, Login, @@ -110,14 +120,17 @@ impl ConnectionIntent { } } +#[derive(Debug)] pub struct LoginHello { name: String, profile_id: uuid::Uuid, } impl Encode for LoginHello { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Infallible> where B: bytes::BufMut, { @@ -129,13 +142,15 @@ impl Encode for LoginHello { impl<'de> Decode<'de> for LoginHello { type Output = Self; + type Error = BoxedError; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { let name = String::decode(buf)?; - let uuid = uuid::Uuid::decode(buf)?; + let uuid = uuid::Uuid::decode(buf).unwrap(); Ok(Self { name, @@ -146,6 +161,7 @@ impl<'de> Decode<'de> for LoginHello { impl super::Packet for LoginHello where L: listener::Accept {} +#[derive(Debug)] pub struct LoginQueryRes { query_id: i32, res: Option, @@ -159,7 +175,9 @@ impl LoginQueryRes { } impl Encode for LoginQueryRes { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = Infallible; + + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -178,7 +196,9 @@ impl Encode for LoginQueryRes { impl<'de> Decode<'de> for LoginQueryRes { type Output = Self; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = ErrorWithVarI32Err; + + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -187,8 +207,10 @@ impl<'de> Decode<'de> for LoginQueryRes { impl<'de> Decode<'de> for NullableRes { type Output = bytes::Bytes; + type Error = PayloadTooLargeError; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -198,16 +220,15 @@ impl<'de> Decode<'de> for LoginQueryRes { buf.advance(remaining); Ok(Bytes::new()) } else { - Err(anyhow::anyhow!( - "payload may not be larger than {} bytes", - super::QUERY_MAX_PAYLOAD_LEN - )) + Err(PayloadTooLargeError { + max: super::QUERY_MAX_PAYLOAD_LEN, + }) } } } let qid = VarI32::decode(buf)?; - let res = Option::::decode(buf)?; + let res = Option::::decode(buf).map_err(ErrorWithVarI32Err::Target)?; Ok(Self { query_id: qid, res }) } @@ -215,12 +236,13 @@ impl<'de> Decode<'de> for LoginQueryRes { impl super::Packet for LoginQueryRes where L: listener::Accept {} +#[derive(Debug)] pub struct LoginKey { encrypted_secret_key: Bytes, /// The nonce value. /// - /// This value is either encrypted (the left side of {@code Either}) or signed + /// This value is either encrypted (the left side of `Either`) or signed /// (the right side). If encrypted, then it must be done so using the server's public key /// and the server verifies it by decrypting and comparing nonces. If signed, then it must /// be done so using the user's private key provided from Mojang's server, and the server @@ -229,8 +251,10 @@ pub struct LoginKey { } impl Encode for LoginKey { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -242,8 +266,10 @@ impl Encode for LoginKey { impl<'de> Decode<'de> for LoginKey { type Output = LoginKey; + type Error = VarI32TooBigError; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -260,23 +286,22 @@ impl<'de> Decode<'de> for LoginKey { impl super::Packet for LoginKey where L: listener::Accept {} impl LoginKey { - #[inline] pub fn new( rng: &mut R, secret_key: &[u8], public_key: &rsa::RsaPublicKey, nonce: &[u8], - ) -> anyhow::Result + ) -> Result where R: rsa::rand_core::CryptoRngCore, { Ok(Self { encrypted_secret_key: public_key .encrypt(rng, rsa::pkcs1v15::Pkcs1v15Encrypt, secret_key)? - .try_into()?, + .into(), nonce: public_key .encrypt(rng, rsa::pkcs1v15::Pkcs1v15Encrypt, nonce)? - .try_into()?, + .into(), }) } @@ -294,6 +319,7 @@ impl LoginKey { } } +#[derive(Debug)] pub struct QueryPing { start_time: u64, } @@ -305,8 +331,10 @@ impl QueryPing { } impl Encode for QueryPing { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -318,8 +346,10 @@ impl Encode for QueryPing { impl<'de> Decode<'de> for QueryPing { type Output = Self; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -331,11 +361,14 @@ impl<'de> Decode<'de> for QueryPing { impl super::Packet for QueryPing where L: listener::Accept {} +#[derive(Debug)] pub struct QueryReq; impl Encode for QueryReq { + type Error = Infallible; + #[inline] - fn encode(&self, _buf: &mut B) -> anyhow::Result<()> + fn encode(&self, _buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -346,8 +379,10 @@ impl Encode for QueryReq { impl<'de> Decode<'de> for QueryReq { type Output = Self; + type Error = Infallible; + #[inline] - fn decode(_buf: &'de mut B) -> anyhow::Result + fn decode(_buf: &'de mut B) -> Result where B: bytes::Buf, { diff --git a/core/src/net/packet/error.rs b/core/src/net/packet/error.rs new file mode 100644 index 0000000..506e01a --- /dev/null +++ b/core/src/net/packet/error.rs @@ -0,0 +1,25 @@ +#[derive(Debug)] +pub struct UnknownConnectionIntentError(pub i32); + +impl std::fmt::Display for UnknownConnectionIntentError { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "unknown connection intent: {}", self.0) + } +} + +impl std::error::Error for UnknownConnectionIntentError {} + +#[derive(Debug)] +pub struct PayloadTooLargeError { + pub max: usize, +} + +impl std::fmt::Display for PayloadTooLargeError { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "payload may not be larger than {} bytes", self.max) + } +} + +impl std::error::Error for PayloadTooLargeError {} diff --git a/core/src/net/packet/s2c.rs b/core/src/net/packet/s2c.rs index faf6ecf..79ba7b3 100644 --- a/core/src/net/packet/s2c.rs +++ b/core/src/net/packet/s2c.rs @@ -1,10 +1,18 @@ +use std::{convert::Infallible, string::FromUtf8Error}; + use bytes::Bytes; -use rimecraft_edcode::{Decode, Encode, VarI32}; +use rimecraft_edcode::{ + error::{ErrorWithVarI32Err, VarI32TooBigError}, + Decode, Encode, VarI32, +}; use rimecraft_primitives::Id; use rsa::{pkcs8::DecodePublicKey, RsaPublicKey}; -use crate::{net::listener, text::Text}; +use crate::{net::listener, text::Text, BoxedError}; + +use super::error::PayloadTooLargeError; +#[derive(Debug)] pub struct LoginCompression { threshold: i32, } @@ -15,14 +23,17 @@ impl LoginCompression { Self { threshold } } + #[inline] pub fn threshold(&self) -> i32 { self.threshold } } impl Encode for LoginCompression { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -33,8 +44,10 @@ impl Encode for LoginCompression { impl<'de> Decode<'de> for LoginCompression { type Output = Self; + type Error = VarI32TooBigError; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -46,6 +59,7 @@ impl<'de> Decode<'de> for LoginCompression { impl super::Packet for LoginCompression where L: listener::Accept {} +#[derive(Debug)] pub struct LoginDisconnect { reason: Text, } @@ -63,7 +77,9 @@ impl LoginDisconnect { } impl Encode for LoginDisconnect { - fn encode(&self, _buf: &mut B) -> anyhow::Result<()> + type Error = Infallible; + + fn encode(&self, _buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -74,7 +90,9 @@ impl Encode for LoginDisconnect { impl<'de> Decode<'de> for LoginDisconnect { type Output = Self; - fn decode(_buf: &'de mut B) -> anyhow::Result + type Error = Infallible; + + fn decode(_buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -84,6 +102,7 @@ impl<'de> Decode<'de> for LoginDisconnect { impl super::Packet for LoginDisconnect where L: listener::Accept {} +#[derive(Debug)] pub struct LoginHello { server_id: String, pub_key: Bytes, @@ -118,8 +137,10 @@ impl LoginHello { } impl Encode for LoginHello { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -132,8 +153,10 @@ impl Encode for LoginHello { impl<'de> Decode<'de> for LoginHello { type Output = Self; + type Error = ErrorWithVarI32Err; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -151,6 +174,7 @@ impl<'de> Decode<'de> for LoginHello { impl super::Packet for LoginHello where L: listener::Accept {} +#[derive(Debug)] pub struct LoginQueryReq { query_id: i32, channel: Id, @@ -179,8 +203,10 @@ impl LoginQueryReq { } impl Encode for LoginQueryReq { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -194,7 +220,9 @@ impl Encode for LoginQueryReq { impl<'de> Decode<'de> for LoginQueryReq { type Output = Self; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = BoxedError; + + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -212,10 +240,10 @@ impl<'de> Decode<'de> for LoginQueryReq { payload, }) } else { - Err(anyhow::anyhow!( - "payload may not be larger than {} bytes", - super::QUERY_MAX_PAYLOAD_LEN - )) + Err(PayloadTooLargeError { + max: super::QUERY_MAX_PAYLOAD_LEN, + } + .into()) } } } @@ -224,6 +252,7 @@ impl super::Packet for LoginQueryReq where L: listener::Accept {} //TODO: LoginSuccessS2CPacket and authlib's GameProfile implementation +#[derive(Debug)] pub struct PingResult { start_time: u64, } @@ -241,8 +270,10 @@ impl PingResult { } impl Encode for PingResult { + type Error = Infallible; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -254,8 +285,10 @@ impl Encode for PingResult { impl<'de> Decode<'de> for PingResult { type Output = Self; + type Error = Infallible; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { diff --git a/core/src/util/mod.rs b/core/src/util/mod.rs index d1fa993..b85a5ee 100644 --- a/core/src/util/mod.rs +++ b/core/src/util/mod.rs @@ -9,6 +9,8 @@ use std::{fmt::UpperHex, ops::Deref, str::FromStr}; use crate::text::Text; +pub(crate) type BoxedError = Box; + #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] #[repr(u8)] pub enum Rarity { diff --git a/core/src/world/palette.rs b/core/src/world/palette.rs index c42f752..186d69b 100644 --- a/core/src/world/palette.rs +++ b/core/src/world/palette.rs @@ -1,7 +1,23 @@ -use std::hash::Hash; +use std::{convert::Infallible, hash::Hash}; use rimecraft_collections::PackedArray; -use rimecraft_edcode::{Decode, Encode, VarI32}; +use rimecraft_edcode::{error::ErrorWithVarI32Err, Decode, Encode, VarI32}; + +pub mod error { + #[derive(Debug)] + pub struct RawIdNotFoundError; + + impl std::fmt::Display for RawIdNotFoundError { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "raw id not found in the target id list") + } + } + + impl std::error::Error for RawIdNotFoundError {} +} + +use error::*; /// A palette maps objects from and to small integer IDs that uses less /// number of bits to make storage smaller. @@ -139,7 +155,9 @@ impl<'a, T> Encode for Palette<'a, T> where T: Eq + Copy + Hash + 'a, { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = Infallible; + + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -179,7 +197,9 @@ impl<'a, T> rimecraft_edcode::Update for Palette<'a, T> where T: Eq + Copy + Hash + 'a, { - fn update(&mut self, buf: &mut B) -> anyhow::Result<()> + type Error = ErrorWithVarI32Err; + + fn update(&mut self, buf: &mut B) -> Result<(), ::Error> where B: bytes::Buf, { @@ -197,22 +217,18 @@ where self.ids .get(VarI32::decode(buf)? as usize) .copied() - .ok_or_else(|| { - anyhow::anyhow!("raw id not found in the target id list.") - })?, + .ok_or_else(|| ErrorWithVarI32Err::Target(RawIdNotFoundError))?, ); } Inner::BiMap(bimap) => { - *bimap = { - let mut map = bimap::BiMap::new(); - for _ in 0..VarI32::decode(buf)? { - map.insert( - map.len(), - *self.ids.get(VarI32::decode(buf)? as usize).unwrap(), - ); - } - map + let mut map = bimap::BiMap::new(); + for _ in 0..VarI32::decode(buf)? { + map.insert( + map.len(), + *self.ids.0.get(VarI32::decode(buf)? as usize).unwrap(), + ); } + *bimap = map } } diff --git a/primitives/src/identifier.rs b/primitives/src/identifier.rs index e00f9b3..463e09d 100644 --- a/primitives/src/identifier.rs +++ b/primitives/src/identifier.rs @@ -271,7 +271,7 @@ impl<'de> rimecraft_edcode::Decode<'de> for Identifier { type Error = rimecraft_edcode::error::EitherError< Error, - rimecraft_edcode::error::ErrorWithVarI32Len, + rimecraft_edcode::error::ErrorWithVarI32Err, >; #[inline] diff --git a/util/edcode/src/error.rs b/util/edcode/src/error.rs index 33ab01d..797981a 100644 --- a/util/edcode/src/error.rs +++ b/util/edcode/src/error.rs @@ -11,35 +11,35 @@ impl std::fmt::Display for VarI32TooBigError { impl std::error::Error for VarI32TooBigError {} #[derive(Debug)] -pub enum ErrorWithVarI32Len { +pub enum ErrorWithVarI32Err { Target(T), - Len(VarI32TooBigError), + Var(VarI32TooBigError), } -impl std::fmt::Display for ErrorWithVarI32Len { +impl std::fmt::Display for ErrorWithVarI32Err { #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - ErrorWithVarI32Len::Target(e) => write!(f, "{}", e), - ErrorWithVarI32Len::Len(e) => write!(f, "variable length error: {}", e), + ErrorWithVarI32Err::Target(e) => write!(f, "{}", e), + ErrorWithVarI32Err::Var(e) => write!(f, "variable integer error: {}", e), } } } -impl std::error::Error for ErrorWithVarI32Len { +impl std::error::Error for ErrorWithVarI32Err { #[inline] fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - ErrorWithVarI32Len::Target(e) => Some(e), - ErrorWithVarI32Len::Len(e) => Some(e), + ErrorWithVarI32Err::Target(e) => Some(e), + ErrorWithVarI32Err::Var(e) => Some(e), } } } -impl From for ErrorWithVarI32Len { +impl From for ErrorWithVarI32Err { #[inline] fn from(value: VarI32TooBigError) -> Self { - Self::Len(value) + Self::Var(value) } } diff --git a/util/edcode/src/imp.rs b/util/edcode/src/imp.rs index 13979fa..9eaa722 100644 --- a/util/edcode/src/imp.rs +++ b/util/edcode/src/imp.rs @@ -157,7 +157,7 @@ where { type Output = T; - type Error = ErrorWithVarI32Len; + type Error = ErrorWithVarI32Err; fn decode(buf: &'de mut B) -> Result where @@ -166,7 +166,7 @@ where let len = VarI32::decode(buf)? as usize; use std::io::Read; serde_json::from_reader(bytes::Buf::reader(buf).take(len as u64)) - .map_err(ErrorWithVarI32Len::Target) + .map_err(ErrorWithVarI32Err::Target) } } @@ -252,7 +252,7 @@ impl Encode for String { impl<'de> Decode<'de> for String { type Output = String; - type Error = ErrorWithVarI32Len; + type Error = ErrorWithVarI32Err; fn decode(buf: &'de mut B) -> Result where @@ -261,7 +261,7 @@ impl<'de> Decode<'de> for String { let len = VarI32::decode(buf)? as usize; let mut vec = vec![0; len]; buf.copy_to_slice(&mut vec[..]); - Ok(String::from_utf8(vec).map_err(ErrorWithVarI32Len::Target)?) + Ok(String::from_utf8(vec).map_err(ErrorWithVarI32Err::Target)?) } } @@ -290,7 +290,7 @@ where { type Output = Vec; - type Error = ErrorWithVarI32Len; + type Error = ErrorWithVarI32Err; fn decode(mut buf: &'de mut B) -> Result where @@ -300,7 +300,7 @@ where let mut vec = Vec::with_capacity(len); for _ in 0..len { - vec.push(T::decode(&mut buf).map_err(ErrorWithVarI32Len::Target)?); + vec.push(T::decode(&mut buf).map_err(ErrorWithVarI32Err::Target)?); } Ok(vec) @@ -336,7 +336,7 @@ where { type Output = std::collections::HashMap; - type Error = ErrorWithVarI32Len>; + type Error = ErrorWithVarI32Err>; fn decode(buf: &'de mut B) -> Result where @@ -345,8 +345,8 @@ where let len = VarI32::decode(buf)? as usize; let mut map = std::collections::HashMap::with_capacity(len); for _ in 0..len { - let obj = K::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(EitherError::A(e)))?; - let obj1 = V::decode(buf).map_err(|e| ErrorWithVarI32Len::Target(EitherError::B(e)))?; + let obj = K::decode(buf).map_err(|e| ErrorWithVarI32Err::Target(EitherError::A(e)))?; + let obj1 = V::decode(buf).map_err(|e| ErrorWithVarI32Err::Target(EitherError::B(e)))?; map.insert(obj, obj1); } Ok(map)