Add packet_name (#274)

## Description

Adds `packet_name` method to the `Packet` trait to help with #238.

## Test Plan

Steps:
1. `cargo t -p valence_protocol`
This commit is contained in:
Ryan Johnson 2023-03-07 04:12:08 -08:00 committed by GitHub
parent a69cc5d1c3
commit e64f1b7123
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 20 deletions

View file

@ -261,9 +261,9 @@ pub trait Decode<'a>: Sized {
/// type must implement [`Encode`], [`Decode`], and [`fmt::Debug`]. /// 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] /// #[packet_id = 42]
/// struct MyStruct { /// struct MyStruct {
/// first: i32, /// 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 /// The packet returned by [`Self::packet_id`]. If the packet ID is not
/// statically known, then a negative value is used instead. /// statically known, then a negative value is used instead.
const PACKET_ID: i32 = -1; 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 /// Like [`Encode::encode`], but a leading [`VarInt`] packet ID must be
/// written first. /// written first.
/// ///
@ -292,14 +297,14 @@ pub trait Packet<'a>: Sized + fmt::Debug {
/// ///
/// [`VarInt`]: var_int::VarInt /// [`VarInt`]: var_int::VarInt
fn decode_packet(r: &mut &'a [u8]) -> Result<Self>; fn decode_packet(r: &mut &'a [u8]) -> Result<Self>;
/// Returns the ID of this packet.
fn packet_id(&self) -> i32;
} }
#[allow(dead_code)] #[allow(dead_code)]
#[cfg(test)] #[cfg(test)]
mod derive_tests { mod tests {
use super::*; use super::*;
use crate::packet::c2s::play::HandSwingC2s;
use crate::packet::C2sPlayPacket;
#[derive(Encode, Decode, Packet, Debug)] #[derive(Encode, Decode, Packet, Debug)]
#[packet_id = 1] #[packet_id = 1]
@ -359,18 +364,39 @@ mod derive_tests {
} }
#[allow(unconditional_recursion)] #[allow(unconditional_recursion)]
fn has_impls<'a, T>() fn assert_has_impls<'a, T>()
where where
T: Encode + Decode<'a> + Packet<'a>, T: Encode + Decode<'a> + Packet<'a>,
{ {
has_impls::<RegularStruct>(); assert_has_impls::<RegularStruct>();
has_impls::<UnitStruct>(); assert_has_impls::<UnitStruct>();
has_impls::<EmptyStruct>(); assert_has_impls::<EmptyStruct>();
has_impls::<TupleStruct>(); assert_has_impls::<TupleStruct>();
has_impls::<StructWithGenerics>(); assert_has_impls::<StructWithGenerics>();
has_impls::<TupleStructWithGenerics>(); assert_has_impls::<TupleStructWithGenerics>();
has_impls::<RegularEnum>(); assert_has_impls::<RegularEnum>();
has_impls::<EmptyEnum>(); assert_has_impls::<EmptyEnum>();
has_impls::<EnumWithGenericsAndTags>(); assert_has_impls::<EnumWithGenericsAndTags>();
}
#[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"
);
} }
} }

View file

@ -41,6 +41,10 @@ macro_rules! packet_group {
$packet_id $packet_id
} }
fn packet_name(&self) -> &str {
stringify!($packet)
}
#[allow(unused_imports)] #[allow(unused_imports)]
fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> {
use ::valence_protocol::__private::{Encode, Context, VarInt}; 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<()> { fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> {
use crate::Encode; use crate::Encode;
use crate::var_int::VarInt; use crate::var_int::VarInt;
@ -142,6 +154,10 @@ macro_rules! packet_group {
$packet_id $packet_id
} }
fn packet_name(&self) -> &str {
stringify!($packet_name)
}
#[allow(unused_imports)] #[allow(unused_imports)]
fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> {
use ::valence_protocol::__private::{Encode, Context, VarInt}; 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<()> { fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> {
use crate::Encode; use crate::Encode;
use crate::var_int::VarInt; use crate::var_int::VarInt;

View file

@ -16,8 +16,9 @@ pub struct PublicKeyData<'a> {
pub signature: &'a [u8], pub signature: &'a [u8],
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] #[derive(Copy, Clone, PartialEq, Eq, Default, Debug, Encode, Decode)]
pub enum Hand { pub enum Hand {
#[default]
Main, Main,
Off, Off,
} }

View file

@ -36,6 +36,7 @@ pub fn derive_packet(item: TokenStream) -> Result<TokenStream> {
let (impl_generics, ty_generics, where_clause) = let (impl_generics, ty_generics, where_clause) =
decode_split_for_impl(input.generics, lifetime.clone()); decode_split_for_impl(input.generics, lifetime.clone());
let name_str = input.ident.to_string();
let name = input.ident; let name = input.ident;
Ok(quote! { Ok(quote! {
@ -48,6 +49,10 @@ pub fn derive_packet(item: TokenStream) -> Result<TokenStream> {
#packet_id #packet_id
} }
fn packet_name(&self) -> &str {
#name_str
}
fn encode_packet(&self, mut w: impl ::std::io::Write) -> ::valence_protocol::__private::Result<()> { fn encode_packet(&self, mut w: impl ::std::io::Write) -> ::valence_protocol::__private::Result<()> {
use ::valence_protocol::__private::{Encode, Context, VarInt}; use ::valence_protocol::__private::{Encode, Context, VarInt};
@ -55,16 +60,18 @@ pub fn derive_packet(item: TokenStream) -> Result<TokenStream> {
.encode(&mut w) .encode(&mut w)
.context("failed to encode packet ID")?; .context("failed to encode packet ID")?;
self.encode(w) Encode::encode(self, w)
} }
fn decode_packet(r: &mut &#lifetime [u8]) -> ::valence_protocol::__private::Result<Self> { fn decode_packet(r: &mut &#lifetime [u8]) -> ::valence_protocol::__private::Result<Self> {
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; 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)
} }
} }
}) })