This commit is contained in:
parent
90246b6a80
commit
908b58f1b9
@ -8,6 +8,6 @@ edition = "2018"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = {version = "1.0", features=["full", "extra-traits", "parsing"]}
|
||||
syn = {version = "2.0.39", features=["full", "extra-traits", "parsing"]}
|
||||
quote = "1.0"
|
||||
proc-macro2 = "1.0"
|
||||
|
@ -6,8 +6,10 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{parse_macro_input, ItemStruct, NestedMeta, DeriveInput, Field};
|
||||
use syn::{parse_macro_input, ItemStruct, DeriveInput, Field};
|
||||
use syn::punctuated::Iter;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::parse::Parse;
|
||||
use quote::quote;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -308,7 +310,7 @@ fn get_struct_fields(fields: Iter<Field>) -> Result<Vec<AttrType>, TokenStream>
|
||||
}
|
||||
let mut attr_meta = AttrMeta::None;
|
||||
for attr in &field.attrs {
|
||||
attr_meta = match attr.path.segments[0].ident.to_string().as_str() {
|
||||
attr_meta = match attr.path().segments[0].ident.to_string().as_str() {
|
||||
"utf8" => AttrMeta::Utf8,
|
||||
"utf16" => AttrMeta::Utf16,
|
||||
"nodebug" => AttrMeta::NoDebug,
|
||||
@ -345,35 +347,51 @@ fn get_struct_fields(fields: Iter<Field>) -> Result<Vec<AttrType>, TokenStream>
|
||||
}
|
||||
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pso_packet(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as syn::AttributeArgs);
|
||||
let mut cmd = 0;
|
||||
let mut flag = true;
|
||||
let mut manual_flag = false;
|
||||
for a in args {
|
||||
match &a {
|
||||
NestedMeta::Lit(lit) => {
|
||||
if let syn::Lit::Int(litint) = lit {
|
||||
cmd = litint.base10_parse().unwrap();
|
||||
}
|
||||
},
|
||||
NestedMeta::Meta(k) => {
|
||||
if let syn::Meta::Path(syn::Path {segments, ..}) = k {
|
||||
match segments[0].ident.to_string().as_str() {
|
||||
"no_flag" => flag = false,
|
||||
"manual_flag" => {
|
||||
flag = false;
|
||||
manual_flag = true;
|
||||
},
|
||||
_ => {
|
||||
return syn::Error::new(segments[0].ident.span(), "unknown macro param").to_compile_error().into();
|
||||
#[derive(Debug)]
|
||||
struct PSOPacketAttrs {
|
||||
cmd: u16,
|
||||
flag: bool,
|
||||
manual_flag: bool,
|
||||
}
|
||||
|
||||
impl Parse for PSOPacketAttrs {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let vars = Punctuated::<syn::Expr, syn::Token![,]>::parse_terminated(input)?;
|
||||
|
||||
let (cmd, flag, manual_flag) = vars
|
||||
.into_iter()
|
||||
.fold((None, true, false), |mut acc, attr| {
|
||||
match attr {
|
||||
syn::Expr::Lit(lit) => {
|
||||
if let syn::Lit::Int(int) = lit.lit {
|
||||
acc.0 = int.base10_parse().ok();
|
||||
}
|
||||
},
|
||||
syn::Expr::Path(path) => {
|
||||
if path.path.is_ident("no_flag") {
|
||||
acc.1 = false;
|
||||
}
|
||||
if path.path.is_ident("manual_flag") {
|
||||
acc.2 = true;
|
||||
}
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
}
|
||||
acc
|
||||
});
|
||||
Ok(PSOPacketAttrs {
|
||||
cmd: cmd.unwrap(),
|
||||
flag,
|
||||
manual_flag
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pso_packet(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as PSOPacketAttrs);
|
||||
|
||||
let pkt_struct = parse_macro_input!(item as ItemStruct);
|
||||
let attrs = match get_struct_fields(pkt_struct.fields.iter()) {
|
||||
@ -381,7 +399,7 @@ pub fn pso_packet(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
Err(err) => return err
|
||||
};
|
||||
|
||||
if manual_flag {
|
||||
if args.manual_flag {
|
||||
match &attrs[0] {
|
||||
AttrType::Array(_, ident, _, _) => {
|
||||
if ident.to_string() != "flag" {
|
||||
@ -397,7 +415,7 @@ pub fn pso_packet(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
let struct_def = generate_struct_def(pkt_struct.ident.clone(), &attrs);
|
||||
let psopacket_impl = generate_psopacket_impl(cmd, pkt_struct.ident.clone(), &attrs, flag);
|
||||
let psopacket_impl = generate_psopacket_impl(args.cmd, pkt_struct.ident.clone(), &attrs, args.flag);
|
||||
let debug_impl = generate_debug_impl(pkt_struct.ident.clone(), &attrs);
|
||||
let partialeq_impl = generate_partialeq_impl(pkt_struct.ident.clone(), &attrs);
|
||||
|
||||
@ -588,18 +606,10 @@ fn generate_psomessage_impl(msg_cmd: u8, name: syn::Ident, attrs: &Vec<AttrType>
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pso_message(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as syn::AttributeArgs);
|
||||
let mut cmd = 0;
|
||||
for a in args {
|
||||
if let NestedMeta::Lit(lit) = a {
|
||||
if let syn::Lit::Int(litint) = lit {
|
||||
cmd = litint.base10_parse().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let cmd = parse_macro_input!(attr as syn::LitInt).base10_parse().unwrap();
|
||||
let pkt_struct = parse_macro_input!(item as ItemStruct);
|
||||
let mut attrs = match get_struct_fields(pkt_struct.fields.iter()) {
|
||||
|
||||
let mut fields = match get_struct_fields(pkt_struct.fields.iter()) {
|
||||
Ok(a) => a,
|
||||
Err(err) => return err
|
||||
};
|
||||
@ -617,13 +627,13 @@ pub fn pso_message(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
segments: punctuated
|
||||
}
|
||||
};
|
||||
attrs.insert(0, AttrType::Value(u8tpath.clone(), syn::Ident::new("target", proc_macro2::Span::call_site()), AttrMeta::None));
|
||||
attrs.insert(0, AttrType::Value(u8tpath, syn::Ident::new("client", proc_macro2::Span::call_site()), AttrMeta::None));
|
||||
fields.insert(0, AttrType::Value(u8tpath.clone(), syn::Ident::new("target", proc_macro2::Span::call_site()), AttrMeta::None));
|
||||
fields.insert(0, AttrType::Value(u8tpath, syn::Ident::new("client", proc_macro2::Span::call_site()), AttrMeta::None));
|
||||
|
||||
let struct_def = generate_struct_def(pkt_struct.ident.clone(), &attrs);
|
||||
let psopacket_impl = generate_psomessage_impl(cmd, pkt_struct.ident.clone(), &attrs);
|
||||
let debug_impl = generate_debug_impl(pkt_struct.ident.clone(), &attrs);
|
||||
let partialeq_impl = generate_partialeq_impl(pkt_struct.ident.clone(), &attrs);
|
||||
let struct_def = generate_struct_def(pkt_struct.ident.clone(), &fields);
|
||||
let psopacket_impl = generate_psomessage_impl(cmd, pkt_struct.ident.clone(), &fields);
|
||||
let debug_impl = generate_debug_impl(pkt_struct.ident.clone(), &fields);
|
||||
let partialeq_impl = generate_partialeq_impl(pkt_struct.ident.clone(), &fields);
|
||||
|
||||
let q = quote!{
|
||||
#[derive(Clone)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user