aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-19 01:28:37 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-19 01:28:37 +0800
commit4be889ac2dc5263ce03bb014de24916bee2e9aa8 (patch)
treea2b6782801cb53af670d1b96a6c85f0e50f520f4
parent66aab5323663a2d5e3e2db562cf6ce60d9e2c5be (diff)
Add dispatch_tree integration to dispatcher_clap
-rw-r--r--CHANGELOG.md2
-rw-r--r--mingling_macros/src/dispatcher_clap.rs30
2 files changed, 31 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b9ca68b..4dc1aa9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -57,6 +57,8 @@
- Allows the program instance to be **taken** (moved out) via an `unsafe fn take()` after execution completes, enabling proper cleanup before `std::process::exit()` in `exec_and_exit`
- Is paired with corresponding simplifications in `once_exec.rs` and `repl_exec.rs` that switch from `THIS_PROGRAM.get().unwrap().as_ref()` to `THIS_PROGRAM.get_raw().unwrap()`
+4. **\[macros:dispatcher_clap\]** Added `dispatch_tree` feature integration for `#[dispatcher_clap]`. When the `dispatch_tree` feature is enabled, `#[dispatcher_clap]` will now automatically register the dispatcher and entry in the dispatch tree via `register_dispatcher!`, matching the behavior already present in the `dispatcher!` macro. When the feature is disabled, no additional code is generated.
+
#### Optimizations:
1. **\[core:flag\]** Refactored the `special_argument!` and `special_arguments!` macros to replace index‑based `while` loops with iterator `position` and `drain`, improving both performance and readability.
diff --git a/mingling_macros/src/dispatcher_clap.rs b/mingling_macros/src/dispatcher_clap.rs
index 5a6cf4c..34d146c 100644
--- a/mingling_macros/src/dispatcher_clap.rs
+++ b/mingling_macros/src/dispatcher_clap.rs
@@ -232,6 +232,9 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
None
};
+ let dispatch_tree_entry =
+ get_dispatch_tree_entry(&command_name_str, &dispatcher_struct, &struct_name);
+
let expanded = quote! {
// Keep the original struct definition
#input_struct
@@ -242,9 +245,13 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
// Generate the help block if enabled
#help_gen
+ // Dispatch tree registration (if feature enabled)
+ #dispatch_tree_entry
+
// Generate the dispatcher struct
#[doc(hidden)]
- struct #dispatcher_struct;
+ #[derive(Default)]
+ pub struct #dispatcher_struct;
impl ::mingling::Dispatcher<#program_path> for #dispatcher_struct {
fn node(&self) -> ::mingling::Node {
@@ -273,3 +280,24 @@ pub fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> TokenStream
expanded.into()
}
+
+#[cfg(feature = "dispatch_tree")]
+fn get_dispatch_tree_entry(
+ command_name_str: &str,
+ dispatcher_struct: &Ident,
+ entry_name: &Ident,
+) -> proc_macro2::TokenStream {
+ let node_name_lit = syn::LitStr::new(command_name_str, proc_macro2::Span::call_site());
+ quote! {
+ ::mingling::macros::register_dispatcher!(#node_name_lit, #dispatcher_struct, #entry_name);
+ }
+}
+
+#[cfg(not(feature = "dispatch_tree"))]
+fn get_dispatch_tree_entry(
+ _command_name_str: &str,
+ _dispatcher_struct: &Ident,
+ _entry_name: &Ident,
+) -> proc_macro2::TokenStream {
+ quote! {}
+}