Replaced `PacketArray` trait with `McType` macro
This commit is contained in:
parent
90f2270c78
commit
17c7360c76
|
|
@ -107,3 +107,51 @@ pub fn derive_packet(input: TokenStream) -> TokenStream {
|
|||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(McType)]
|
||||
pub fn derive_mctype_struct(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &input.ident;
|
||||
|
||||
let Data::Struct(data_struct) = input.data else {
|
||||
return syn::Error::new_spanned(name, "McType can only be derived for structs")
|
||||
.to_compile_error()
|
||||
.into();
|
||||
};
|
||||
|
||||
let Fields::Named(fields) = data_struct.fields else {
|
||||
return syn::Error::new_spanned(name, "McType requires named fields")
|
||||
.to_compile_error()
|
||||
.into();
|
||||
};
|
||||
|
||||
// build field accessors
|
||||
let read_fields = fields.named.iter().map(|f| {
|
||||
let fname = &f.ident;
|
||||
let fty = &f.ty;
|
||||
quote! { #fname: <#fty as McType>::get(data)? }
|
||||
});
|
||||
|
||||
let write_fields = fields.named.iter().map(|f| {
|
||||
let fname = &f.ident;
|
||||
quote! { out.extend(self.#fname.convert()); }
|
||||
});
|
||||
|
||||
let expanded = quote! {
|
||||
impl McType for #name {
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
#(#read_fields),*
|
||||
})
|
||||
}
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
let mut out = Vec::new();
|
||||
#(#write_fields)*
|
||||
out
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use serde::{Serialize, Deserialize};
|
|||
|
||||
pub use crate::mc_types::error::PacketError;
|
||||
pub use crate::mc_types::protocol::{ProtocolRead, ProtocolConnection};
|
||||
pub use crate::mc_types::packet::{Result, Packet, PacketArray};
|
||||
pub use crate::mc_types::packet::{Result, Packet};
|
||||
use crate::mc_types::helpers::*;
|
||||
|
||||
pub const VERSION_NAME: &str = "1.21";
|
||||
|
|
@ -120,7 +120,42 @@ impl McType for String {
|
|||
fn convert(&self) -> Vec<u8> { convert_string(*self) }
|
||||
}
|
||||
|
||||
impl McType for Vec<u8> {
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_byte_array(data)) }
|
||||
fn convert(&self) -> Vec<u8> { convert_byte_array(*self) }
|
||||
impl<T: McType> McType for Vec<T> {
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||
let length = get_var_int(data)?;
|
||||
let mut out = Vec::with_capacity(length as usize);
|
||||
for _ in 0..length {
|
||||
out.push(T::get(data)?);
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
let mut data = convert_var_int(self.len() as i32);
|
||||
for el in self {
|
||||
data.extend(el.convert());
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: McType> McType for Option<T> {
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||
if get_bool(data) {
|
||||
Ok(Some(T::get(data)?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
match self {
|
||||
Some(v) => {
|
||||
let mut data = convert_bool(true);
|
||||
data.extend(v.convert());
|
||||
data
|
||||
}
|
||||
None => convert_bool(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,16 +242,3 @@ pub fn convert_string(s: &str) -> Vec<u8> {
|
|||
data.append(&mut s.as_bytes().to_vec());
|
||||
data
|
||||
}
|
||||
|
||||
pub fn get_byte_array(data: &mut Vec<u8>) -> Result<Vec<u8>> {
|
||||
let length = get_var_int(data)? as usize;
|
||||
let buffer = data[..length].to_vec();
|
||||
for _ in 0..length { data.remove(0); }
|
||||
Ok(buffer)
|
||||
}
|
||||
pub fn convert_byte_array(mut s: &mut Vec<u8>) -> Vec<u8> {
|
||||
let length = s.len() as i32;
|
||||
let mut data = convert_var_int(length);
|
||||
data.append(&mut s);
|
||||
data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,26 +30,3 @@ pub trait Packet: Sized {
|
|||
conn.write_data(&mut self.convert()).await
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PacketArray: Sized {
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self>;
|
||||
fn convert(&self) -> Vec<u8>;
|
||||
|
||||
fn get_array(data: &mut Vec<u8>) -> Result<Vec<Self>> {
|
||||
let length = get_var_int(data)?;
|
||||
let mut out_data: Vec<Self> = vec![];
|
||||
for _ in 0..length {
|
||||
out_data.push(Self::get(data)?);
|
||||
}
|
||||
Ok(out_data)
|
||||
}
|
||||
|
||||
fn convert_array(array: &mut Vec<Self>) -> Vec<u8> {
|
||||
let length = array.len() as i32;
|
||||
let mut data: Vec<u8> = convert_var_int(length);
|
||||
for element in array {
|
||||
data.append(&mut Self::convert(element));
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue