aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-08-10 16:19:45 +0800
committer魏曹先生 <1992414357@qq.com>2026-08-10 16:19:45 +0800
commit2d0aae4b2d595ced100f7a2ec8d13b872a5eb65e (patch)
tree9df306e1185470655f3ed43fad866cf02430160f
parent61b770ca958afa7e5eca4c50f5e06bdf3ed7a94a (diff)
refactor: simplify macro parsing code and fix clippy warnings
-rw-r--r--mingling_core/src/build/comp.rs8
-rw-r--r--mingling_macros/src/attr/command.rs19
-rw-r--r--mingling_macros/src/attr/dispatcher_clap.rs55
-rw-r--r--mingling_macros/src/attr/program_setup.rs2
-rw-r--r--mingling_macros/src/func/dispatcher.rs2
-rw-r--r--mingling_macros/src/func/entry.rs4
-rw-r--r--mingling_macros/src/func/group.rs4
-rw-r--r--mingling_macros/src/func/group_structural.rs4
-rw-r--r--mingling_macros/src/func/pack_err.rs8
-rw-r--r--mingling_macros/src/func/pack_err_structural.rs9
-rw-r--r--mingling_macros/src/lib.rs4
11 files changed, 61 insertions, 58 deletions
diff --git a/mingling_core/src/build/comp.rs b/mingling_core/src/build/comp.rs
index 2abb1e1..c1000c7 100644
--- a/mingling_core/src/build/comp.rs
+++ b/mingling_core/src/build/comp.rs
@@ -10,6 +10,7 @@ const TMPL_COMP_FISH: &str = include_str!("../../tmpls/comps/fish.fish");
const TMPL_COMP_PWSH: &str = include_str!("../../tmpls/comps/pwsh.ps1");
/// Generate shell completion scripts for a given binary name.
+///
/// On Windows, generates `PowerShell` completion.
/// On Linux, generates Zsh, Bash, and Fish completions.
/// Scripts are written to the `OUT_DIR` (or `target/` if `OUT_DIR` is not set).
@@ -63,7 +64,7 @@ pub fn build_comp_scripts(name: &str) -> Result<(), std::io::Error> {
/// ```
pub fn build_comp_script(shell_flag: &ShellFlag, bin_name: &str) -> Result<(), std::io::Error> {
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
- let target_dir = out_dir.join("../../../").clone();
+ let target_dir = out_dir.join("../../../");
build_comp_script_to(shell_flag, bin_name, &target_dir.to_string_lossy())
}
@@ -116,13 +117,12 @@ pub fn build_comp_script_to_file(
std::fs::write(output_path.into(), tmpl.to_string())
}
-fn get_tmpl(shell_flag: &ShellFlag) -> (&'static str, &'static str) {
+const fn get_tmpl(shell_flag: &ShellFlag) -> (&'static str, &'static str) {
match shell_flag {
- ShellFlag::Bash => (TMPL_COMP_BASH, ".sh"),
+ ShellFlag::Bash | ShellFlag::Other(_) => (TMPL_COMP_BASH, ".sh"),
ShellFlag::Zsh => (TMPL_COMP_ZSH, ".zsh"),
ShellFlag::Fish => (TMPL_COMP_FISH, ".fish"),
ShellFlag::Powershell => (TMPL_COMP_PWSH, ".ps1"),
- ShellFlag::Other(_) => (TMPL_COMP_BASH, ".sh"),
}
}
diff --git a/mingling_macros/src/attr/command.rs b/mingling_macros/src/attr/command.rs
index 9598fa8..bec4dc2 100644
--- a/mingling_macros/src/attr/command.rs
+++ b/mingling_macros/src/attr/command.rs
@@ -51,8 +51,7 @@ impl Parse for CommandArgs {
entry = Some(input.parse()?);
} else {
return Err(input.error(format!(
- "unknown key `{}`; expected `node`, `name`, or `entry`",
- key
+ "unknown key `{key}`; expected `node`, `name`, or `entry`"
)));
}
} else {
@@ -67,7 +66,7 @@ impl Parse for CommandArgs {
}
}
- Ok(CommandArgs {
+ Ok(Self {
node,
name,
entry,
@@ -142,10 +141,10 @@ struct ResolvedNames {
fn resolve_names(fn_name: &Ident, args: &CommandArgs) -> ResolvedNames {
let fn_name_str = fn_name.to_string();
- let node_str = match &args.node {
- Some(lit) => lit.value(),
- None => default_node_from_fn(fn_name),
- };
+ let node_str = args
+ .node
+ .as_ref()
+ .map_or_else(|| default_node_from_fn(fn_name), syn::LitStr::value);
let node_lit = syn::LitStr::new(&node_str, fn_name.span());
let has_overrides = args.node.is_some() || args.name.is_some() || args.entry.is_some();
@@ -160,7 +159,7 @@ fn resolve_names(fn_name: &Ident, args: &CommandArgs) -> ResolvedNames {
Ident::new(&format!("Entry{pascal}"), fn_name.span())
});
- let chain_fn_name = Ident::new(&format!("__command_chain_{}", fn_name_str), fn_name.span());
+ let chain_fn_name = Ident::new(&format!("__command_chain_{fn_name_str}"), fn_name.span());
ResolvedNames {
node_lit,
@@ -213,7 +212,7 @@ fn build_wrapper_params(
let mut params = syn::punctuated::Punctuated::new();
let entry_param: FnArg = syn::parse_quote! { _args: #entry_type };
params.push(entry_param);
- for arg in sig.inputs.iter() {
+ for arg in &sig.inputs {
params.push(arg.clone());
}
params
@@ -317,7 +316,7 @@ pub(crate) fn command_attr(attr: TokenStream, item: TokenStream) -> TokenStream
let wrapper_full = format!("__command_chain_{}", &fn_name_s);
let snaked_wrapper = just_fmt::snake_case!(wrapper_full);
let chain_internal = Ident::new(
- &format!("__internal_chain_{}", snaked_wrapper),
+ &format!("__internal_chain_{snaked_wrapper}"),
fn_name.span(),
);
diff --git a/mingling_macros/src/attr/dispatcher_clap.rs b/mingling_macros/src/attr/dispatcher_clap.rs
index 218750c..c0665d0 100644
--- a/mingling_macros/src/attr/dispatcher_clap.rs
+++ b/mingling_macros/src/attr/dispatcher_clap.rs
@@ -39,11 +39,11 @@ impl Parse for ClapOptions {
error_struct = Some(value);
} else if key == "help" {
let value: LitBool = input.parse()?;
- if !value.value() {
+ if value.value() {
+ help_enabled = true;
+ } else {
// help = false is allowed but does nothing
help_enabled = false;
- } else {
- help_enabled = true;
}
} else {
return Err(syn::Error::new(
@@ -53,14 +53,14 @@ impl Parse for ClapOptions {
}
}
- Ok(ClapOptions {
+ Ok(Self {
error_struct,
help_enabled,
})
}
}
-/// Input for the dispatcher_clap attribute
+/// Input for the `dispatcher_clap` attribute
struct DispatcherClapInput {
/// `("cmd", Disp, ...)`
command_name: LitStr,
@@ -84,7 +84,7 @@ impl Parse for DispatcherClapInput {
input.parse::<ClapOptions>()?
};
- Ok(DispatcherClapInput {
+ Ok(Self {
command_name,
dispatcher_struct,
options,
@@ -105,28 +105,31 @@ pub(crate) fn dispatcher_clap_attr(attr: TokenStream, item: TokenStream) -> Toke
let options = &attr_input.options;
// Generate the `begin` method body
- let begin_body = if let Some(ref error_struct) = options.error_struct {
- quote! {
- if ::mingling::this::<#program_path>().user_context.help {
- return ::mingling::Routable::<#program_path>::to_chain(#struct_name::default());
- }
- match <#struct_name as ::clap::Parser>::try_parse_from(clap_args) {
- Ok(parsed) => ::mingling::Routable::<#program_path>::to_chain(parsed),
- Err(e) => {
- return ::mingling::Routable::<#program_path>::to_render(#error_struct::new(format!("{}", e.render().ansi())))
- },
+ let begin_body = options.error_struct.as_ref().map_or_else(
+ || {
+ quote! {
+ if ::mingling::this::<#program_path>().user_context.help {
+ return ::mingling::Routable::<#program_path>::to_chain(#struct_name::default());
+ }
+ let parsed = <#struct_name as ::clap::Parser>::try_parse_from(clap_args)
+ .unwrap_or_else(|e| e.exit());
+ ::mingling::Routable::<#program_path>::to_chain(parsed)
}
- }
- } else {
- quote! {
- if ::mingling::this::<#program_path>().user_context.help {
- return ::mingling::Routable::<#program_path>::to_chain(#struct_name::default());
+ },
+ |error_struct| {
+ quote! {
+ if ::mingling::this::<#program_path>().user_context.help {
+ return ::mingling::Routable::<#program_path>::to_chain(#struct_name::default());
+ }
+ match <#struct_name as ::clap::Parser>::try_parse_from(clap_args) {
+ Ok(parsed) => ::mingling::Routable::<#program_path>::to_chain(parsed),
+ Err(e) => {
+ return ::mingling::Routable::<#program_path>::to_render(#error_struct::new(format!("{}", e.render().ansi())))
+ },
+ }
}
- let parsed = <#struct_name as ::clap::Parser>::try_parse_from(clap_args)
- .unwrap_or_else(|e| e.exit());
- ::mingling::Routable::<#program_path>::to_chain(parsed)
- }
- };
+ },
+ );
// Generate the error pack type
let error_pack = options.error_struct.as_ref().map(|error_struct| {
diff --git a/mingling_macros/src/attr/program_setup.rs b/mingling_macros/src/attr/program_setup.rs
index dee5a1c..fa01178 100644
--- a/mingling_macros/src/attr/program_setup.rs
+++ b/mingling_macros/src/attr/program_setup.rs
@@ -47,7 +47,7 @@ fn extract_return_type(sig: &Signature) -> syn::Result<()> {
}
}
-pub(crate) fn setup_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
+pub(crate) fn setup_attr(attr: &TokenStream, item: TokenStream) -> TokenStream {
// #[program_setup] takes no arguments; always use the default program path
let _ = attr;
let program_path = crate::default_program_path();
diff --git a/mingling_macros/src/func/dispatcher.rs b/mingling_macros/src/func/dispatcher.rs
index d834c95..bbe1074 100644
--- a/mingling_macros/src/func/dispatcher.rs
+++ b/mingling_macros/src/func/dispatcher.rs
@@ -32,7 +32,7 @@ impl Parse for DispatcherChainInput {
if input.is_empty() {
#[cfg(feature = "extras")]
{
- return Ok(DispatcherChainInput::Auto {
+ return Ok(Self::Auto {
cmd_attrs,
command_name,
});
diff --git a/mingling_macros/src/func/entry.rs b/mingling_macros/src/func/entry.rs
index 35209e5..76fbc15 100644
--- a/mingling_macros/src/func/entry.rs
+++ b/mingling_macros/src/func/entry.rs
@@ -18,11 +18,11 @@ impl syn::parse::Parse for EntryInput {
let content;
syn::bracketed!(content in input);
let strings = parse_strings(&content)?;
- Ok(EntryInput::Typed { ident, strings })
+ Ok(Self::Typed { ident, strings })
} else {
// entry!["a", "b", "c"] — bare bracket content
let strings = parse_strings(input)?;
- Ok(EntryInput::Untyped { strings })
+ Ok(Self::Untyped { strings })
}
}
}
diff --git a/mingling_macros/src/func/group.rs b/mingling_macros/src/func/group.rs
index edb1fe1..8ca46d9 100644
--- a/mingling_macros/src/func/group.rs
+++ b/mingling_macros/src/func/group.rs
@@ -33,10 +33,10 @@ impl Parse for GroupInput {
let alias: Ident = input.parse()?;
let _eq: syn::Token![=] = input.parse()?;
let type_path: TypePath = input.parse()?;
- Ok(GroupInput::Aliased { alias, type_path })
+ Ok(Self::Aliased { alias, type_path })
} else {
let type_path: TypePath = input.parse()?;
- Ok(GroupInput::Plain(type_path))
+ Ok(Self::Plain(type_path))
}
}
}
diff --git a/mingling_macros/src/func/group_structural.rs b/mingling_macros/src/func/group_structural.rs
index 2bd2f83..3e6dbc5 100644
--- a/mingling_macros/src/func/group_structural.rs
+++ b/mingling_macros/src/func/group_structural.rs
@@ -115,10 +115,10 @@ impl syn::parse::Parse for GroupStructuralInput {
let alias: Ident = input.parse()?;
let _eq: syn::Token![=] = input.parse()?;
let type_path: TypePath = input.parse()?;
- Ok(GroupStructuralInput::Aliased { alias, type_path })
+ Ok(Self::Aliased { alias, type_path })
} else {
let type_path: TypePath = input.parse()?;
- Ok(GroupStructuralInput::Plain(type_path))
+ Ok(Self::Plain(type_path))
}
}
}
diff --git a/mingling_macros/src/func/pack_err.rs b/mingling_macros/src/func/pack_err.rs
index 8b224b0..dcfcf86 100644
--- a/mingling_macros/src/func/pack_err.rs
+++ b/mingling_macros/src/func/pack_err.rs
@@ -4,9 +4,9 @@ use quote::quote;
use syn::{Ident, Token, Type, parse_macro_input};
enum PackErrInput {
- /// pack_err!(ErrorNotFound)
+ /// `pack_err!(ErrorNotFound)`
Simple { type_name: Ident },
- /// pack_err!(ErrorNotDir = PathBuf)
+ /// `pack_err!(ErrorNotDir = PathBuf)`
Typed {
type_name: Ident,
inner_type: Box<Type>,
@@ -20,12 +20,12 @@ impl syn::parse::Parse for PackErrInput {
if input.peek(Token![=]) {
input.parse::<Token![=]>()?;
let inner_type: Type = input.parse()?;
- Ok(PackErrInput::Typed {
+ Ok(Self::Typed {
type_name,
inner_type: Box::new(inner_type),
})
} else {
- Ok(PackErrInput::Simple { type_name })
+ Ok(Self::Simple { type_name })
}
}
}
diff --git a/mingling_macros/src/func/pack_err_structural.rs b/mingling_macros/src/func/pack_err_structural.rs
index 7d3a6f8..2c4a2fb 100644
--- a/mingling_macros/src/func/pack_err_structural.rs
+++ b/mingling_macros/src/func/pack_err_structural.rs
@@ -9,8 +9,9 @@ pub(crate) fn pack_err_structural(input: TokenStream) -> TokenStream {
let parsed = parse_macro_input!(input as PackErrInput);
let type_name = match &parsed {
- PackErrInput::Simple { type_name } => type_name.clone(),
- PackErrInput::Typed { type_name, .. } => type_name.clone(),
+ PackErrInput::Simple { type_name } | PackErrInput::Typed { type_name, .. } => {
+ type_name.clone()
+ }
};
// Register in STRUCTURED_TYPES
@@ -108,12 +109,12 @@ impl syn::parse::Parse for PackErrInput {
if input.peek(Token![=]) {
input.parse::<Token![=]>()?;
let inner_type: Type = input.parse()?;
- Ok(PackErrInput::Typed {
+ Ok(Self::Typed {
type_name,
inner_type: Box::new(inner_type),
})
} else {
- Ok(PackErrInput::Simple { type_name })
+ Ok(Self::Simple { type_name })
}
}
}
diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs
index c87584d..6ae8693 100644
--- a/mingling_macros/src/lib.rs
+++ b/mingling_macros/src/lib.rs
@@ -438,7 +438,7 @@ pub fn pack_structural(input: TokenStream) -> TokenStream {
/// This macro provides a concise way to define error types that implement `Grouped`
/// and are registered for inclusion in the program enum.
///
-/// The `name` field is automatically set to the snake_case version of the struct name
+/// The `name` field is automatically set to the `snake_case` version of the struct name
/// at compile time.
///
/// # Syntax
@@ -1101,7 +1101,7 @@ pub fn completion(attr: TokenStream, item: TokenStream) -> TokenStream {
#[cfg(feature = "extras")]
#[proc_macro_attribute]
pub fn program_setup(attr: TokenStream, item: TokenStream) -> TokenStream {
- program_setup::setup_attr(attr, item)
+ program_setup::setup_attr(&attr, item)
}
/// Declares a command from a plain function.