diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-17 03:27:46 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-17 03:27:46 +0800 |
| commit | c23c590330af83afb6e146bcd9b0a274b3689d22 (patch) | |
| tree | 34599cf2737ce4de22653c9ccae2d60a38a15842 /mingling_pathf/src/patterns/dispatcher_clap.rs | |
| parent | 6980fbf2f9fb4c599d8dc6ff549a8b3288eb24e9 (diff) | |
refactor!: remove Node type and simplify dispatcher macro syntax
The `dispatcher!` macro no longer requires a `CMD*` dispatcher type
argument; the dispatcher struct is now generated internally as
`__Dispatcher{Pascal}`. The `Node` type, `node!` macro, and
`Dispatcher::node()` / `clone_dispatcher()` methods are removed.
Diffstat (limited to 'mingling_pathf/src/patterns/dispatcher_clap.rs')
| -rw-r--r-- | mingling_pathf/src/patterns/dispatcher_clap.rs | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/mingling_pathf/src/patterns/dispatcher_clap.rs b/mingling_pathf/src/patterns/dispatcher_clap.rs index da9da3e..cd7bf67 100644 --- a/mingling_pathf/src/patterns/dispatcher_clap.rs +++ b/mingling_pathf/src/patterns/dispatcher_clap.rs @@ -2,16 +2,16 @@ //! The `DispatcherClapPattern` matches structs annotated with `#[dispatcher_clap(...)]` and //! extracts key items for code generation or analysis: //! - The entry struct name (always) -//! - The dispatcher command struct (`CMD*`, always) +//! - The hidden dispatcher struct (`__Dispatcher*`, always) //! - The error type, if `error = ErrorType` is specified //! - The help internal struct, if `help = true` is specified //! - The `__internal_dispatcher_*` compile-time collected static (always) //! //! Supported forms: -//! - `#[dispatcher_clap("greet", CMDGreet)] struct EntryGreet { ... }` -//! - `#[dispatcher_clap("greet", CMDGreet, error = ErrorGreet)] struct EntryGreet { ... }` -//! - `#[dispatcher_clap("greet", CMDGreet, help = true)] struct EntryGreet { ... }` -//! - `#[dispatcher_clap("greet", CMDGreet, error = ErrorGreet, help = true)] struct EntryGreet { ... }` +//! - `#[dispatcher_clap("greet")] struct EntryGreet { ... }` +//! - `#[dispatcher_clap("greet", error = ErrorGreet)] struct EntryGreet { ... }` +//! - `#[dispatcher_clap("greet", help = true)] struct EntryGreet { ... }` +//! - `#[dispatcher_clap("greet", error = ErrorGreet, help = true)] struct EntryGreet { ... }` use syn::Item; @@ -19,16 +19,16 @@ use crate::pattern_analyzer::{AnalyzeItem, AnalyzePattern}; /// Match structs annotated with `#[dispatcher_clap(...)]`, extracting: /// - The entry type (struct name, always) -/// - The dispatcher struct (`CMD*`, always) +/// - The hidden dispatcher struct (`__Dispatcher*`, always) /// - The error type, if `error = ErrorType` is specified /// - The help internal struct, if `help = true` is specified /// - `__internal_dispatcher_*` — compile-time collected static (always) /// /// Covers forms: -/// - `#[dispatcher_clap("greet", CMDGreet)] struct EntryGreet { ... }` -/// - `#[dispatcher_clap("greet", CMDGreet, error = ErrorGreet)] struct EntryGreet { ... }` -/// - `#[dispatcher_clap("greet", CMDGreet, help = true)] struct EntryGreet { ... }` -/// - `#[dispatcher_clap("greet", CMDGreet, error = ErrorGreet, help = true)] struct EntryGreet { ... }` +/// - `#[dispatcher_clap("greet")] struct EntryGreet { ... }` +/// - `#[dispatcher_clap("greet", error = ErrorGreet)] struct EntryGreet { ... }` +/// - `#[dispatcher_clap("greet", help = true)] struct EntryGreet { ... }` +/// - `#[dispatcher_clap("greet", error = ErrorGreet, help = true)] struct EntryGreet { ... }` #[derive(Default)] pub struct DispatcherClapPattern; @@ -95,9 +95,10 @@ impl DispatcherClapPattern { let args_str = args.map(|l| l.tokens.to_string()).unwrap_or_default(); let parsed = parse_dispatcher_clap_args(&args_str); - // CMD type — always - if let Some(ref cmd) = parsed.cmd_type { - items.push(AnalyzeItem::local(module.to_string(), cmd.clone())); + // Hidden dispatcher struct — always (if the command name is given) + if let Some(ref cmd_name) = parsed.cmd_name { + let hidden_name = format!("__Dispatcher{}", to_pascal_case(cmd_name)); + items.push(AnalyzeItem::local(module.to_string(), hidden_name)); } // Error type — if error = TypeName @@ -107,9 +108,9 @@ impl DispatcherClapPattern { // Help internal struct — if help = true if parsed.help_enabled - && let Some(ref cmd) = parsed.cmd_type + && let Some(ref cmd_name) = parsed.cmd_name { - let help_fn = format!("__{}_help", just_fmt::snake_case!(cmd)); + let help_fn = format!("__{}_help", just_fmt::snake_case!(cmd_name)); let help_struct = format!("__internal_help_{}", just_fmt::snake_case!(&help_fn)); items.push(AnalyzeItem::local(module.to_string(), help_struct)); } @@ -128,15 +129,13 @@ impl DispatcherClapPattern { struct ParsedClapArgs { cmd_name: Option<String>, - cmd_type: Option<String>, error_type: Option<String>, help_enabled: bool, } -/// Parse `#[dispatcher_clap("cmd", CMDType, error = ErrorType, help = true)]` arguments. +/// Parse `#[dispatcher_clap("cmd", error = ErrorType, help = true)]` arguments. fn parse_dispatcher_clap_args(args: &str) -> ParsedClapArgs { let mut cmd_name = None; - let mut cmd_type = None; let mut error_type = None; let mut help_enabled = false; @@ -178,23 +177,30 @@ fn parse_dispatcher_clap_args(args: &str) -> ParsedClapArgs { } _ => {} } - } else { - // Bare ident — the CMD type - let clean = part.trim_end_matches([')', ']']).trim(); - if !clean.is_empty() && cmd_type.is_none() { - cmd_type = Some(clean.to_string()); - } } + // Bare idents (e.g. the old CMD struct argument) are ignored. } ParsedClapArgs { cmd_name, - cmd_type, error_type, help_enabled, } } +/// Simple `pascal_case` conversion for deriving the hidden dispatcher name. +fn to_pascal_case(s: &str) -> String { + s.split(['-', '_', '.']) + .filter(|s| !s.is_empty()) + .map(|s| { + let mut c = s.chars(); + c.next().map_or_else(String::new, |f| { + f.to_uppercase().collect::<String>() + c.as_str() + }) + }) + .collect() +} + fn has_attr(attrs: &[syn::Attribute], name: &str) -> bool { attrs .iter() |
