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 2459cf4..463e09d 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::ErrorWithVarI32Err, + >; + #[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/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..797981a --- /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 ErrorWithVarI32Err { + Target(T), + Var(VarI32TooBigError), +} + +impl std::fmt::Display for ErrorWithVarI32Err { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ErrorWithVarI32Err::Target(e) => write!(f, "{}", e), + ErrorWithVarI32Err::Var(e) => write!(f, "variable integer error: {}", e), + } + } +} + +impl std::error::Error for ErrorWithVarI32Err { + #[inline] + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + ErrorWithVarI32Err::Target(e) => Some(e), + ErrorWithVarI32Err::Var(e) => Some(e), + } + } +} + +impl From for ErrorWithVarI32Err { + #[inline] + fn from(value: VarI32TooBigError) -> Self { + Self::Var(value) + } +} + +#[derive(Debug)] +pub enum EitherError { + A(T1), + B(T2), +} + +impl std::fmt::Display for EitherError { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EitherError::A(e) => write!(f, "A error: {}", e), + EitherError::B(e) => write!(f, "B error: {}", e), + } + } +} + +impl std::error::Error + for EitherError +{ + #[inline] + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + 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 aba9d96..9eaa722 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(()) - } -} - -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; +macro_rules! edcode_primitive { + ($($t:ty => $fe:ident, $fd:ident),*) => { + $( + impl Encode for $t { + type Error = Infallible; - #[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(()) - } -} + #[inline] + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> { + buf.$fe(*self); + Ok(()) + } + } -impl<'de> Decode<'de> for f32 { - type Output = f32; + impl<'de> Decode<'de> for $t { + type Output = $t; + type Error = Infallible; - #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result - where - B: bytes::Buf, - { - Ok(buf.get_f32()) - } -} - -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, { @@ -327,103 +98,82 @@ impl<'de> Decode<'de> for bool { } #[cfg(feature = "nbt")] -impl Encode for Nbt<'_, T> +impl Encode for Nbt where T: serde::Serialize, { + type Error = fastnbt::error::Error; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + 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 = fastnbt::error::Error; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + 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 = serde_json::Error; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + 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; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = ErrorWithVarI32Err; + + 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(ErrorWithVarI32Err::Target) } } 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 +196,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 +216,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 +238,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 +252,16 @@ impl Encode for String { impl<'de> Decode<'de> for String { type Output = String; - fn decode(buf: &'de mut B) -> anyhow::Result + type Error = ErrorWithVarI32Err; + + 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(ErrorWithVarI32Err::Target)?) } } @@ -515,35 +269,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 = ErrorWithVarI32Err; + + 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(ErrorWithVarI32Err::Target)?); } Ok(vec) @@ -555,42 +312,43 @@ where K: Encode, V: Encode, { - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + type Error = EitherError<::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(EitherError::A)?; + value.encode(buf).map_err(EitherError::B)?; } - 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 = ErrorWithVarI32Err>; + + 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| ErrorWithVarI32Err::Target(EitherError::A(e)))?; + let obj1 = V::decode(buf).map_err(|e| ErrorWithVarI32Err::Target(EitherError::B(e)))?; map.insert(obj, obj1); } - Ok(map) } } @@ -599,15 +357,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 +379,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 +395,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 +413,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 +428,10 @@ impl<'de> Decode<'de> for uuid::Uuid { #[cfg(feature = "nbt")] impl Encode for std::collections::HashMap { + type Error = fastnbt::error::Error; + #[inline] - fn encode(&self, buf: &mut B) -> anyhow::Result<()> + fn encode(&self, buf: &mut B) -> Result<(), Self::Error> where B: bytes::BufMut, { @@ -674,8 +443,10 @@ impl Encode for std::collections::HashMap { impl<'de> Decode<'de> for std::collections::HashMap { type Output = std::collections::HashMap; + type Error = fastnbt::error::Error; + #[inline] - fn decode(buf: &'de mut B) -> anyhow::Result + fn decode(buf: &'de mut B) -> Result where B: bytes::Buf, { @@ -685,8 +456,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 +474,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 +490,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 +509,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 +525,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 +539,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..2e8b2da 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, { @@ -60,25 +73,20 @@ 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); 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>, }