diff --git a/crates/valence_protocol/src/lib.rs b/crates/valence_protocol/src/lib.rs index 6f02f34..9cd9d7d 100644 --- a/crates/valence_protocol/src/lib.rs +++ b/crates/valence_protocol/src/lib.rs @@ -261,9 +261,9 @@ pub trait Decode<'a>: Sized { /// type must implement [`Encode`], [`Decode`], and [`fmt::Debug`]. /// /// ``` -/// use valence_protocol::{Encode, Packet}; +/// use valence_protocol::{Decode, Encode, Packet}; /// -/// #[derive(Encode, Packet, Debug)] +/// #[derive(Encode, Decode, Packet, Debug)] /// #[packet_id = 42] /// struct MyStruct { /// first: i32, @@ -282,6 +282,11 @@ pub trait Packet<'a>: Sized + fmt::Debug { /// The packet returned by [`Self::packet_id`]. If the packet ID is not /// statically known, then a negative value is used instead. const PACKET_ID: i32 = -1; + /// Returns the ID of this packet. + fn packet_id(&self) -> i32; + /// Returns the name of this packet, typically without whitespace or + /// additional formatting. + fn packet_name(&self) -> &str; /// Like [`Encode::encode`], but a leading [`VarInt`] packet ID must be /// written first. /// @@ -292,14 +297,14 @@ pub trait Packet<'a>: Sized + fmt::Debug { /// /// [`VarInt`]: var_int::VarInt fn decode_packet(r: &mut &'a [u8]) -> Result; - /// Returns the ID of this packet. - fn packet_id(&self) -> i32; } #[allow(dead_code)] #[cfg(test)] -mod derive_tests { +mod tests { use super::*; + use crate::packet::c2s::play::HandSwingC2s; + use crate::packet::C2sPlayPacket; #[derive(Encode, Decode, Packet, Debug)] #[packet_id = 1] @@ -359,18 +364,39 @@ mod derive_tests { } #[allow(unconditional_recursion)] - fn has_impls<'a, T>() + fn assert_has_impls<'a, T>() where T: Encode + Decode<'a> + Packet<'a>, { - has_impls::(); - has_impls::(); - has_impls::(); - has_impls::(); - has_impls::(); - has_impls::(); - has_impls::(); - has_impls::(); - has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + } + + #[test] + fn packet_name() { + assert_eq!(UnitStruct.packet_name(), "UnitStruct"); + assert_eq!(RegularEnum::Empty.packet_name(), "RegularEnum"); + assert_eq!( + StructWithGenerics { + foo: "blah", + bar: () + } + .packet_name(), + "StructWithGenerics" + ); + assert_eq!( + C2sPlayPacket::HandSwingC2s(HandSwingC2s { + hand: Default::default() + }) + .packet_name(), + "HandSwingC2s" + ); } } diff --git a/crates/valence_protocol/src/packet.rs b/crates/valence_protocol/src/packet.rs index bdb3772..30a5b80 100644 --- a/crates/valence_protocol/src/packet.rs +++ b/crates/valence_protocol/src/packet.rs @@ -41,6 +41,10 @@ macro_rules! packet_group { $packet_id } + fn packet_name(&self) -> &str { + stringify!($packet) + } + #[allow(unused_imports)] fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { use ::valence_protocol::__private::{Encode, Context, VarInt}; @@ -73,6 +77,14 @@ macro_rules! packet_group { } } + fn packet_name(&self) -> &str { + match self { + $( + Self::$packet(pkt) => pkt.packet_name(), + )* + } + } + fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { use crate::Encode; use crate::var_int::VarInt; @@ -142,6 +154,10 @@ macro_rules! packet_group { $packet_id } + fn packet_name(&self) -> &str { + stringify!($packet_name) + } + #[allow(unused_imports)] fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { use ::valence_protocol::__private::{Encode, Context, VarInt}; @@ -174,6 +190,14 @@ macro_rules! packet_group { } } + fn packet_name(&self) -> &str { + match self { + $( + Self::$packet(pkt) => pkt.packet_name(), + )* + } + } + fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { use crate::Encode; use crate::var_int::VarInt; diff --git a/crates/valence_protocol/src/types.rs b/crates/valence_protocol/src/types.rs index fbeca4e..96fd90a 100644 --- a/crates/valence_protocol/src/types.rs +++ b/crates/valence_protocol/src/types.rs @@ -16,8 +16,9 @@ pub struct PublicKeyData<'a> { pub signature: &'a [u8], } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug, Encode, Decode)] pub enum Hand { + #[default] Main, Off, } diff --git a/crates/valence_protocol_macros/src/packet.rs b/crates/valence_protocol_macros/src/packet.rs index 565d439..3ad3951 100644 --- a/crates/valence_protocol_macros/src/packet.rs +++ b/crates/valence_protocol_macros/src/packet.rs @@ -36,6 +36,7 @@ pub fn derive_packet(item: TokenStream) -> Result { let (impl_generics, ty_generics, where_clause) = decode_split_for_impl(input.generics, lifetime.clone()); + let name_str = input.ident.to_string(); let name = input.ident; Ok(quote! { @@ -48,6 +49,10 @@ pub fn derive_packet(item: TokenStream) -> Result { #packet_id } + fn packet_name(&self) -> &str { + #name_str + } + fn encode_packet(&self, mut w: impl ::std::io::Write) -> ::valence_protocol::__private::Result<()> { use ::valence_protocol::__private::{Encode, Context, VarInt}; @@ -55,16 +60,18 @@ pub fn derive_packet(item: TokenStream) -> Result { .encode(&mut w) .context("failed to encode packet ID")?; - self.encode(w) + Encode::encode(self, w) } fn decode_packet(r: &mut &#lifetime [u8]) -> ::valence_protocol::__private::Result { - use ::valence_protocol::__private::{Decode, Context, VarInt, ensure}; + use ::valence_protocol::__private::{Decode, Context, VarInt}; let id = VarInt::decode(r).context("failed to decode packet ID")?.0; - ensure!(id == #packet_id, "unexpected packet ID {} (expected {})", id, #packet_id); + ::valence_protocol::__private::ensure!( + id == #packet_id, "unexpected packet ID {} (expected {})", id, #packet_id + ); - Self::decode(r) + Decode::decode(r) } } })