From 60b91db3df168532f9143f0cafb7b5166e1dc78b Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 16 May 2026 22:31:52 +0800 Subject: Accept paths for program name parameters in macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All proc macros (`pack!`, `dispatcher!`, `#[chain]`, `#[program_setup]`, `#[dispatcher_clap]`, `#[derive(Groupped)]`) now parse program names as `syn::Path` instead of bare `Ident`, allowing use of paths like `crate::MyProgram` or `my_crate::MyProgram`. The default program name `ThisProgram` is no longer re-exported or required as an import — generated code references `crate::ThisProgram` directly. --- mingling_macros/src/dispatcher.rs | 40 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'mingling_macros/src/dispatcher.rs') diff --git a/mingling_macros/src/dispatcher.rs b/mingling_macros/src/dispatcher.rs index a74db6d..ba36545 100644 --- a/mingling_macros/src/dispatcher.rs +++ b/mingling_macros/src/dispatcher.rs @@ -11,11 +11,10 @@ use syn::{Ident, Result as SynResult, Token}; #[cfg(feature = "dispatch_tree")] use crate::COMPILE_TIME_DISPATCHERS; -use crate::DEFAULT_PROGRAM_NAME; enum DispatcherChainInput { Explicit { - group_name: Ident, + group_name: syn::Path, command_name: syn::LitStr, command_struct: Ident, pack: Ident, @@ -29,10 +28,10 @@ enum DispatcherChainInput { impl Parse for DispatcherChainInput { fn parse(input: ParseStream) -> SynResult { - let lookahead = input.lookahead1(); - - if lookahead.peek(Ident) && input.peek2(Token![,]) && input.peek3(syn::LitStr) { - let group_name = input.parse()?; + if (input.peek(Ident) || input.peek(Token![crate])) + && (input.peek2(Token![::]) || input.peek2(Token![,])) + { + let group_name = input.parse::()?; input.parse::()?; let command_name = input.parse()?; input.parse::()?; @@ -46,7 +45,7 @@ impl Parse for DispatcherChainInput { command_struct, pack, }) - } else if lookahead.peek(syn::LitStr) { + } else if input.peek(syn::LitStr) { // Default format: "command_name", CommandStruct => ChainStruct let command_name = input.parse()?; input.parse::()?; @@ -60,7 +59,7 @@ impl Parse for DispatcherChainInput { pack, }) } else { - Err(lookahead.error()) + Err(input.lookahead1().error()) } } } @@ -77,23 +76,29 @@ pub fn dispatcher(input: TokenStream) -> TokenStream { let dispatcher_input = syn::parse_macro_input!(input as DispatcherChainInput); // Determine if we're using default or explicit group - let (group_name, command_name, command_struct, pack, use_default) = match dispatcher_input { + let (command_name, command_struct, pack, _use_default, group_path) = match dispatcher_input { DispatcherChainInput::Explicit { group_name, command_name, command_struct, pack, - } => (group_name, command_name, command_struct, pack, false), + } => ( + command_name, + command_struct, + pack, + false, + quote! { #group_name }, + ), DispatcherChainInput::Default { command_name, command_struct, pack, } => ( - Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()), command_name, command_struct, pack, true, + crate::default_program_path(), ), }; @@ -104,22 +109,13 @@ pub fn dispatcher(input: TokenStream) -> TokenStream { let dispatch_tree_entry = get_dispatch_tree_entry(&command_name_str, &command_struct, &pack); let expanded = { - let program_ident = if use_default { - Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()) - } else { - group_name.clone() - }; - let program_path = if use_default { - crate::default_program_path() - } else { - quote! { #group_name } - }; + let program_path = group_path; quote! { #[derive(Debug, Default)] pub struct #command_struct; - ::mingling::macros::pack!(#program_ident, #pack = Vec); + ::mingling::macros::pack!(#program_path, #pack = Vec); #comp_entry #dispatch_tree_entry -- cgit