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`].
///
/// ```
/// 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<Self>;
/// 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::<RegularStruct>();
has_impls::<UnitStruct>();
has_impls::<EmptyStruct>();
has_impls::<TupleStruct>();
has_impls::<StructWithGenerics>();
has_impls::<TupleStructWithGenerics>();
has_impls::<RegularEnum>();
has_impls::<EmptyEnum>();
has_impls::<EnumWithGenericsAndTags>();
assert_has_impls::<RegularStruct>();
assert_has_impls::<UnitStruct>();
assert_has_impls::<EmptyStruct>();
assert_has_impls::<TupleStruct>();
assert_has_impls::<StructWithGenerics>();
assert_has_impls::<TupleStructWithGenerics>();
assert_has_impls::<RegularEnum>();
assert_has_impls::<EmptyEnum>();
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
}
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;

View file

@ -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,
}

View file

@ -36,6 +36,7 @@ pub fn derive_packet(item: TokenStream) -> Result<TokenStream> {
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<TokenStream> {
#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<TokenStream> {
.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<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;
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)
}
}
})