From 2aa7bda3cb21ce6c052b82e08bcab79a625d04f2 Mon Sep 17 00:00:00 2001 From: Weicao-CatilGrass <1992414357@qq.com> Date: Sun, 31 May 2026 02:42:52 +0800 Subject: Enhance code quality across the entire codebase --- mingling_macros/src/chain.rs | 8 +++---- mingling_macros/src/dispatch_tree_gen.rs | 14 +++++------ mingling_macros/src/dispatcher.rs | 3 ++- mingling_macros/src/entry.rs | 23 +++++++----------- mingling_macros/src/enum_tag.rs | 15 ++++++------ mingling_macros/src/groupped.rs | 22 +++++++---------- mingling_macros/src/lib.rs | 24 +++++++++++++------ mingling_macros/src/pack.rs | 1 + mingling_macros/src/renderer.rs | 41 ++++++++++++++------------------ mingling_macros/src/res_injection.rs | 3 ++- 10 files changed, 75 insertions(+), 79 deletions(-) (limited to 'mingling_macros/src') diff --git a/mingling_macros/src/chain.rs b/mingling_macros/src/chain.rs index ac05480..b0ea8ae 100644 --- a/mingling_macros/src/chain.rs +++ b/mingling_macros/src/chain.rs @@ -229,8 +229,8 @@ fn generate_struct_and_impl( group_name: &proc_macro2::TokenStream, program_type: &proc_macro2::TokenStream, use_crate_prefix: bool, - proc_fn: proc_macro2::TokenStream, - origin_proc_fn: proc_macro2::TokenStream, + proc_fn: &proc_macro2::TokenStream, + origin_proc_fn: &proc_macro2::TokenStream, ) -> proc_macro2::TokenStream { let chain_type = if use_crate_prefix { program_type @@ -389,8 +389,8 @@ pub fn chain_attr(attr: TokenStream, item: TokenStream) -> TokenStream { &group_name, &program_type, use_crate_prefix, - proc_fn, - origin_proc_fn, + &proc_fn, + &origin_proc_fn, ); expanded.into() diff --git a/mingling_macros/src/dispatch_tree_gen.rs b/mingling_macros/src/dispatch_tree_gen.rs index a2cd52c..66fb6e7 100644 --- a/mingling_macros/src/dispatch_tree_gen.rs +++ b/mingling_macros/src/dispatch_tree_gen.rs @@ -43,7 +43,7 @@ pub fn gen_dispatch_args_trie(entries: &[(String, String, String)]) -> TokenStre quote! { fn dispatch_args_trie( - raw: &Vec, + raw: &[String], ) -> Result<::mingling::AnyOutput, ::mingling::error::ProgramInternalExecuteError> { let raw_string = format!("{} ", raw.join(" ")); @@ -63,7 +63,7 @@ pub fn gen_dispatch_args_trie(entries: &[(String, String, String)]) -> TokenStre fn build_dispatch_body(nodes: &[(String, String)], depth: usize) -> TokenStream { if nodes.is_empty() { return quote! { - return Ok(Self::build_dispatcher_not_found(raw.clone())); + return Ok(Self::build_dispatcher_not_found(raw.to_vec())); }; } @@ -121,7 +121,7 @@ fn build_dispatch_body(nodes: &[(String, String)], depth: usize) -> TokenStream arms.push(quote! { Some(#ch_char) => { #arm - return Ok(Self::build_dispatcher_not_found(raw.clone())); + return Ok(Self::build_dispatcher_not_found(raw.to_vec())); } }); } else { @@ -150,7 +150,7 @@ fn build_dispatch_body(nodes: &[(String, String)], depth: usize) -> TokenStream let match_body = quote! { match raw_chars.nth(0) { #(#arms)* - _ => return Ok(Self::build_dispatcher_not_found(raw.clone())), + _ => return Ok(Self::build_dispatcher_not_found(raw.to_vec())), } }; quote! { @@ -161,19 +161,19 @@ fn build_dispatch_body(nodes: &[(String, String)], depth: usize) -> TokenStream // Only exact nodes, no deeper groups quote! { #(#exact_checks)* - return Ok(Self::build_dispatcher_not_found(raw.clone())); + return Ok(Self::build_dispatcher_not_found(raw.to_vec())); } } else if arms.is_empty() { // Only fallback (shouldn't happen if nodes is non-empty) quote! { - return Ok(Self::build_dispatcher_not_found(raw.clone())); + return Ok(Self::build_dispatcher_not_found(raw.to_vec())); } } else { // Only group arms quote! { match raw_chars.nth(0) { #(#arms)* - _ => return Ok(Self::build_dispatcher_not_found(raw.clone())), + _ => return Ok(Self::build_dispatcher_not_found(raw.to_vec())), } } } diff --git a/mingling_macros/src/dispatcher.rs b/mingling_macros/src/dispatcher.rs index b7952a1..7e973eb 100644 --- a/mingling_macros/src/dispatcher.rs +++ b/mingling_macros/src/dispatcher.rs @@ -104,6 +104,7 @@ impl Parse for DispatcherChainInput { // Additionally, the token stream generation patterns are nearly identical between // the two main functions and could benefit from refactoring. +#[allow(clippy::too_many_lines)] pub fn dispatcher(input: TokenStream) -> TokenStream { // Parse the input let dispatcher_input = syn::parse_macro_input!(input as DispatcherChainInput); @@ -332,7 +333,7 @@ pub fn register_dispatcher(_input: TokenStream) -> TokenStream { quote! {}.into() } -/// Converts a dotted command name (e.g. "remote.add") to PascalCase (e.g. "RemoteAdd"). +/// Converts a dotted command name (e.g. "remote.add") to `PascalCase` (e.g. "`RemoteAdd`"). /// /// Each segment is split by `.`, the first character of each segment is uppercased, /// and the segments are joined. This is used by the abbreviated `dispatcher!` syntax diff --git a/mingling_macros/src/entry.rs b/mingling_macros/src/entry.rs index 6237e41..2ac5d6b 100644 --- a/mingling_macros/src/entry.rs +++ b/mingling_macros/src/entry.rs @@ -42,21 +42,16 @@ fn parse_strings(input: &syn::parse::ParseBuffer) -> syn::Result> { pub fn entry(input: TokenStream) -> TokenStream { let parsed = parse_macro_input!(input as EntryInput); - let string_exprs = match &parsed { - EntryInput::Typed { .. } | EntryInput::Untyped { .. } => { - let strings = match &parsed { - EntryInput::Typed { strings, .. } => strings, - EntryInput::Untyped { strings } => strings, - }; - strings - .iter() - .map(|s| { - let lit = syn::LitStr::new(s, proc_macro2::Span::call_site()); - quote! { #lit.to_string() } - }) - .collect::>() - } + let strings = match &parsed { + EntryInput::Typed { strings, .. } | EntryInput::Untyped { strings } => strings, }; + let string_exprs = strings + .iter() + .map(|s| { + let lit = syn::LitStr::new(s, proc_macro2::Span::call_site()); + quote! { #lit.to_string() } + }) + .collect::>(); let expanded = match parsed { EntryInput::Typed { ident, .. } => { diff --git a/mingling_macros/src/enum_tag.rs b/mingling_macros/src/enum_tag.rs index 8f0576a..6277b69 100644 --- a/mingling_macros/src/enum_tag.rs +++ b/mingling_macros/src/enum_tag.rs @@ -13,7 +13,7 @@ pub fn derive_enum_tag(input: TokenStream) -> TokenStream { } } -/// Implementation of the EnumTag derive macro +/// Implementation of the `EnumTag` derive macro fn derive_enum_tag_impl(input: DeriveInput) -> Result { let enum_name = &input.ident; let generics = &input.generics; @@ -42,7 +42,7 @@ fn derive_enum_tag_impl(input: DeriveInput) -> Result for variant in data.variants { process_variant( - variant, + &variant, enum_name, &mut variant_info, &mut match_arms, @@ -82,7 +82,7 @@ fn derive_enum_tag_impl(input: DeriveInput) -> Result /// Process a single enum variant fn process_variant( - variant: Variant, + variant: &Variant, enum_name: &Ident, variant_info: &mut Vec, match_arms: &mut Vec, @@ -97,10 +97,9 @@ fn process_variant( } Fields::Named(_) | Fields::Unnamed(_) => { return Err(Error::new_spanned( - &variant, + variant, format!( - "EnumTag cannot be derived for enum variant `{}` with fields. Only unit variants are supported.", - variant_name + "EnumTag cannot be derived for enum variant `{variant_name}` with fields. Only unit variants are supported." ), )); } @@ -132,7 +131,7 @@ fn process_variant( Ok(()) } -/// Extract description from #[enum_desc] attribute +/// Extract description from #[`enum_desc`] attribute fn extract_description(attrs: &[Attribute]) -> Result> { for attr in attrs { if attr.path().is_ident("enum_desc") { @@ -150,7 +149,7 @@ fn extract_description(attrs: &[Attribute]) -> Result> { Ok(None) } -/// Extract rename from #[enum_rename] attribute +/// Extract rename from #[`enum_rename`] attribute fn extract_rename(attrs: &[Attribute]) -> Result> { for attr in attrs { if attr.path().is_ident("enum_rename") { diff --git a/mingling_macros/src/groupped.rs b/mingling_macros/src/groupped.rs index e385812..534e2a6 100644 --- a/mingling_macros/src/groupped.rs +++ b/mingling_macros/src/groupped.rs @@ -23,13 +23,10 @@ pub fn derive_groupped(input: TokenStream) -> TokenStream { // Parse attributes to find #[group(...)] let group_ident: proc_macro2::TokenStream = parse_group_attribute(&input.attrs) - .map(|ident| quote! { #ident }) - .unwrap_or_else(crate::default_program_path); + .map_or_else(crate::default_program_path, |ident| quote! { #ident }); - let any_output_convert_impls = proc_macro2::TokenStream::from(build_any_output_convert_impls( - struct_name.clone(), - group_ident.clone(), - )); + let any_output_convert_impls = + proc_macro2::TokenStream::from(build_any_output_convert_impls(&struct_name, &group_ident)); // Generate the Groupped trait implementation let expanded = quote! { @@ -55,13 +52,10 @@ pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream { // Parse attributes to find #[group(...)] let group_ident: proc_macro2::TokenStream = parse_group_attribute(&input_parsed.attrs) - .map(|ident| quote! { #ident }) - .unwrap_or_else(crate::default_program_path); + .map_or_else(crate::default_program_path, |ident| quote! { #ident }); - let any_output_convert_impls = proc_macro2::TokenStream::from(build_any_output_convert_impls( - struct_name.clone(), - group_ident.clone(), - )); + let any_output_convert_impls = + proc_macro2::TokenStream::from(build_any_output_convert_impls(&struct_name, &group_ident)); // Generate both Serialize and Groupped implementations let expanded = quote! { @@ -83,8 +77,8 @@ pub fn derive_groupped_serialize(input: TokenStream) -> TokenStream { } fn build_any_output_convert_impls( - struct_name: Ident, - group_ident: proc_macro2::TokenStream, + struct_name: &Ident, + group_ident: &proc_macro2::TokenStream, ) -> TokenStream { quote! { impl ::std::convert::Into<::mingling::AnyOutput<#group_ident>> for #struct_name { diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs index 8cae29f..7a93895 100644 --- a/mingling_macros/src/lib.rs +++ b/mingling_macros/src/lib.rs @@ -82,7 +82,7 @@ pub(crate) static CHAINS_EXIST: Registry = OnceLock::new(); pub(crate) static RENDERERS_EXIST: Registry = OnceLock::new(); pub(crate) static HELP_REQUESTS: Registry = OnceLock::new(); -/// Checks that a TypePath is a simple single-segment identifier (no `::` in the path). +/// Checks that a `TypePath` is a simple single-segment identifier (no `::` in the path). /// /// This is used by `#[renderer]`, `#[help]`, `#[chain]`, and `#[completion]` attribute macros /// to ensure that the type in the function signature is a bare identifier like `Empty`, @@ -307,7 +307,7 @@ pub fn empty_result(_input: TokenStream) -> TokenStream { /// /// When the `extra_macros` feature is enabled, the `CommandStruct => EntryStruct` /// portion can be omitted. The struct names are auto-derived from the command path -/// using PascalCase conversion: +/// using `PascalCase` conversion: /// /// ```rust,ignore /// // Auto-derives: "remote.add" → CMDRemoteAdd ⇒ EntryRemoteAdd @@ -1188,7 +1188,7 @@ pub fn program_comp_gen(input: TokenStream) -> TokenStream { /// Registers a type into the global packed types registry for inclusion in /// the program enum generated by `gen_program!`. /// -/// This macro is called internally by `pack!` and `#[derive(Groupped)]`(macro.derive_groupped.html) +/// This macro is called internally by `pack!` and `#[derive(Groupped)]`(`macro.derive_groupped.html`) /// and is generally not needed in user code. However, it can be used for manual /// registration if you are implementing custom type registration outside of /// the standard macros. @@ -1201,6 +1201,10 @@ pub fn program_comp_gen(input: TokenStream) -> TokenStream { /// /// Each call inserts the type's name into the `PACKED_TYPES` global set, which /// is later consumed by `program_final_gen!` to generate enum variants. +/// +/// # Panics +/// +/// Panics if the global `PACKED_TYPES` mutex is poisoned. #[proc_macro] pub fn register_type(input: TokenStream) -> TokenStream { let type_ident = parse_macro_input!(input as syn::Ident); @@ -1348,7 +1352,13 @@ pub fn program_fallback_gen(input: TokenStream) -> TokenStream { /// pub fn new() -> Program { Program::new() } /// } /// ``` +/// +/// # Panics +/// +/// Panics if any of the global registries (`PACKED_TYPES`, `RENDERERS`, `CHAINS`, etc.) +/// are poisoned. #[proc_macro] +#[allow(clippy::too_many_lines)] pub fn program_final_gen(input: TokenStream) -> TokenStream { let name = read_name(&input); @@ -1479,11 +1489,11 @@ pub fn program_final_gen(input: TokenStream) -> TokenStream { .collect(); let num_variants = packed_types.len(); - let repr_type = if num_variants <= u8::MAX as usize { + let repr_type = if u8::try_from(num_variants).is_ok() { quote! { u8 } - } else if num_variants <= u16::MAX as usize { + } else if u16::try_from(num_variants).is_ok() { quote! { u16 } - } else if num_variants <= u32::MAX as usize { + } else if u32::try_from(num_variants).is_ok() { quote! { u32 } } else { quote! { u128 } @@ -1612,7 +1622,7 @@ pub fn program_final_gen(input: TokenStream) -> TokenStream { /// /// # Related /// -/// - `suggest_enum!`(macro.suggest_enum.html) — Build suggestions from an `EnumTag` enum. +/// - `suggest_enum!`(`macro.suggest_enum.html`) — Build suggestions from an `EnumTag` enum. #[cfg(feature = "comp")] #[proc_macro] pub fn suggest(input: TokenStream) -> TokenStream { diff --git a/mingling_macros/src/pack.rs b/mingling_macros/src/pack.rs index 954a052..5a1c388 100644 --- a/mingling_macros/src/pack.rs +++ b/mingling_macros/src/pack.rs @@ -59,6 +59,7 @@ impl Parse for PackInput { } } +#[allow(clippy::too_many_lines)] pub fn pack(input: TokenStream) -> TokenStream { // Parse the input let pack_input = syn::parse_macro_input!(input as PackInput); diff --git a/mingling_macros/src/renderer.rs b/mingling_macros/src/renderer.rs index ae75895..4cf9fc1 100644 --- a/mingling_macros/src/renderer.rs +++ b/mingling_macros/src/renderer.rs @@ -7,20 +7,21 @@ use crate::get_global_set; use crate::res_injection::{extract_args_info, generate_immut_resource_bindings}; /// Extracts and returns the return type from the function signature (or None for `()` / no return type). -fn extract_return_type(sig: &Signature) -> syn::Result> { +fn extract_return_type(sig: &Signature) -> Option { match &sig.output { ReturnType::Type(_, ty) => { match &**ty { // `()` means no custom return type - Type::Tuple(tuple) if tuple.elems.is_empty() => Ok(None), + Type::Tuple(tuple) if tuple.elems.is_empty() => None, // Any other return type is allowed - custom_ty => Ok(Some((*custom_ty).clone())), + custom_ty => Some((*custom_ty).clone()), } } - ReturnType::Default => Ok(None), + ReturnType::Default => None, } } +#[allow(clippy::too_many_lines)] pub fn renderer_attr(attr: TokenStream, item: TokenStream) -> TokenStream { // Parse attribute arguments for program path (e.g. #[renderer(my_crate::Program)]) let (program_path, _use_crate_prefix) = parse_renderer_attr_args(attr); @@ -48,10 +49,7 @@ pub fn renderer_attr(attr: TokenStream, item: TokenStream) -> TokenStream { } // Validate return type – now returns Some(type) if custom type, None if () - let return_type = match extract_return_type(&input_fn.sig) { - Ok(rt) => rt, - Err(e) => return e.to_compile_error().into(), - }; + let return_type = extract_return_type(&input_fn.sig); // Get function body statements let fn_body_stmts: Vec = input_fn.block.stmts.clone(); @@ -83,23 +81,20 @@ pub fn renderer_attr(attr: TokenStream, item: TokenStream) -> TokenStream { let mut_resources: Vec<_> = resources.iter().filter(|r| r.is_mut).collect(); // Determine public return type and the expression to return dummy_r - let (public_return_type, result_return) = match &return_type { + let (public_return_type, result_return) = if let Some(custom_ty) = &return_type { // User specified a custom return type (e.g. -> String) - Some(custom_ty) => { - let ret_ty = quote! { #custom_ty }; - let expr = quote! { dummy_r.into() }; - (ret_ty, expr) - } + let ret_ty = quote! { #custom_ty }; + let expr = quote! { dummy_r.into() }; + (ret_ty, expr) + } else { // Return type is () — no custom return type specified - None => { - let ret_ty = quote! { () }; - let expr = quote! { - if !dummy_r.is_empty() { - ::std::println!("{}", &*dummy_r); - } - }; - (ret_ty, expr) - } + let ret_ty = quote! { () }; + let expr = quote! { + if !dummy_r.is_empty() { + ::std::println!("{}", &*dummy_r); + } + }; + (ret_ty, expr) }; let inner_body_with_resources = if has_mut_resources { diff --git a/mingling_macros/src/res_injection.rs b/mingling_macros/src/res_injection.rs index bdb3b73..f2280e3 100644 --- a/mingling_macros/src/res_injection.rs +++ b/mingling_macros/src/res_injection.rs @@ -13,6 +13,7 @@ pub(crate) struct ResourceInjection { /// Extracts the previous type and parameter name from function arguments, /// and collects resource injection parameters from the 2nd argument onward. +#[allow(clippy::too_many_lines)] pub(crate) fn extract_args_info( sig: &Signature, ) -> syn::Result<(Pat, TypePath, Vec)> { @@ -183,7 +184,7 @@ pub(crate) fn wrap_body_with_mut_resources( #(#fn_body_stmts)* }; - for res in mut_resources.iter() { + for res in mut_resources { let var_name = &res.var_name; let inner_type = &res.inner_type; wrapped = quote! { -- cgit