aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros/src/dispatcher.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_macros/src/dispatcher.rs')
-rw-r--r--mingling_macros/src/dispatcher.rs190
1 files changed, 49 insertions, 141 deletions
diff --git a/mingling_macros/src/dispatcher.rs b/mingling_macros/src/dispatcher.rs
index 6bf10f1..51dce95 100644
--- a/mingling_macros/src/dispatcher.rs
+++ b/mingling_macros/src/dispatcher.rs
@@ -8,14 +8,6 @@ use syn::{Attribute, Ident, LitStr, Result as SynResult, Token};
use crate::COMPILE_TIME_DISPATCHERS;
enum DispatcherChainInput {
- Explicit {
- cmd_attrs: Vec<Attribute>,
- entry_attrs: Vec<Attribute>,
- group_name: syn::Path,
- command_name: syn::LitStr,
- command_struct: Ident,
- pack: Ident,
- },
Default {
cmd_attrs: Vec<Attribute>,
entry_attrs: Vec<Attribute>,
@@ -35,27 +27,7 @@ impl Parse for DispatcherChainInput {
// Collect outer attributes for the CMD struct
let cmd_attrs = input.call(Attribute::parse_outer)?;
- if (input.peek(Ident) || input.peek(Token![crate]))
- && (input.peek2(Token![::]) || input.peek2(Token![,]))
- {
- let group_name = input.parse::<syn::Path>()?;
- input.parse::<Token![,]>()?;
- let command_name = input.parse()?;
- input.parse::<Token![,]>()?;
- let command_struct = input.parse()?;
- input.parse::<Token![=>]>()?;
- let entry_attrs = input.call(Attribute::parse_outer)?;
- let pack = input.parse()?;
-
- Ok(DispatcherChainInput::Explicit {
- cmd_attrs,
- entry_attrs,
- group_name,
- command_name,
- command_struct,
- pack,
- })
- } else if input.peek(syn::LitStr) {
+ if input.peek(syn::LitStr) {
// Parse the command name string first
let command_name: LitStr = input.parse()?;
@@ -97,12 +69,8 @@ impl Parse for DispatcherChainInput {
}
}
-// 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.
+// NOTICE: The token stream generation patterns in `dispatcher_chain` and `dispatcher_render`
+// are nearly identical and could benefit from refactoring into common helper functions.
#[allow(clippy::too_many_lines)]
pub fn dispatcher(input: TokenStream) -> TokenStream {
@@ -110,94 +78,36 @@ pub fn dispatcher(input: TokenStream) -> TokenStream {
let dispatcher_input = syn::parse_macro_input!(input as DispatcherChainInput);
#[cfg(not(feature = "extra_macros"))]
- let (command_name, command_struct, pack, cmd_attrs, entry_attrs, _use_default, group_path) =
- match dispatcher_input {
- DispatcherChainInput::Explicit {
- cmd_attrs,
- entry_attrs,
- group_name,
- command_name,
- command_struct,
- pack,
- } => (
- command_name,
- command_struct,
- pack,
- cmd_attrs,
- entry_attrs,
- false,
- quote! { #group_name },
- ),
- DispatcherChainInput::Default {
- cmd_attrs,
- entry_attrs,
- command_name,
- command_struct,
- pack,
- } => (
- command_name,
- command_struct,
- pack,
- cmd_attrs,
- entry_attrs,
- true,
- crate::default_program_path(),
- ),
- };
+ let (command_name, command_struct, pack, cmd_attrs, entry_attrs) = match dispatcher_input {
+ DispatcherChainInput::Default {
+ cmd_attrs,
+ entry_attrs,
+ command_name,
+ command_struct,
+ pack,
+ } => (command_name, command_struct, pack, cmd_attrs, entry_attrs),
+ };
#[cfg(feature = "extra_macros")]
- let (command_name, command_struct, pack, cmd_attrs, entry_attrs, _use_default, group_path) =
- match dispatcher_input {
- DispatcherChainInput::Explicit {
- cmd_attrs,
- entry_attrs,
- group_name,
- command_name,
- command_struct,
- pack,
- } => (
- command_name,
- command_struct,
- pack,
- cmd_attrs,
- entry_attrs,
- false,
- quote! { #group_name },
- ),
- DispatcherChainInput::Default {
- cmd_attrs,
- entry_attrs,
- command_name,
- command_struct,
- pack,
- } => (
- command_name,
- command_struct,
- pack,
- cmd_attrs,
- entry_attrs,
- true,
- crate::default_program_path(),
- ),
- DispatcherChainInput::Auto {
- cmd_attrs,
- command_name,
- } => {
- let command_name_str = command_name.value();
- let pascal = dotted_to_pascal_case(&command_name_str);
- let command_struct = Ident::new(&format!("CMD{pascal}"), command_name.span());
- let pack = Ident::new(&format!("Entry{pascal}"), command_name.span());
- (
- command_name,
- command_struct,
- pack,
- cmd_attrs,
- Vec::new(),
- true,
- crate::default_program_path(),
- )
- }
- };
+ let (command_name, command_struct, pack, cmd_attrs, entry_attrs) = match dispatcher_input {
+ DispatcherChainInput::Default {
+ cmd_attrs,
+ entry_attrs,
+ command_name,
+ command_struct,
+ pack,
+ } => (command_name, command_struct, pack, cmd_attrs, entry_attrs),
+ DispatcherChainInput::Auto {
+ cmd_attrs,
+ command_name,
+ } => {
+ let command_name_str = command_name.value();
+ let pascal = dotted_to_pascal_case(&command_name_str);
+ let command_struct = Ident::new(&format!("CMD{pascal}"), command_name.span());
+ let pack = Ident::new(&format!("Entry{pascal}"), command_name.span());
+ (command_name, command_struct, pack, cmd_attrs, Vec::new())
+ }
+ };
let command_name_str = command_name.value();
@@ -205,30 +115,28 @@ pub fn dispatcher(input: TokenStream) -> TokenStream {
let dispatch_tree_entry = get_dispatch_tree_entry(&command_name_str, &command_struct, &pack);
- let expanded = {
- let program_path = group_path;
+ let program_type = crate::default_program_path();
- quote! {
- #(#cmd_attrs)*
- #[derive(Debug, Default)]
- pub struct #command_struct;
+ let expanded = quote! {
+ #(#cmd_attrs)*
+ #[derive(Debug, Default)]
+ pub struct #command_struct;
- ::mingling::macros::pack!(#(#entry_attrs)* #program_path, #pack = Vec<String>);
+ ::mingling::macros::pack!(#(#entry_attrs)* #pack = Vec<String>);
- #comp_entry
- #dispatch_tree_entry
+ #comp_entry
+ #dispatch_tree_entry
- impl ::mingling::Dispatcher<#program_path> for #command_struct {
- fn node(&self) -> ::mingling::Node {
- ::mingling::macros::node!(#command_name_str)
- }
- fn begin(&self, args: Vec<String>) -> ::mingling::ChainProcess<#program_path> {
- use ::mingling::Groupped;
- #pack::new(args).to_chain()
- }
- fn clone_dispatcher(&self) -> Box<dyn ::mingling::Dispatcher<#program_path>> {
- Box::new(#command_struct)
- }
+ impl ::mingling::Dispatcher<#program_type> for #command_struct {
+ fn node(&self) -> ::mingling::Node {
+ ::mingling::macros::node!(#command_name_str)
+ }
+ fn begin(&self, args: Vec<String>) -> ::mingling::ChainProcess<#program_type> {
+ use ::mingling::Groupped;
+ #pack::new(args).to_chain()
+ }
+ fn clone_dispatcher(&self) -> Box<dyn ::mingling::Dispatcher<#program_type>> {
+ Box::new(#command_struct)
}
}
};