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