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