From 05d07bbc627b59fd07a8764a972b4aac63a46f53 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 16 May 2026 22:17:38 +0800 Subject: Use `default_program_path()` instead of `default_program_ident()` --- mingling_macros/src/chain.rs | 6 +-- mingling_macros/src/dispatcher.rs | 11 +++-- mingling_macros/src/dispatcher_clap.rs | 79 +++++++++++++++++++--------------- mingling_macros/src/groupped.rs | 18 ++++---- mingling_macros/src/lib.rs | 5 +++ mingling_macros/src/pack.rs | 18 ++++---- mingling_macros/src/program_setup.rs | 16 +++---- 7 files changed, 83 insertions(+), 70 deletions(-) (limited to 'mingling_macros') diff --git a/mingling_macros/src/chain.rs b/mingling_macros/src/chain.rs index 47f32e3..3c0cca5 100644 --- a/mingling_macros/src/chain.rs +++ b/mingling_macros/src/chain.rs @@ -134,8 +134,6 @@ fn extract_args_info(sig: &Signature) -> syn::Result<(Pat, TypePath, Vec TokenStream { - let default_program_ident = crate::default_program_ident(); - // Parse the attribute arguments (e.g., MyProgram from #[chain(MyProgram)]) // If no argument is provided, use ThisProgram let (group_name, use_crate_prefix) = if attr.is_empty() { @@ -235,7 +233,7 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream { // Determine the program type for the return type let program_type = if use_crate_prefix { - quote! { #default_program_ident } + crate::default_program_path() } else { quote! { #group_name } }; @@ -390,7 +388,7 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream { ::mingling::macros::register_chain!(#previous_type, #struct_name); - impl ::mingling::Chain<#default_program_ident> for #struct_name { + impl ::mingling::Chain<#program_type> for #struct_name { type Previous = #previous_type; #proc_fn diff --git a/mingling_macros/src/dispatcher.rs b/mingling_macros/src/dispatcher.rs index 64f0339..a74db6d 100644 --- a/mingling_macros/src/dispatcher.rs +++ b/mingling_macros/src/dispatcher.rs @@ -109,6 +109,11 @@ pub fn dispatcher(input: TokenStream) -> TokenStream { } else { group_name.clone() }; + let program_path = if use_default { + crate::default_program_path() + } else { + quote! { #group_name } + }; quote! { #[derive(Debug, Default)] @@ -119,14 +124,14 @@ pub fn dispatcher(input: TokenStream) -> TokenStream { #comp_entry #dispatch_tree_entry - impl ::mingling::Dispatcher<#program_ident> for #command_struct { + impl ::mingling::Dispatcher<#program_path> for #command_struct { fn node(&self) -> ::mingling::Node { ::mingling::macros::node!(#command_name_str) } - fn begin(&self, args: Vec) -> ::mingling::ChainProcess<#program_ident> { + fn begin(&self, args: Vec) -> ::mingling::ChainProcess<#program_path> { #pack::new(args).to_chain() } - fn clone_dispatcher(&self) -> Box> { + fn clone_dispatcher(&self) -> Box> { Box::new(#command_struct) } } diff --git a/mingling_macros/src/dispatcher_clap.rs b/mingling_macros/src/dispatcher_clap.rs index 2a1ac44..b32883e 100644 --- a/mingling_macros/src/dispatcher_clap.rs +++ b/mingling_macros/src/dispatcher_clap.rs @@ -132,40 +132,49 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream let struct_name = &input_struct.ident; // Determine the program name and other fields - let (command_name_str, dispatcher_struct, options, program_ident) = match &attr_input { - DispatcherClapInput::Default { - command_name, - dispatcher_struct, - options, - } => ( - command_name.value(), - dispatcher_struct.clone(), - ClapOptions { - error_struct: options.error_struct.clone(), - help_enabled: options.help_enabled, - }, - Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()), - ), - DispatcherClapInput::Explicit { - group_name, - command_name, - dispatcher_struct, - options, - } => ( - command_name.value(), - dispatcher_struct.clone(), - ClapOptions { - error_struct: options.error_struct.clone(), - help_enabled: options.help_enabled, - }, - group_name.clone(), - ), - }; + let (command_name_str, dispatcher_struct, options, program_ident, program_path) = + match &attr_input { + DispatcherClapInput::Default { + command_name, + dispatcher_struct, + options, + } => { + let path = crate::default_program_path(); + ( + command_name.value(), + dispatcher_struct.clone(), + ClapOptions { + error_struct: options.error_struct.clone(), + help_enabled: options.help_enabled, + }, + Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()), + path, + ) + } + DispatcherClapInput::Explicit { + group_name, + command_name, + dispatcher_struct, + options, + } => { + let path = quote! { #group_name }; + ( + command_name.value(), + dispatcher_struct.clone(), + ClapOptions { + error_struct: options.error_struct.clone(), + help_enabled: options.help_enabled, + }, + group_name.clone(), + path, + ) + } + }; // Generate the `begin` method body let begin_body = if let Some(ref error_struct) = options.error_struct { quote! { - if ::mingling::this::<#program_ident>().user_context.help { + if ::mingling::this::<#program_path>().user_context.help { return #struct_name::default().to_chain(); } match <#struct_name as ::clap::Parser>::try_parse_from(clap_args) { @@ -177,7 +186,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream } } else { quote! { - if ::mingling::this::<#program_ident>().user_context.help { + if ::mingling::this::<#program_path>().user_context.help { return #struct_name::default().to_chain(); } let parsed = <#struct_name as ::clap::Parser>::try_parse_from(clap_args) @@ -205,7 +214,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream fn #help_fn_name(_prev: #struct_name) { use clap::ColorChoice; - let this = ::mingling::this::<#program_ident>(); + let this = ::mingling::this::<#program_path>(); match this.stdout_setting.clap_help_print_behaviour { ::mingling::ClapHelpPrintBehaviour::WriteToRenderResult => { <#struct_name as ::clap::CommandFactory>::command() @@ -238,7 +247,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream #[doc(hidden)] struct #dispatcher_struct; - impl ::mingling::Dispatcher<#program_ident> for #dispatcher_struct { + impl ::mingling::Dispatcher<#program_path> for #dispatcher_struct { fn node(&self) -> ::mingling::Node { ::mingling::macros::node!(#command_name_str) } @@ -246,7 +255,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream fn begin( &self, args: Vec, - ) -> ::mingling::ChainProcess<#program_ident> { + ) -> ::mingling::ChainProcess<#program_path> { // Prepend a dummy program name for clap's parse_from let clap_args = std::iter::once(String::new()) .chain(args) @@ -257,7 +266,7 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream fn clone_dispatcher( &self, - ) -> Box> { + ) -> Box> { Box::new(#dispatcher_struct) } } diff --git a/mingling_macros/src/groupped.rs b/mingling_macros/src/groupped.rs index 4fd0665..e385812 100644 --- a/mingling_macros/src/groupped.rs +++ b/mingling_macros/src/groupped.rs @@ -1,10 +1,7 @@ use proc_macro::TokenStream; -use proc_macro2::Span; use quote::quote; use syn::{Attribute, DeriveInput, Ident, parse_macro_input}; -use crate::DEFAULT_PROGRAM_NAME; - /// Parses the `#[group(...)]` attribute to extract the group type fn parse_group_attribute(attrs: &[Attribute]) -> Option { for attr in attrs { @@ -25,8 +22,9 @@ pub fn derive_groupped(input: TokenStream) -> TokenStream { let struct_name = input.ident; // Parse attributes to find #[group(...)] - let group_ident = parse_group_attribute(&input.attrs) - .unwrap_or_else(|| Ident::new(DEFAULT_PROGRAM_NAME, Span::call_site())); + let group_ident: proc_macro2::TokenStream = parse_group_attribute(&input.attrs) + .map(|ident| quote! { #ident }) + .unwrap_or_else(crate::default_program_path); let any_output_convert_impls = proc_macro2::TokenStream::from(build_any_output_convert_impls( struct_name.clone(), @@ -56,8 +54,9 @@ pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream { let struct_name = input_parsed.ident.clone(); // Parse attributes to find #[group(...)] - let group_ident = parse_group_attribute(&input_parsed.attrs) - .unwrap_or_else(|| Ident::new(DEFAULT_PROGRAM_NAME, Span::call_site())); + let group_ident: proc_macro2::TokenStream = parse_group_attribute(&input_parsed.attrs) + .map(|ident| quote! { #ident }) + .unwrap_or_else(crate::default_program_path); let any_output_convert_impls = proc_macro2::TokenStream::from(build_any_output_convert_impls( struct_name.clone(), @@ -83,7 +82,10 @@ pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream { expanded.into() } -fn build_any_output_convert_impls(struct_name: Ident, group_ident: Ident) -> TokenStream { +fn build_any_output_convert_impls( + struct_name: Ident, + group_ident: proc_macro2::TokenStream, +) -> TokenStream { quote! { impl ::std::convert::Into<::mingling::AnyOutput<#group_ident>> for #struct_name { fn into(self) -> ::mingling::AnyOutput<#group_ident> { diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs index 7dd2fe2..d5bdf35 100644 --- a/mingling_macros/src/lib.rs +++ b/mingling_macros/src/lib.rs @@ -46,10 +46,15 @@ mod suggest; pub(crate) const DEFAULT_PROGRAM_NAME: &str = "ThisProgram"; +#[allow(dead_code)] pub(crate) fn default_program_ident() -> Ident { Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()) } +pub(crate) fn default_program_path() -> proc_macro2::TokenStream { + quote::quote! { crate::ThisProgram } +} + // Global variables #[cfg(feature = "general_renderer")] pub(crate) static GENERAL_RENDERERS: Lazy>> = diff --git a/mingling_macros/src/pack.rs b/mingling_macros/src/pack.rs index 2242082..1c0bb7b 100644 --- a/mingling_macros/src/pack.rs +++ b/mingling_macros/src/pack.rs @@ -52,7 +52,7 @@ impl Parse for PackInput { } pub fn pack(input: TokenStream) -> TokenStream { - let default_program_ident = crate::default_program_ident(); + let default_program_path = crate::default_program_path(); // Parse the input let pack_input = syn::parse_macro_input!(input as PackInput); @@ -211,13 +211,13 @@ pub fn pack(input: TokenStream) -> TokenStream { #default_impl #register_impl - impl Into> for #type_name { - fn into(self) -> mingling::AnyOutput<#default_program_ident> { + impl Into> for #type_name { + fn into(self) -> mingling::AnyOutput<#default_program_path> { mingling::AnyOutput::new(self) } } - impl From<#type_name> for mingling::ChainProcess<#default_program_ident> { + impl From<#type_name> for mingling::ChainProcess<#default_program_path> { fn from(value: #type_name) -> Self { mingling::AnyOutput::new(value).route_chain() } @@ -225,19 +225,19 @@ pub fn pack(input: TokenStream) -> TokenStream { impl #type_name { /// Converts the wrapper type into a `ChainProcess` for chaining operations. - pub fn to_chain(self) -> mingling::ChainProcess<#default_program_ident> { + pub fn to_chain(self) -> mingling::ChainProcess<#default_program_path> { mingling::AnyOutput::new(self).route_chain() } /// Converts the wrapper type into a `ChainProcess` for rendering operations. - pub fn to_render(self) -> mingling::ChainProcess<#default_program_ident> { + pub fn to_render(self) -> mingling::ChainProcess<#default_program_path> { mingling::AnyOutput::new(self).route_renderer() } } - impl ::mingling::Groupped<#default_program_ident> for #type_name { - fn member_id() -> #default_program_ident { - #default_program_ident::#type_name + impl ::mingling::Groupped<#default_program_path> for #type_name { + fn member_id() -> #default_program_path { + #default_program_path::#type_name } } } diff --git a/mingling_macros/src/program_setup.rs b/mingling_macros/src/program_setup.rs index 57b7e6c..dd32581 100644 --- a/mingling_macros/src/program_setup.rs +++ b/mingling_macros/src/program_setup.rs @@ -3,8 +3,6 @@ use quote::quote; use syn::spanned::Spanned; use syn::{FnArg, Ident, ItemFn, Pat, PatType, ReturnType, Signature, Type, parse_macro_input}; -use crate::DEFAULT_PROGRAM_NAME; - /// Extracts the program parameter from function arguments fn extract_program_param(sig: &Signature) -> syn::Result<(Pat, Type)> { // The function should have exactly one parameter @@ -50,17 +48,13 @@ fn extract_return_type(sig: &Signature) -> syn::Result<()> { } pub fn setup_attr(attr: TokenStream, item: TokenStream) -> TokenStream { - let default_program_ident = crate::default_program_ident(); - // Parse the attribute arguments (e.g., MyProgram from #[program_setup(MyProgram)]) // If no argument is provided, use ThisProgram let (program_name, use_crate_prefix) = if attr.is_empty() { - ( - Ident::new(DEFAULT_PROGRAM_NAME, proc_macro2::Span::call_site()), - true, - ) + (crate::default_program_path(), true) } else { - (parse_macro_input!(attr as Ident), false) + let ident: Ident = parse_macro_input!(attr as Ident); + (quote! { #ident }, false) }; // Parse the function item @@ -110,8 +104,8 @@ pub fn setup_attr(attr: TokenStream, item: TokenStream) -> TokenStream { #[doc(hidden)] #vis struct #struct_name; - impl ::mingling::setup::ProgramSetup<#default_program_ident> for #struct_name { - fn setup(&mut self, program: &mut ::mingling::Program<#default_program_ident>) { + impl ::mingling::setup::ProgramSetup<#program_name> for #struct_name { + fn setup(&mut self, program: &mut ::mingling::Program<#program_name>) { // Call the original function with the actual Program type #fn_name(program); } -- cgit