From 1d9a65ae06faf4a6329eb07e8c1deab3811c782b Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 25 Apr 2026 18:59:04 +0800 Subject: Rename dispatcher_chain.rs to dispatcher.rs --- mingling_macros/src/dispatcher.rs | 163 ++++++++++++++++++++++++++++++++ mingling_macros/src/dispatcher_chain.rs | 163 -------------------------------- mingling_macros/src/lib.rs | 4 +- 3 files changed, 165 insertions(+), 165 deletions(-) create mode 100644 mingling_macros/src/dispatcher.rs delete mode 100644 mingling_macros/src/dispatcher_chain.rs diff --git a/mingling_macros/src/dispatcher.rs b/mingling_macros/src/dispatcher.rs new file mode 100644 index 0000000..6223a81 --- /dev/null +++ b/mingling_macros/src/dispatcher.rs @@ -0,0 +1,163 @@ +//! Dispatcher Chain and Dispatcher Render Macros +//! +//! This module provides macros for creating dispatcher chain and dispatcher render structs +//! with automatic implementations of the `Dispatcher` trait. + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse::{Parse, ParseStream}; +use syn::{Ident, Result as SynResult, Token}; + +enum DispatcherChainInput { + Explicit { + group_name: Ident, + command_name: syn::LitStr, + command_struct: Ident, + pack: Ident, + }, + Default { + command_name: syn::LitStr, + command_struct: Ident, + pack: Ident, + }, +} + +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()?; + input.parse::()?; + let command_name = input.parse()?; + input.parse::()?; + let command_struct = input.parse()?; + input.parse::]>()?; + let pack = input.parse()?; + + Ok(DispatcherChainInput::Explicit { + group_name, + command_name, + command_struct, + pack, + }) + } else if lookahead.peek(syn::LitStr) { + // Default format: "command_name", CommandStruct => ChainStruct + let command_name = input.parse()?; + input.parse::()?; + let command_struct = input.parse()?; + input.parse::]>()?; + let pack = input.parse()?; + + Ok(DispatcherChainInput::Default { + command_name, + command_struct, + pack, + }) + } else { + Err(lookahead.error()) + } + } +} + +// NOTICE: This implementation contains significant code duplication between the explicit +// and default cases in both `dispatcher_chain` and `dispatcher_render` functions. +// The logic for handling default vs explicit group names and generating the appropriate +// code should be extracted into common helper functions to reduce redundancy. +// Additionally, the token stream generation patterns are nearly identical between +// the two main functions and could benefit from refactoring. + +pub fn dispatcher_chain(input: TokenStream) -> TokenStream { + // Parse the input + 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 { + DispatcherChainInput::Explicit { + group_name, + command_name, + command_struct, + pack, + } => (group_name, command_name, command_struct, pack, false), + DispatcherChainInput::Default { + command_name, + command_struct, + pack, + } => ( + Ident::new("ThisProgram", proc_macro2::Span::call_site()), + command_name, + command_struct, + pack, + true, + ), + }; + + let command_name_str = command_name.value(); + + let comp_entry = get_comp_entry(&pack); + + let expanded = if use_default { + // For default case, use ThisProgram + quote! { + #[derive(Debug, Default)] + pub struct #command_struct; + + ::mingling::macros::pack!(ThisProgram, #pack = Vec); + + #comp_entry + + impl ::mingling::Dispatcher for #command_struct { + fn node(&self) -> ::mingling::Node { + ::mingling::macros::node!(#command_name_str) + } + fn begin(&self, args: Vec) -> ::mingling::ChainProcess { + #pack::new(args).to_chain() + } + fn clone_dispatcher(&self) -> Box> { + Box::new(#command_struct) + } + } + } + } else { + // For explicit case, use the provided group_name + quote! { + #[derive(Debug, Default)] + pub struct #command_struct; + + ::mingling::macros::pack!(#group_name, #pack = Vec); + + #comp_entry + + impl ::mingling::Dispatcher<#group_name> for #command_struct { + fn node(&self) -> ::mingling::Node { + ::mingling::macros::node!(#command_name_str) + } + fn begin(&self, args: Vec) -> ::mingling::ChainProcess<#group_name> { + #pack::new(args).to_chain() + } + fn clone_dispatcher(&self) -> Box> { + Box::new(#command_struct) + } + } + } + }; + + expanded.into() +} + +#[cfg(feature = "comp")] +fn get_comp_entry(entry_name: &Ident) -> proc_macro2::TokenStream { + let comp_entry = quote! { + impl ::mingling::CompletionEntry for #entry_name { + fn get_input(self) -> Vec { + self.inner.clone() + } + } + }; + comp_entry +} + +#[cfg(not(feature = "comp"))] +fn get_comp_entry(_entry_name: &Ident) -> proc_macro2::TokenStream { + quote! {} +} diff --git a/mingling_macros/src/dispatcher_chain.rs b/mingling_macros/src/dispatcher_chain.rs deleted file mode 100644 index 6223a81..0000000 --- a/mingling_macros/src/dispatcher_chain.rs +++ /dev/null @@ -1,163 +0,0 @@ -//! Dispatcher Chain and Dispatcher Render Macros -//! -//! This module provides macros for creating dispatcher chain and dispatcher render structs -//! with automatic implementations of the `Dispatcher` trait. - -use proc_macro::TokenStream; -use quote::quote; -use syn::parse::{Parse, ParseStream}; -use syn::{Ident, Result as SynResult, Token}; - -enum DispatcherChainInput { - Explicit { - group_name: Ident, - command_name: syn::LitStr, - command_struct: Ident, - pack: Ident, - }, - Default { - command_name: syn::LitStr, - command_struct: Ident, - pack: Ident, - }, -} - -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()?; - input.parse::()?; - let command_name = input.parse()?; - input.parse::()?; - let command_struct = input.parse()?; - input.parse::]>()?; - let pack = input.parse()?; - - Ok(DispatcherChainInput::Explicit { - group_name, - command_name, - command_struct, - pack, - }) - } else if lookahead.peek(syn::LitStr) { - // Default format: "command_name", CommandStruct => ChainStruct - let command_name = input.parse()?; - input.parse::()?; - let command_struct = input.parse()?; - input.parse::]>()?; - let pack = input.parse()?; - - Ok(DispatcherChainInput::Default { - command_name, - command_struct, - pack, - }) - } else { - Err(lookahead.error()) - } - } -} - -// NOTICE: This implementation contains significant code duplication between the explicit -// and default cases in both `dispatcher_chain` and `dispatcher_render` functions. -// The logic for handling default vs explicit group names and generating the appropriate -// code should be extracted into common helper functions to reduce redundancy. -// Additionally, the token stream generation patterns are nearly identical between -// the two main functions and could benefit from refactoring. - -pub fn dispatcher_chain(input: TokenStream) -> TokenStream { - // Parse the input - 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 { - DispatcherChainInput::Explicit { - group_name, - command_name, - command_struct, - pack, - } => (group_name, command_name, command_struct, pack, false), - DispatcherChainInput::Default { - command_name, - command_struct, - pack, - } => ( - Ident::new("ThisProgram", proc_macro2::Span::call_site()), - command_name, - command_struct, - pack, - true, - ), - }; - - let command_name_str = command_name.value(); - - let comp_entry = get_comp_entry(&pack); - - let expanded = if use_default { - // For default case, use ThisProgram - quote! { - #[derive(Debug, Default)] - pub struct #command_struct; - - ::mingling::macros::pack!(ThisProgram, #pack = Vec); - - #comp_entry - - impl ::mingling::Dispatcher for #command_struct { - fn node(&self) -> ::mingling::Node { - ::mingling::macros::node!(#command_name_str) - } - fn begin(&self, args: Vec) -> ::mingling::ChainProcess { - #pack::new(args).to_chain() - } - fn clone_dispatcher(&self) -> Box> { - Box::new(#command_struct) - } - } - } - } else { - // For explicit case, use the provided group_name - quote! { - #[derive(Debug, Default)] - pub struct #command_struct; - - ::mingling::macros::pack!(#group_name, #pack = Vec); - - #comp_entry - - impl ::mingling::Dispatcher<#group_name> for #command_struct { - fn node(&self) -> ::mingling::Node { - ::mingling::macros::node!(#command_name_str) - } - fn begin(&self, args: Vec) -> ::mingling::ChainProcess<#group_name> { - #pack::new(args).to_chain() - } - fn clone_dispatcher(&self) -> Box> { - Box::new(#command_struct) - } - } - } - }; - - expanded.into() -} - -#[cfg(feature = "comp")] -fn get_comp_entry(entry_name: &Ident) -> proc_macro2::TokenStream { - let comp_entry = quote! { - impl ::mingling::CompletionEntry for #entry_name { - fn get_input(self) -> Vec { - self.inner.clone() - } - } - }; - comp_entry -} - -#[cfg(not(feature = "comp"))] -fn get_comp_entry(_entry_name: &Ident) -> proc_macro2::TokenStream { - quote! {} -} diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs index a1493ba..5a3b04a 100644 --- a/mingling_macros/src/lib.rs +++ b/mingling_macros/src/lib.rs @@ -14,7 +14,7 @@ use syn::parse_macro_input; mod chain; #[cfg(feature = "comp")] mod completion; -mod dispatcher_chain; +mod dispatcher; mod enum_tag; mod groupped; mod node; @@ -55,7 +55,7 @@ pub fn pack(input: TokenStream) -> TokenStream { #[proc_macro] pub fn dispatcher(input: TokenStream) -> TokenStream { - dispatcher_chain::dispatcher_chain(input) + dispatcher::dispatcher_chain(input) } #[proc_macro] -- cgit