diff --git a/Cargo.toml b/Cargo.toml index 091d3d7..00dd07c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,6 @@ [workspace] resolver = "2" -members = [ - "crates/util/*", - "crates/client/*", - "crates/core/*", -] +members = ["crates/util/*", "crates/client/*", "crates/core/*"] [workspace.lints.rust] missing-docs = "warn" diff --git a/crates/core/component/Cargo.toml b/crates/core/component/Cargo.toml index fca00ae..b730930 100644 --- a/crates/core/component/Cargo.toml +++ b/crates/core/component/Cargo.toml @@ -16,7 +16,7 @@ serde = "1.0" erased-serde = "0.4" bytes = "1.6" ahash = "0.8" -rimecraft-edcode = { path = "../../util/edcode" } +edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2" } rimecraft-registry = { path = "../registry", features = ["serde"] } rimecraft-global-cx = { path = "../global-cx", features = ["nbt", "std"] } rimecraft-maybe = { path = "../../util/maybe" } diff --git a/crates/core/component/src/changes.rs b/crates/core/component/src/changes.rs index d4ec5a7..299c572 100644 --- a/crates/core/component/src/changes.rs +++ b/crates/core/component/src/changes.rs @@ -3,7 +3,6 @@ use std::{fmt::Debug, marker::PhantomData, str::FromStr}; use ahash::AHashMap; -use rimecraft_edcode::{Encode, VarI32}; use rimecraft_global_cx::ProvideIdTy; use rimecraft_maybe::Maybe; use rimecraft_registry::{ProvideRegistry, Reg}; @@ -99,24 +98,6 @@ where } } -//TODO: implement encode and decode -/* -impl Encode for ComponentChanges<'_, '_, Cx> -where - Cx: ProvideIdTy, -{ - fn encode(&self, buf: B) -> Result<(), std::io::Error> - where - B: bytes::BufMut, - { - let c_valid = self.changes.iter().filter(|(_, v)| v.is_some()).count(); - let c_rm = self.changes.len() - c_valid; - VarI32(c_valid as i32).encode(buf)?; - VarI32(c_rm as i32).encode(buf)?; - } -} -*/ - impl Debug for ComponentChanges<'_, '_, Cx> where Cx: ProvideIdTy + Debug, diff --git a/crates/core/component/src/lib.rs b/crates/core/component/src/lib.rs index 4721f88..5a15273 100644 --- a/crates/core/component/src/lib.rs +++ b/crates/core/component/src/lib.rs @@ -6,7 +6,8 @@ use std::{ marker::PhantomData, }; -use rimecraft_edcode::{Decode, Encode}; +use bytes::{Buf, BufMut}; +use edcode2::{Decode, Encode}; use rimecraft_global_cx::ProvideIdTy; use rimecraft_registry::{ProvideRegistry, Reg}; use serde::{de::DeserializeOwned, Serialize}; @@ -49,7 +50,11 @@ where impl ComponentType where - T: Encode + Decode + Send + Sync + 'static, + T: for<'a> Encode<&'a dyn BufMut> + + for<'a> Decode<'static, &'a dyn Buf> + + Send + + Sync + + 'static, { /// Codec for packet encoding and decoding. pub const PACKET_CODEC: PacketCodec = PacketCodec { @@ -58,7 +63,13 @@ where .expect("mismatched type") .encode(buf) }, - decode: |buf| Ok(Box::new(T::decode(buf)?)), + decode: { + assert!( + >::SUPPORT_NON_IN_PLACE, + "non-in-place decoding is not supported for this type", + ); + |buf| Ok(Box::new(T::decode(buf)?)) + }, upd: |obj, buf| { obj.downcast_mut::() .expect("mismatched type") @@ -145,8 +156,6 @@ impl PartialEq for ComponentType { } } -impl ComponentType where T: Encode + Decode {} - impl Default for ComponentType where T: Clone + Eq + Send + Sync + 'static, @@ -188,9 +197,9 @@ struct SerdeCodec { #[derive(Debug, Clone, Copy)] #[allow(dead_code)] pub struct PacketCodec { - encode: fn(&Object, &mut dyn bytes::BufMut) -> Result<(), std::io::Error>, - decode: fn(&mut dyn bytes::Buf) -> Result, std::io::Error>, - upd: fn(&mut Object, &mut dyn bytes::Buf) -> Result<(), std::io::Error>, + encode: fn(&Object, &mut dyn BufMut) -> Result<(), edcode2::BoxedError<'static>>, + decode: fn(&mut dyn Buf) -> Result, edcode2::BoxedError<'static>>, + upd: fn(&mut Object, &mut dyn Buf) -> Result<(), edcode2::BoxedError<'static>>, } #[derive(Debug, Clone, Copy)] diff --git a/crates/core/item/Cargo.toml b/crates/core/item/Cargo.toml index 4909da1..6c6daa1 100644 --- a/crates/core/item/Cargo.toml +++ b/crates/core/item/Cargo.toml @@ -19,12 +19,12 @@ rimecraft-global-cx = { path = "../global-cx", features = ["nbt"] } rimecraft-registry = { path = "../registry" } rimecraft-fmt = { path = "../../util/fmt" } serde = { version = "1.0", optional = true } -rimecraft-edcode = { path = "../../util/edcode", optional = true } +edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2", optional = true } [features] default = ["serde", "edcode"] serde = ["dep:serde", "rimecraft-registry/serde"] -edcode = ["dep:rimecraft-edcode", "rimecraft-registry/edcode"] +edcode = ["dep:edcode2", "rimecraft-registry/edcode"] [lints] workspace = true diff --git a/crates/core/item/src/edcode.rs b/crates/core/item/src/edcode.rs index ce05c06..25b085b 100644 --- a/crates/core/item/src/edcode.rs +++ b/crates/core/item/src/edcode.rs @@ -1,21 +1,19 @@ -use rimecraft_edcode::{Decode, Encode}; +use edcode2::{Buf, BufExt, BufMut, BufMutExt, Decode, Encode}; use rimecraft_global_cx::nbt_edcode::{ReadNbt, WriteNbt}; use rimecraft_registry::{ProvideRegistry, Reg}; use crate::{stack::ItemStackCx, ItemStack, RawItem}; -impl Encode for ItemStack<'_, Cx> +impl Encode for ItemStack<'_, Cx> where Cx: ItemStackCx + for<'a> WriteNbt>, + B: BufMut, { - fn encode(&self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { if self.count() == 0 { - false.encode(buf)?; + buf.put_bool(false); } else { - true.encode(&mut buf)?; + buf.put_bool(true); let item = self.item(); item.encode(&mut buf)?; self.count().encode(&mut buf)?; @@ -27,17 +25,15 @@ where } } -impl<'r, Cx> Decode for ItemStack<'r, Cx> +impl<'r, 'de, Cx, B> Decode<'de, B> for ItemStack<'r, Cx> where Cx: ItemStackCx + ReadNbt> + ProvideRegistry<'r, Cx::Id, RawItem>, + B: Buf, { - fn decode(mut buf: B) -> Result - where - B: rimecraft_edcode::bytes::Buf, - { - if bool::decode(&mut buf)? { + fn decode(mut buf: B) -> Result> { + if buf.get_bool() { let item = Reg::<'r, Cx::Id, RawItem>::decode(&mut buf)?; - let count = u8::decode(&mut buf)?; + let count = buf.get_u8(); let nbt = Cx::read_nbt(buf.reader())?; Ok(ItemStack::with_nbt(item, count, nbt)) } else { diff --git a/crates/core/palette/Cargo.toml b/crates/core/palette/Cargo.toml index d8e5f77..8ed794e 100644 --- a/crates/core/palette/Cargo.toml +++ b/crates/core/palette/Cargo.toml @@ -14,13 +14,13 @@ maintenance = { status = "passively-maintained" } [dependencies] rimecraft-packed-int-array = { path = "../../util/packed-int-array" } rimecraft-maybe = { path = "../../util/maybe" } -rimecraft-edcode = { path = "../../util/edcode", optional = true } +edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2", optional = true } serde = { version = "1.0", features = ["derive"], optional = true } rimecraft-serde-update = { path = "../../util/serde-update", optional = true } ahash = "0.8" [features] -edcode = ["dep:rimecraft-edcode"] +edcode = ["dep:edcode2"] serde = ["dep:serde", "dep:rimecraft-serde-update"] [lints] diff --git a/crates/core/palette/src/container.rs b/crates/core/palette/src/container.rs index b622582..ef342b3 100644 --- a/crates/core/palette/src/container.rs +++ b/crates/core/palette/src/container.rs @@ -314,18 +314,16 @@ where #[cfg(feature = "edcode")] mod _edcode { - use rimecraft_edcode::{Encode, Update, VarI32}; + use edcode2::{Buf, BufMut, Decode, Encode}; use super::*; - impl Encode for Data + impl Encode for Data where L: for<'a> IndexToRaw<&'a T>, + B: BufMut, { - fn encode(&self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { buf.put_u8( self.storage .as_array() @@ -341,53 +339,25 @@ mod _edcode { } } - impl Data - where - L: for<'a> IndexToRaw<&'a T>, - { - /// Returns the encoded length of this data. - /// - /// # Panics - /// - /// See errors in [`Palette::encoded_len`]. - pub fn encoded_len(&self) -> usize { - let len = self - .storage - .as_array() - .map(|array| array.data().len()) - .unwrap_or_default(); - 1 + self - .palette - .encoded_len() - .expect("palette is not encodable") - + VarI32(len as i32).encoded_len() - + len * 8 - } - } - - impl Encode for PalettedContainer + impl Encode for PalettedContainer where L: for<'a> IndexToRaw<&'a T>, + B: BufMut, { #[inline] - fn encode(&self, buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, buf: B) -> Result<(), edcode2::BoxedError<'static>> { self.data.encode(buf) } } - impl Update for PalettedContainer + impl<'de, L, T, Cx, B> Decode<'de, B> for PalettedContainer where L: for<'s> IndexFromRaw<'s, T> + Clone, T: Clone + Hash + Eq, Cx: ProvidePalette, + B: Buf, { - fn update(&mut self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::Buf, - { + fn decode_in_place(&mut self, mut buf: B) -> Result<(), edcode2::BoxedError<'de>> { let data = compatible_data::( self.list.clone(), Some(&self.data), @@ -397,28 +367,20 @@ mod _edcode { self.data = data } - self.data.palette.update(&mut buf)?; + self.data.palette.decode_in_place(&mut buf)?; if let Some(array) = self.data.storage.as_array_mut() { - array.data_mut().update(&mut buf)?; + array.data_mut().decode_in_place(&mut buf)?; } Ok(()) } - } - impl PalettedContainer - where - L: for<'a> IndexToRaw<&'a T>, - { - /// Returns the encoded length of this container. - /// - /// # Panics - /// - /// See errors in [`Palette::encoded_len`]. #[inline] - pub fn encoded_len(&self) -> usize { - self.data.encoded_len() + fn decode(_buf: B) -> Result> { + Err("paletted containers does not support non-in-place decoding".into()) } + + const SUPPORT_NON_IN_PLACE: bool = false; } } diff --git a/crates/core/palette/src/lib.rs b/crates/core/palette/src/lib.rs index 6faeda8..bb8ab52 100644 --- a/crates/core/palette/src/lib.rs +++ b/crates/core/palette/src/lib.rs @@ -292,63 +292,54 @@ mod _edcode { use std::io::{self, ErrorKind}; - use rimecraft_edcode::{Decode, Encode, Update, VarI32}; + use edcode2::{Buf, BufExt, BufMut, BufMutExt, Decode, Encode}; use super::*; - impl Encode for Palette + impl Encode for Palette where L: for<'a> IndexToRaw<&'a T>, + B: BufMut, { - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { match &self.internal { - PaletteImpl::Singular(value) => value - .as_ref() - .ok_or_else(|| io::Error::new(ErrorKind::Other, Error::Uninitialized)) - .and_then(|v| { - self.list.raw_id(v).ok_or_else(|| { - io::Error::new(ErrorKind::InvalidData, Error::UnknownEntry) - }) - }) - .and_then(|id| VarI32(id as i32).encode(buf)), + PaletteImpl::Singular(value) => buf.put_variable( + value + .as_ref() + .ok_or(Error::Uninitialized) + .and_then(|v| self.list.raw_id(v).ok_or(Error::UnknownEntry))? + as u32, + ), PaletteImpl::Array(forward) | PaletteImpl::BiMap { forward, .. } => { - VarI32(forward.len() as i32).encode(&mut buf)?; + buf.put_variable(forward.len() as u32); for entry in forward { - VarI32(self.list.raw_id(entry).ok_or_else(|| { - io::Error::new(ErrorKind::InvalidData, Error::UnknownEntry) - })? as i32) - .encode(&mut buf)?; + buf.put_variable(self.list.raw_id(entry).ok_or(Error::UnknownEntry)? as u32) } - Ok(()) } - PaletteImpl::Direct => Ok(()), + PaletteImpl::Direct => {} } + Ok(()) } } - impl Update for Palette + impl<'de, L, T, B> Decode<'de, B> for Palette where L: for<'s> IndexFromRaw<'s, T>, + B: Buf, { - fn update(&mut self, mut buf: B) -> Result<(), io::Error> - where - B: rimecraft_edcode::bytes::Buf, - { + fn decode_in_place(&mut self, mut buf: B) -> Result<(), edcode2::BoxedError<'de>> { match &mut self.internal { PaletteImpl::Singular(entry) => { - let id = VarI32::decode(buf)?.0 as usize; + let id = buf.get_variable::() as usize; *entry = Some(self.list.of_raw(id).ok_or_else(|| { io::Error::new(ErrorKind::InvalidData, Error::UnknownId(id)) })?); } PaletteImpl::Array(forward) | PaletteImpl::BiMap { forward, .. } => { - let len = VarI32::decode(&mut buf)?.0 as usize; + let len = buf.get_variable::() as usize; *forward = Vec::with_capacity(len); for _ in 0..len { - let id = VarI32::decode(&mut buf)?.0 as usize; + let id = buf.get_variable::() as usize; forward.push(self.list.of_raw(id).ok_or_else(|| { io::Error::new(ErrorKind::InvalidData, Error::UnknownId(id)) })?); @@ -358,38 +349,13 @@ mod _edcode { } Ok(()) } - } - impl Palette - where - L: for<'a> IndexToRaw<&'a T>, - { - /// Returns the encoded length of this palette. - /// - /// # Errors - /// - /// - Returns `Err` if the palette is uninitialized. - /// - Returns `Err` if the palette entry is unknown. #[inline] - pub fn encoded_len(&self) -> Result { - match &self.internal { - PaletteImpl::Singular(Some(entry)) => self - .list - .raw_id(entry) - .ok_or(Error::UnknownEntry) - .map(|id| VarI32(id as i32).encoded_len()), - PaletteImpl::Singular(None) => Err(Error::Uninitialized), - PaletteImpl::Array(forward) | PaletteImpl::BiMap { forward, .. } => { - let mut len = VarI32(forward.len() as i32).encoded_len(); - for entry in forward { - len += VarI32(self.list.raw_id(entry).ok_or(Error::UnknownEntry)? as i32) - .encoded_len(); - } - Ok(len) - } - PaletteImpl::Direct => Ok(0), - } + fn decode(_buf: B) -> Result> { + Err("palettes does not support non-in-place decoding".into()) } + + const SUPPORT_NON_IN_PLACE: bool = false; } } diff --git a/crates/core/registry/Cargo.toml b/crates/core/registry/Cargo.toml index 92dc3e2..7c00b81 100644 --- a/crates/core/registry/Cargo.toml +++ b/crates/core/registry/Cargo.toml @@ -14,15 +14,11 @@ maintenance = { status = "passively-maintained" } [dependencies] parking_lot = "0.12" serde = { version = "1.0", optional = true } -rimecraft-edcode = { path = "../../util/edcode", optional = true } -rimecraft-identifier = { path = "../../util/identifier", optional = true, features = [ - "vanilla", -] } +edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2", optional = true } [features] serde = ["dep:serde"] -edcode = ["dep:rimecraft-edcode"] -vanilla-identifier = ["dep:rimecraft-identifier"] +edcode = ["dep:edcode2"] [lints] workspace = true diff --git a/crates/core/registry/src/entry.rs b/crates/core/registry/src/entry.rs index 7b0e50c..0b596c1 100644 --- a/crates/core/registry/src/entry.rs +++ b/crates/core/registry/src/entry.rs @@ -159,59 +159,58 @@ mod serde { #[cfg(feature = "edcode")] mod edcode { - use std::hash::Hash; + use std::{fmt::Display, hash::Hash}; - use rimecraft_edcode::{Decode, Encode, VarI32}; + use edcode2::{Buf, BufExt, BufMut, BufMutExt, Decode, Encode}; use crate::{ProvideRegistry, Reg}; use super::{Entry, RefEntry}; - impl<'r, K, T> Encode for RefEntry + impl<'r, K, T, B> Encode for RefEntry where - K: Hash + Eq + Clone + 'r, + K: Hash + Eq + Clone + Display + 'r, T: ProvideRegistry<'r, K, T> + 'r, + B: BufMut, { - fn encode(&self, buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { let id = Reg::raw_id(T::registry().get(self.key()).ok_or_else(|| { - std::io::Error::new(std::io::ErrorKind::InvalidData, "unknown registry key") + edcode2::BoxedError::<'static>::from(format!( + "unknown registry id {}", + self.key().value() + )) })?); - VarI32((id + 1) as i32).encode(buf) + buf.put_variable((id + 1) as u32); + Ok(()) } } - impl<'a, 'r, K, T> Decode for &'a RefEntry + impl<'a, 'r, 'de, K, T, B> Decode<'de, B> for &'a RefEntry where 'r: 'a, K: 'r, T: ProvideRegistry<'r, K, T> + 'r, + B: Buf, { - fn decode(buf: B) -> Result - where - B: rimecraft_edcode::bytes::Buf, - { - let id = (VarI32::decode(buf)?.0 - 1) as usize; - T::registry().of_raw(id).map(From::from).ok_or_else(|| { - std::io::Error::new(std::io::ErrorKind::InvalidData, "unknown registry id") - }) + fn decode(mut buf: B) -> Result> { + let id = buf.get_variable::() as usize - 1; + T::registry() + .of_raw(id) + .map(From::from) + .ok_or_else(|| format!("unknown registry id: {}", id).into()) } } - impl<'r, K, T> Encode for Entry<'_, K, T> + impl<'r, K, T, B> Encode for Entry<'_, K, T> where - K: Hash + Eq + Clone + 'r, - T: ProvideRegistry<'r, K, T> + Encode + 'r, + K: Hash + Eq + Clone + Display + 'r, + T: ProvideRegistry<'r, K, T> + Encode + 'r, + B: BufMut, { - fn encode(&self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { match self { Entry::Direct(value) => { - VarI32(0).encode(&mut buf)?; + buf.put_variable(0i32); value.encode(buf) } Entry::Ref(entry) => entry.encode(buf), @@ -219,25 +218,21 @@ mod edcode { } } - impl<'a, 'r, K, T> Decode for Entry<'a, K, T> + impl<'a, 'r, 'de, K, T, B> Decode<'de, B> for Entry<'a, K, T> where 'r: 'a, K: 'r, - T: ProvideRegistry<'r, K, T> + Decode + 'r, + T: ProvideRegistry<'r, K, T> + Decode<'de, B> + 'r, + B: Buf, { - fn decode(mut buf: B) -> Result - where - B: rimecraft_edcode::bytes::Buf, - { - let id = VarI32::decode(&mut buf)?.0; + fn decode(mut buf: B) -> Result> { + let id = buf.get_variable::() as usize; match id { 0 => T::decode(buf).map(Entry::Direct), id => T::registry() - .of_raw((id - 1) as usize) + .of_raw(id - 1) .map(|r| Entry::Ref(r.into())) - .ok_or_else(|| { - std::io::Error::new(std::io::ErrorKind::InvalidData, "unknown registry id") - }), + .ok_or_else(|| format!("unknown registry id: {}", id - 1).into()), } } } diff --git a/crates/core/registry/src/key.rs b/crates/core/registry/src/key.rs index 40f1f9b..f7fd75e 100644 --- a/crates/core/registry/src/key.rs +++ b/crates/core/registry/src/key.rs @@ -139,79 +139,65 @@ mod serde { /// Helper module for `edcode` support. #[cfg(feature = "edcode")] pub mod edcode { - use rimecraft_edcode::{bytes, Decode, Encode}; + + use edcode2::{Decode, Encode}; use crate::ProvideRegistry; use super::{Key, Root}; - impl Encode for Key + impl Encode for Key where - K: Encode, + K: Encode, { #[inline] - fn encode(&self, buf: B) -> Result<(), std::io::Error> - where - B: bytes::BufMut, - { + fn encode(&self, buf: B) -> Result<(), edcode2::BoxedError<'static>> { self.value.encode(buf) } } - impl<'r, K, T> Decode for Key + impl<'r, 'de, K, T, B> Decode<'de, B> for Key where - K: Decode + Clone + 'r, + K: Decode<'de, B> + Clone + 'r, T: ProvideRegistry<'r, K, T> + 'r, { #[inline] - fn decode(buf: B) -> Result - where - B: bytes::Buf, - { + fn decode(buf: B) -> Result> { let value = K::decode(buf)?; Ok(Key::new(T::registry().key.value.to_owned(), value)) } } - /// Serde wrapper for registry reference keys. + /// Wrapper for registry reference keys. #[derive(Debug, Clone, Copy)] pub struct RegRef(pub T); - impl Encode for RegRef<&Key> + impl Encode for RegRef<&Key> where - K: Encode, + K: Encode, { #[inline] - fn encode(&self, buf: B) -> Result<(), std::io::Error> - where - B: bytes::BufMut, - { + fn encode(&self, buf: B) -> Result<(), edcode2::BoxedError<'static>> { self.0.value.encode(buf) } } - impl Encode for RegRef> + impl Encode for RegRef> where - K: Encode, + K: Encode, { #[inline] - fn encode(&self, buf: B) -> Result<(), std::io::Error> - where - B: bytes::BufMut, - { + fn encode(&self, buf: B) -> Result<(), edcode2::BoxedError<'static>> { RegRef(&self.0).encode(buf) } } - impl<'r, K, T> Decode for RegRef> + impl<'r, 'de, K, T, B> Decode<'de, B> for RegRef> where - K: Decode + Clone + Root + 'r, + K: Decode<'de, B> + Clone + Root + 'r, { #[inline] - fn decode(buf: B) -> Result - where - B: bytes::Buf, - { + fn decode(buf: B) -> Result> { Ok(Self(Key::new(K::root(), K::decode(buf)?))) } } diff --git a/crates/core/registry/src/lib.rs b/crates/core/registry/src/lib.rs index df5cdc1..93c8218 100644 --- a/crates/core/registry/src/lib.rs +++ b/crates/core/registry/src/lib.rs @@ -616,34 +616,33 @@ mod serde { #[cfg(feature = "edcode")] mod edcode { - use rimecraft_edcode::{Decode, Encode, VarI32}; + + use edcode2::{Buf, BufExt, BufMut, BufMutExt, Decode, Encode}; use crate::{ProvideRegistry, Reg}; - impl Encode for Reg<'_, K, T> { - #[inline] - fn encode(&self, buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { - VarI32(self.raw as i32).encode(buf) + impl Encode for Reg<'_, K, T> + where + B: BufMut, + { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { + buf.put_variable(self.raw as u32); + Ok(()) } } - impl<'a, 'r, K, T> Decode for Reg<'a, K, T> + impl<'a, 'r, 'de, K, T, B> Decode<'de, B> for Reg<'a, K, T> where 'r: 'a, K: 'r, T: ProvideRegistry<'r, K, T> + 'r, + B: Buf, { - fn decode(buf: B) -> Result - where - B: rimecraft_edcode::bytes::Buf, - { - let id = VarI32::decode(buf)?.0 as usize; + fn decode(mut buf: B) -> Result> { + let id = buf.get_variable::() as usize; T::registry() .of_raw(id) - .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid id")) + .ok_or_else(|| format!("invalid id: {}", id).into()) } } } @@ -651,29 +650,5 @@ mod edcode { #[allow(dead_code)] type BoxedError = Box; -#[cfg(feature = "vanilla-identifier")] -/// Vanilla root registry key. -pub const VANILLA_ROOT_KEY: rimecraft_identifier::vanilla::Identifier = - rimecraft_identifier::vanilla::Identifier::new( - rimecraft_identifier::vanilla::MINECRAFT, - rimecraft_identifier::vanilla::Path::new_unchecked("root"), - ); - -#[cfg(feature = "vanilla-identifier")] -impl crate::key::Root for rimecraft_identifier::vanilla::Identifier { - #[inline(always)] - fn root() -> Self { - VANILLA_ROOT_KEY - } -} - -#[cfg(feature = "vanilla-identifier")] -#[doc = "`Registry` using vanilla `Identifier`."] -pub type VanillaRegistry = Registry; - -#[cfg(feature = "vanilla-identifier")] -#[doc = "Mutable `Registry` using vanilla `Identifier`."] -pub type VanillaRegistryMut = RegistryMut; - #[cfg(test)] mod tests; diff --git a/crates/core/world/Cargo.toml b/crates/core/world/Cargo.toml index 76d198e..2c38932 100644 --- a/crates/core/world/Cargo.toml +++ b/crates/core/world/Cargo.toml @@ -25,14 +25,14 @@ rimecraft-packed-int-array = { path = "../../util/packed-int-array" } # External utils serde = { version = "1.0", features = ["derive"] } serde_repr = "0.1" -rimecraft-edcode = { path = "../../util/edcode", optional = true } +edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2", optional = true } parking_lot = "0.12" fastnbt = "2.5" ahash = "0.8" [features] default = ["edcode"] -edcode = ["dep:rimecraft-edcode", "rimecraft-chunk-palette/edcode"] +edcode = ["dep:edcode2", "rimecraft-chunk-palette/edcode"] [lints] workspace = true diff --git a/crates/core/world/src/chunk/section.rs b/crates/core/world/src/chunk/section.rs index fa7f212..d0c34e2 100644 --- a/crates/core/world/src/chunk/section.rs +++ b/crates/core/world/src/chunk/section.rs @@ -290,27 +290,26 @@ pub trait ComputeIndex: ProvidePalette { #[cfg(feature = "edcode")] mod _edcode { - use rimecraft_edcode::{Encode, Update}; + + use edcode2::{Buf, BufMut, Decode, Encode}; use super::*; - impl<'w, Cx> Encode for ChunkSection<'w, Cx> + impl<'w, Cx, B> Encode for ChunkSection<'w, Cx> where Cx: ChunkCx<'w>, Cx::BlockStateList: for<'a> PalIndexToRaw<&'a BlockState<'w, Cx>>, Cx::BiomeList: for<'a> PalIndexToRaw<&'a IBiome<'w, Cx>>, + B: BufMut, { - fn encode(&self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { buf.put_i16(self.ne_block_c as i16); self.bsc.encode(&mut buf)?; self.bic.encode(&mut buf) } } - impl<'w, Cx> Update for ChunkSection<'w, Cx> + impl<'w, 'de, Cx, B> Decode<'de, B> for ChunkSection<'w, Cx> where Cx: ChunkCx<'w>, @@ -322,30 +321,24 @@ mod _edcode { Cx: ProvidePalette>, Cx: ProvidePalette>, + + B: Buf, { - fn update(&mut self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::Buf, - { + fn decode_in_place(&mut self, mut buf: B) -> Result<(), edcode2::BoxedError<'de>> { self.ne_block_c = buf.get_i16() as u16; - self.bsc.update(&mut buf)?; + self.bsc.decode_in_place(&mut buf)?; let mut sliced = self.bic.to_slice(); - sliced.update(&mut buf)?; + sliced.decode_in_place(&mut buf)?; self.bic = sliced; Ok(()) } - } - impl<'w, Cx> ChunkSection<'w, Cx> - where - Cx: ChunkCx<'w>, - Cx::BlockStateList: for<'a> PalIndexToRaw<&'a BlockState<'w, Cx>>, - Cx::BiomeList: for<'a> PalIndexToRaw<&'a IBiome<'w, Cx>>, - { - /// Returns the encoded length of the chunk section. - pub fn encoded_len(&self) -> usize { - 2 + self.bsc.encoded_len() + self.bic.encoded_len() + #[inline] + fn decode(_buf: B) -> Result> { + Err("chunk sections does not support non-in-place decoding".into()) } + + const SUPPORT_NON_IN_PLACE: bool = false; } impl<'w, Cx> ChunkSection<'w, Cx> @@ -359,12 +352,15 @@ mod _edcode { { /// Updates the chunk section from the given biome packet buffer. #[allow(clippy::missing_errors_doc)] - pub fn update_from_biome_buf(&mut self, mut buf: B) -> Result<(), std::io::Error> + pub fn update_from_biome_buf( + &mut self, + mut buf: B, + ) -> Result<(), edcode2::BoxedError<'static>> where - B: rimecraft_edcode::bytes::Buf, + B: Buf, { let mut sliced = self.bic.to_slice(); - sliced.update(&mut buf)?; + sliced.decode_in_place(&mut buf)?; self.bic = sliced; Ok(()) } diff --git a/crates/util/edcode-derive-tests/src/lib.rs b/crates/util/edcode-derive-tests/src/lib.rs index 851525a..6e3bc96 100644 --- a/crates/util/edcode-derive-tests/src/lib.rs +++ b/crates/util/edcode-derive-tests/src/lib.rs @@ -1,5 +1,7 @@ //! Tests for `rimecraft-edcode-derive` crate. +#![allow(deprecated)] + #[cfg(test)] mod tests { use rimecraft_edcode::{bytes::BytesMut, Decode, Encode}; diff --git a/crates/util/edcode/Cargo.toml b/crates/util/edcode/Cargo.toml index 51fb8e7..3f953ea 100644 --- a/crates/util/edcode/Cargo.toml +++ b/crates/util/edcode/Cargo.toml @@ -12,6 +12,7 @@ categories = ["encoding"] maintenance = { status = "passively-maintained" } [dependencies] +edcode2 = { path = "../edcode2", package = "rimecraft-edcode2" } bytes = "1.6" serde = { version = "1.0", optional = true } rimecraft-edcode-derive = { path = "../edcode-derive", optional = true } diff --git a/crates/util/edcode/src/imp.rs b/crates/util/edcode/src/imp.rs deleted file mode 100644 index f73bfaf..0000000 --- a/crates/util/edcode/src/imp.rs +++ /dev/null @@ -1,477 +0,0 @@ -use std::{collections::HashMap, hash::Hash}; - -use crate::*; - -impl Encode for bytes::Bytes { - #[inline] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - VarI32(self.len() as i32).encode(&mut buf)?; - buf.put_slice(&self[..]); - Ok(()) - } -} - -impl Decode for bytes::Bytes { - #[inline] - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let len = VarI32::decode(&mut buf)?.0 as usize; - Ok(buf.copy_to_bytes(len)) - } -} - -macro_rules! edcode_primitive { - ($($t:ty => $fe:ident, $fd:ident),*) => { - $( - impl Encode for $t { - #[inline(always)] - fn encode(&self, mut buf: B) -> Result<(), io::Error> { - buf.$fe(*self); - Ok(()) - } - } - - impl Decode for $t { - #[inline(always)] - fn decode(mut buf: B) -> Result{ - Ok(buf.$fd()) - } - } - )* - }; -} - -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 { - #[inline(always)] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - buf.put_u8(if *self { 1 } else { 0 }); - Ok(()) - } -} - -impl Decode for bool { - #[inline(always)] - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - Ok(buf.get_u8() == 0) - } -} - -#[cfg(feature = "fastnbt")] -impl Encode for Nbt -where - T: serde::Serialize, -{ - #[inline] - fn encode(&self, buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - fastnbt::to_writer(bytes::BufMut::writer(buf), &self.0) - .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err)) - } -} - -#[cfg(feature = "fastnbt")] -impl Decode for Nbt -where - T: for<'a> serde::Deserialize<'a>, -{ - #[inline] - fn decode(buf: B) -> Result - where - B: bytes::Buf, - { - fastnbt::from_reader(bytes::Buf::reader(buf)) - .map(Self) - .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err)) - } -} - -#[cfg(feature = "json")] -impl Encode for Json -where - T: serde::Serialize, -{ - #[inline] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - 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 Decode for Json -where - T: for<'a> serde::de::Deserialize<'a>, -{ - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let len = VarI32::decode(&mut buf)?.0 as usize; - use std::io::Read; - serde_json::from_reader(bytes::Buf::reader(buf).take(len as u64)) - .map(Self) - .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err)) - } -} - -impl Encode for VarI32 { - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - let mut i = self.0; - while i & -128 != 0 { - buf.put_u8((i & 127 | 128) as u8); - i >>= 7; - } - buf.put_u8(i as u8); - Ok(()) - } -} - -impl Decode for VarI32 { - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let mut i = 0; - let mut j = 0; - loop { - let b = buf.get_u8(); - i |= ((b & 127) as i32) << (j * 7); - j += 1; - if j > 5 { - return Err(io::Error::new( - io::ErrorKind::InvalidData, - "VarI32 too long", - )); - } - if (b & 128) != 128 { - return Ok(Self(i)); - } - } - } -} - -impl Encode for str { - #[inline] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - let bs = self.as_bytes(); - VarI32(bs.len() as i32).encode(&mut buf)?; - buf.put_slice(bs); - Ok(()) - } -} - -impl Encode for String { - #[inline] - fn encode(&self, buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - str::encode(self, buf) - } -} - -impl Decode for String { - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let len = VarI32::decode(&mut buf)?.0 as usize; - let mut vec = vec![0; len]; - buf.copy_to_slice(&mut vec[..]); - String::from_utf8(vec).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - } -} - -impl Encode for [T] -where - T: Encode, -{ - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - VarI32(self.len() as i32).encode(&mut buf)?; - for object in self.iter() { - object.encode(&mut buf)?; - } - Ok(()) - } -} - -impl Decode for Vec -where - T: Decode, -{ - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let len = VarI32::decode(&mut buf)?.0 as usize; - let mut vec = Vec::with_capacity(len); - - for _ in 0..len { - vec.push(T::decode(&mut buf)?); - } - - Ok(vec) - } -} - -impl Encode for HashMap -where - K: Encode, - V: Encode, -{ - #[inline] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - VarI32(self.len() as i32).encode(&mut buf).unwrap(); - for (key, value) in self.iter() { - key.encode(&mut buf)?; - value.encode(&mut buf)?; - } - Ok(()) - } -} - -impl Decode for HashMap -where - K: Decode + Hash + Eq, - V: Decode, -{ - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let len = VarI32::decode(&mut buf)?.0 as usize; - let mut map = HashMap::with_capacity(len); - for _ in 0..len { - let obj = K::decode(&mut buf)?; - let obj1 = V::decode(&mut buf)?; - map.insert(obj, obj1); - } - Ok(map) - } -} - -impl Encode for Option -where - T: Encode, -{ - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - if let Some(value) = self { - true.encode(&mut buf).unwrap(); - value.encode(&mut buf) - } else { - false.encode(&mut buf).unwrap(); - Ok(()) - } - } -} - -impl Decode for Option -where - T: Decode, -{ - #[allow(clippy::if_then_some_else_none)] - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - Ok(if bool::decode(&mut buf).unwrap() { - Some(T::decode(&mut buf)?) - } else { - None - }) - } -} - -#[cfg(feature = "uuid")] -impl Encode for uuid::Uuid { - #[inline] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - let (a, b) = self.as_u64_pair(); - buf.put_u64(a); - buf.put_u64(b); - Ok(()) - } -} - -#[cfg(feature = "uuid")] -impl Decode for uuid::Uuid { - #[inline] - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let a = buf.get_u64(); - let b = buf.get_u64(); - Ok(uuid::Uuid::from_u64_pair(a, b)) - } -} - -#[cfg(feature = "fastnbt")] -impl Encode for HashMap { - #[inline] - fn encode(&self, buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - Nbt(self).encode(buf) - } -} - -#[cfg(feature = "fastnbt")] -impl Decode for HashMap { - #[inline] - fn decode(buf: B) -> Result - where - B: bytes::Buf, - { - Nbt::decode(buf).map(|nbt| nbt.0) - } -} - -#[cfg(feature = "glam")] -impl Encode for glam::Vec3 { - #[inline] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - buf.put_f32(self.x); - buf.put_f32(self.y); - buf.put_f32(self.z); - Ok(()) - } -} - -#[cfg(feature = "glam")] -impl Decode for glam::Vec3 { - #[inline] - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let x = buf.get_f32(); - let y = buf.get_f32(); - let z = buf.get_f32(); - Ok(glam::Vec3 { x, y, z }) - } -} - -#[cfg(feature = "glam")] -impl Encode for glam::Quat { - #[inline] - fn encode(&self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - buf.put_f32(self.x); - buf.put_f32(self.y); - buf.put_f32(self.z); - buf.put_f32(self.w); - Ok(()) - } -} - -#[cfg(feature = "glam")] -impl Decode for glam::Quat { - #[inline] - fn decode(mut buf: B) -> Result - where - B: bytes::Buf, - { - let x = buf.get_f32(); - let y = buf.get_f32(); - let z = buf.get_f32(); - let w = buf.get_f32(); - Ok(glam::Quat::from_xyzw(x, y, z, w)) - } -} - -impl Encode for () { - #[inline] - fn encode(&self, _buf: B) -> Result<(), io::Error> - where - B: bytes::BufMut, - { - Ok(()) - } -} - -impl Decode for () { - #[inline] - fn decode(_buf: B) -> Result - where - B: bytes::Buf, - { - Ok(()) - } -} - -impl Update for [T] -where - T: Update, -{ - fn update(&mut self, mut buf: B) -> Result<(), io::Error> - where - B: bytes::Buf, - { - let len = VarI32::decode(&mut buf)?.0 as usize; - if len > self.len() { - return Err(io::Error::new( - io::ErrorKind::InvalidData, - "Update length longer than array", - )); - } - self.iter_mut() - .take(len) - .try_for_each(|x| x.update(&mut buf)) - } -} diff --git a/crates/util/edcode/src/lib.rs b/crates/util/edcode/src/lib.rs index 006c02f..9c61a14 100644 --- a/crates/util/edcode/src/lib.rs +++ b/crates/util/edcode/src/lib.rs @@ -1,9 +1,6 @@ //! Encoding and decoding utilities for packet buffers. -mod imp; - -#[cfg(test)] -mod tests; +#![deprecated = "use the `edcode2` crate instead"] use std::io; @@ -62,28 +59,45 @@ pub trait Update { B: bytes::Buf; } -impl Update for T +impl Encode for T where - T: Decode, + T: for<'a> edcode2::Encode<&'a mut dyn bytes::BufMut> + ?Sized, { - #[inline] - fn update(&mut self, buf: B) -> Result<(), io::Error> + fn encode(&self, mut buf: B) -> Result<(), io::Error> where - B: bytes::Buf, + B: bytes::BufMut, { - self.decode_in_place(buf) + edcode2::Encode::encode(self, &mut buf) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) } } -/// Layer for encoding and decoding in nbt binary format for packets. -#[cfg(feature = "fastnbt")] -#[derive(Debug)] -pub struct Nbt(pub T); +impl Decode for T +where + T: for<'a> edcode2::Decode<'static, &'a mut dyn bytes::Buf>, +{ + fn decode(mut buf: B) -> Result + where + B: bytes::Buf, + { + let val: &mut dyn bytes::Buf = &mut buf; + edcode2::Decode::decode(val).map_err(|err| io::Error::new(io::ErrorKind::Other, err)) + } +} -/// Layer for encoding and decoding in json utf8 for packets. -#[cfg(feature = "json")] -#[derive(Debug)] -pub struct Json(pub T); +impl Update for T +where + T: for<'a> edcode2::Decode<'static, &'a mut dyn bytes::Buf>, +{ + fn update(&mut self, mut buf: B) -> Result<(), io::Error> + where + B: bytes::Buf, + { + let val: &mut dyn bytes::Buf = &mut buf; + edcode2::Decode::decode_in_place(self, val) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) + } +} /// Represents a variable integer. #[derive(Debug)] @@ -106,3 +120,16 @@ impl VarI32 { false } } + +impl edcode2::Encode for VarI32 { + fn encode(&self, buf: B) -> Result<(), edcode2::BoxedError<'static>> { + edcode2::Encode::encode(&edcode2::Variable(self.0), buf) + } +} + +impl<'de, B: bytes::Buf> edcode2::Decode<'de, B> for VarI32 { + fn decode(buf: B) -> Result> { + as edcode2::Decode<'de, B>>::decode(buf) + .map(|edcode2::Variable(i)| Self(i)) + } +} diff --git a/crates/util/edcode/src/tests.rs b/crates/util/edcode/src/tests.rs deleted file mode 100644 index d99d6a1..0000000 --- a/crates/util/edcode/src/tests.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::{Decode, Encode}; - -#[test] -fn var_i32_ed() { - use super::VarI32; - - let num = 114514; - - let mut bytes_mut = bytes::BytesMut::new(); - VarI32(num).encode(&mut bytes_mut).unwrap(); - - assert_eq!(bytes_mut.len(), VarI32(num).encoded_len()); - - let mut bytes: bytes::Bytes = bytes_mut.into(); - assert_eq!(VarI32::decode(&mut bytes).unwrap().0, num); -} diff --git a/crates/core/packet-codec/Cargo.toml b/crates/util/edcode2/Cargo.toml similarity index 92% rename from crates/core/packet-codec/Cargo.toml rename to crates/util/edcode2/Cargo.toml index 587b80d..53ce3ec 100644 --- a/crates/core/packet-codec/Cargo.toml +++ b/crates/util/edcode2/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rimecraft-packet-codec" +name = "rimecraft-edcode2" version = "0.1.0" edition = "2021" authors = ["JieningYu "] diff --git a/crates/core/packet-codec/rime-target.toml b/crates/util/edcode2/rime-target.toml similarity index 100% rename from crates/core/packet-codec/rime-target.toml rename to crates/util/edcode2/rime-target.toml diff --git a/crates/core/packet-codec/src/codecs.rs b/crates/util/edcode2/src/codecs.rs similarity index 94% rename from crates/core/packet-codec/src/codecs.rs rename to crates/util/edcode2/src/codecs.rs index 32cc9c9..1b72153 100644 --- a/crates/core/packet-codec/src/codecs.rs +++ b/crates/util/edcode2/src/codecs.rs @@ -112,7 +112,7 @@ macro_rules! unsigned_variable_primitives { } unsigned_variable_primitives! { - u16, u32, u64, u128, usize, + u16, u32, u64, u128, } macro_rules! signed_variable_primitives { @@ -141,7 +141,6 @@ signed_variable_primitives! { i32 => u32, i64 => u64, i128 => u128, - isize => usize, } impl Encode for [T] @@ -167,6 +166,34 @@ where } } +impl<'de, B: Buf, T> Decode<'de, B> for &mut [T] +where + T: for<'a> Decode<'de, &'a mut B>, +{ + fn decode_in_place(&mut self, mut buf: B) -> Result<(), BoxedError<'de>> { + let len = buf.get_variable::() as usize; + if self.len() < len { + return Err(format!( + "slice too short: received {} items, have {} slots", + len, + self.len() + ) + .into()); + } + for val in self[..len].iter_mut() { + val.decode_in_place(&mut buf)?; + } + Ok(()) + } + + #[inline] + fn decode(_buf: B) -> Result> { + Err("slices does not support non-in-place decoding".into()) + } + + const SUPPORT_NON_IN_PLACE: bool = false; +} + impl<'de, B: Buf, T> Decode<'de, B> for Vec where T: for<'a> Decode<'de, &'a mut B>, diff --git a/crates/core/packet-codec/src/lib.rs b/crates/util/edcode2/src/lib.rs similarity index 89% rename from crates/core/packet-codec/src/lib.rs rename to crates/util/edcode2/src/lib.rs index 1f7e01f..b540141 100644 --- a/crates/core/packet-codec/src/lib.rs +++ b/crates/util/edcode2/src/lib.rs @@ -1,11 +1,9 @@ //! Traits for serialization and deserialization of packets. -#![deprecated = "migration to the `edcode` crate is recommended"] - use std::marker::PhantomData; -use bytes::{Buf, BufMut}; -use codecs::Variable; +pub use bytes::{Buf, BufMut}; +pub use codecs::Variable; pub mod codecs; @@ -24,20 +22,13 @@ pub trait Decode<'de, B>: Sized { /// Decodes this packet from the buffer. #[allow(clippy::missing_errors_doc)] fn decode(buf: B) -> Result>; -} -/// Packet decoders that decode in place. -pub trait DecodeInPlace<'de, B> { + /// Whether this decoder supports non-in-place decoding. + const SUPPORT_NON_IN_PLACE: bool = true; + /// Decodes this packet from the buffer in place. #[allow(clippy::missing_errors_doc)] - fn decode_in_place(&mut self, buf: B) -> Result<(), BoxedError<'de>>; -} - -impl<'de, B, T> DecodeInPlace<'de, B> for T -where - T: Decode<'de, B>, -{ - #[inline] + #[inline(always)] fn decode_in_place(&mut self, buf: B) -> Result<(), BoxedError<'de>> { *self = Decode::decode(buf)?; Ok(()) diff --git a/crates/core/packet-codec/src/tests.rs b/crates/util/edcode2/src/tests.rs similarity index 100% rename from crates/core/packet-codec/src/tests.rs rename to crates/util/edcode2/src/tests.rs diff --git a/crates/util/voxel-math/Cargo.toml b/crates/util/voxel-math/Cargo.toml index 0a63d01..a63e0e3 100644 --- a/crates/util/voxel-math/Cargo.toml +++ b/crates/util/voxel-math/Cargo.toml @@ -12,14 +12,14 @@ categories = ["game-development"] maintenance = { status = "passively-maintained" } [dependencies] -rimecraft-edcode = { path = "../../util/edcode", optional = true } +edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } -glam = "0.25" +glam = "0.28.0" [features] default = ["serde", "edcode"] serde = ["dep:serde"] -edcode = ["dep:rimecraft-edcode"] +edcode = ["dep:edcode2"] [lints] workspace = true diff --git a/crates/util/voxel-math/src/block_pos.rs b/crates/util/voxel-math/src/block_pos.rs index e425140..c2bdc98 100644 --- a/crates/util/voxel-math/src/block_pos.rs +++ b/crates/util/voxel-math/src/block_pos.rs @@ -213,27 +213,30 @@ mod _serde { #[cfg(feature = "edcode")] mod edcode { - use rimecraft_edcode::{Decode, Encode}; + + use edcode2::{Buf, BufMut, Decode, Encode}; use super::*; - impl Encode for BlockPos { + impl Encode for BlockPos + where + B: BufMut, + { #[inline] - fn encode(&self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { buf.put_i64((*self).into()); Ok(()) } } - impl Decode for BlockPos { + impl<'de, B> Decode<'de, B> for BlockPos + where + B: Buf, + { + const SUPPORT_NON_IN_PLACE: bool = true; + #[inline] - fn decode(mut buf: B) -> Result - where - B: rimecraft_edcode::bytes::Buf, - { + fn decode(mut buf: B) -> Result> { Ok(buf.get_i64().into()) } } diff --git a/crates/util/voxel-math/src/chunk_pos.rs b/crates/util/voxel-math/src/chunk_pos.rs index f9dfb57..0de0109 100644 --- a/crates/util/voxel-math/src/chunk_pos.rs +++ b/crates/util/voxel-math/src/chunk_pos.rs @@ -74,27 +74,27 @@ impl From for (i32, i32) { #[cfg(feature = "edcode")] mod _edcode { - use rimecraft_edcode::{Decode, Encode}; + use edcode2::{Buf, BufMut, Decode, Encode}; use crate::ChunkPos; - impl Encode for ChunkPos { + impl Encode for ChunkPos + where + B: BufMut, + { #[inline] - fn encode(&self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { buf.put_u64((*self).into()); Ok(()) } } - impl Decode for ChunkPos { + impl<'de, B> Decode<'de, B> for ChunkPos + where + B: Buf, + { #[inline] - fn decode(mut buf: B) -> Result - where - B: rimecraft_edcode::bytes::Buf, - { + fn decode(mut buf: B) -> Result> { Ok(buf.get_u64().into()) } } diff --git a/crates/util/voxel-math/src/chunk_section_pos.rs b/crates/util/voxel-math/src/chunk_section_pos.rs index 3195d44..d551dbb 100644 --- a/crates/util/voxel-math/src/chunk_section_pos.rs +++ b/crates/util/voxel-math/src/chunk_section_pos.rs @@ -113,27 +113,28 @@ impl From for u64 { #[cfg(feature = "edcode")] mod _edcode { - use rimecraft_edcode::{Decode, Encode}; + + use edcode2::{Buf, BufMut, Decode, Encode}; use super::*; - impl Encode for ChunkSectionPos { + impl Encode for ChunkSectionPos + where + B: BufMut, + { #[inline] - fn encode(&self, mut buf: B) -> Result<(), std::io::Error> - where - B: rimecraft_edcode::bytes::BufMut, - { + fn encode(&self, mut buf: B) -> Result<(), edcode2::BoxedError<'static>> { buf.put_u64((*self).into()); Ok(()) } } - impl Decode for ChunkSectionPos { + impl<'de, B> Decode<'de, B> for ChunkSectionPos + where + B: Buf, + { #[inline] - fn decode(mut buf: B) -> Result - where - B: rimecraft_edcode::bytes::Buf, - { + fn decode(mut buf: B) -> Result> { Ok(buf.get_u64().into()) } }