diff options
| author | Weicao-CatilGrass <1992414357@qq.com> | 2026-05-31 02:42:52 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-05-31 17:19:20 +0800 |
| commit | 2aa7bda3cb21ce6c052b82e08bcab79a625d04f2 (patch) | |
| tree | f10b89007fc67ca1a948f34abe6869b49296b932 /mingling_core | |
| parent | 3aa409a55e4f2f0ab41b0949cc06eb13c2da4a43 (diff) | |
Enhance code quality across the entire codebase
Diffstat (limited to 'mingling_core')
28 files changed, 229 insertions, 120 deletions
diff --git a/mingling_core/Cargo.toml b/mingling_core/Cargo.toml index 26e642b..4ce9ecd 100644 --- a/mingling_core/Cargo.toml +++ b/mingling_core/Cargo.toml @@ -2,9 +2,13 @@ name = "mingling_core" version.workspace = true edition.workspace = true +authors = ["Weicao-CatilGrass"] license.workspace = true description = "Core of the mingling library" +readme = "README.md" repository.workspace = true +keywords = ["cli", "cli-framework", "framework", "procedural", "command-line"] +categories = ["command-line-interface"] [features] nightly = [] diff --git a/mingling_core/src/any.rs b/mingling_core/src/any.rs index 3dedea4..46ebced 100644 --- a/mingling_core/src/any.rs +++ b/mingling_core/src/any.rs @@ -10,7 +10,7 @@ pub mod group; /// Any type output /// /// Accepts any type that implements `Send + Groupped<G>` -/// After being passed into AnyOutput, it will be converted to `Box<dyn Any + Send + 'static>` +/// After being passed into `AnyOutput`, it will be converted to `Box<dyn Any + Send + 'static>` /// /// Note: /// - If an enum value that does not belong to this type is incorrectly specified, it will be **unsafely** unwrapped by the scheduler @@ -24,7 +24,7 @@ pub struct AnyOutput<G> { } impl<G> AnyOutput<G> { - /// Create an AnyOutput from a `Send + Groupped<G> + Serialize` type + /// Create an `AnyOutput` from a `Send + Groupped<G> + Serialize` type #[cfg(feature = "general_renderer")] pub fn new<T>(value: T) -> Self where @@ -37,7 +37,7 @@ impl<G> AnyOutput<G> { } } - /// Create an AnyOutput from a `Send + Groupped<G>` type + /// Create an `AnyOutput` from a `Send + Groupped<G>` type #[cfg(not(feature = "general_renderer"))] pub fn new<T>(value: T) -> Self where @@ -50,7 +50,15 @@ impl<G> AnyOutput<G> { } } - /// Downcast the AnyOutput to a concrete type T + /// Attempt to downcast the `AnyOutput` to a concrete type. + /// + /// # Errors + /// + /// Returns `Err(self)` if the downcast fails. + /// + /// # Panics + /// + /// Panics if the inner value is not of type `T`. pub fn downcast<T: 'static>(self) -> Result<T, Self> { if self.type_id == std::any::TypeId::of::<T>() { Ok(*self.inner.downcast::<T>().unwrap()) @@ -75,7 +83,7 @@ impl<G> AnyOutput<G> { } #[cfg(feature = "general_renderer")] - /// Restore AnyOutput back to the original Serialize type + /// Restore `AnyOutput` back to the original Serialize type pub fn restore<T: Serialize + 'static>(self) -> Option<T> { if self.type_id == std::any::TypeId::of::<T>() { match self.inner.downcast::<T>() { diff --git a/mingling_core/src/asset/chain.rs b/mingling_core/src/asset/chain.rs index 1b488fe..423e218 100644 --- a/mingling_core/src/asset/chain.rs +++ b/mingling_core/src/asset/chain.rs @@ -3,7 +3,7 @@ use crate::ChainProcess; #[doc(hidden)] pub mod error; -/// Takes over a type (G: Previous) and converts it to another [AnyOutput](./struct.AnyOutput.html) +/// Takes over a type (G: Previous) and converts it to another [`AnyOutput`](./struct.AnyOutput.html) pub trait Chain<G> { /// The previous type in the chain type Previous; diff --git a/mingling_core/src/asset/chain/error.rs b/mingling_core/src/asset/chain/error.rs index ce69bc5..29abba1 100644 --- a/mingling_core/src/asset/chain/error.rs +++ b/mingling_core/src/asset/chain/error.rs @@ -13,8 +13,8 @@ pub enum ChainProcessError { impl std::fmt::Display for ChainProcessError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - ChainProcessError::Other(s) => write!(f, "Other error: {}", s), - ChainProcessError::IO(e) => write!(f, "IO error: {}", e), + ChainProcessError::Other(s) => write!(f, "Other error: {s}"), + ChainProcessError::IO(e) => write!(f, "IO error: {e}"), } } } @@ -41,14 +41,14 @@ impl From<ProgramInternalExecuteError> for ChainProcessError { ChainProcessError::Other("DispatcherNotFound".into()) } ProgramInternalExecuteError::RendererNotFound(r) => { - ChainProcessError::Other(format!("RendererNotFound: {}", r)) + ChainProcessError::Other(format!("RendererNotFound: {r}")) } ProgramInternalExecuteError::Other(e) => ChainProcessError::Other(e), ProgramInternalExecuteError::IO(e) => { - ChainProcessError::Other(format!("IOError: {:?}", e)) + ChainProcessError::Other(format!("IOError: {e:?}")) } ProgramInternalExecuteError::REPLPanic(program_panic) => { - ChainProcessError::Other(format!("REPLPanic: {}", program_panic)) + ChainProcessError::Other(format!("REPLPanic: {program_panic}")) } } } diff --git a/mingling_core/src/asset/dispatcher.rs b/mingling_core/src/asset/dispatcher.rs index 95b3305..b62a0d0 100644 --- a/mingling_core/src/asset/dispatcher.rs +++ b/mingling_core/src/asset/dispatcher.rs @@ -2,7 +2,7 @@ use std::fmt::Display; use crate::{ChainProcess, Program, ProgramCollect, asset::node::Node}; -/// Dispatches user input commands to specific [ChainProcess](./enum.ChainProcess.html) +/// Dispatches user input commands to specific [`ChainProcess`](./enum.ChainProcess.html) /// /// Note: If you are using [mingling_macros](https://crates.io/crates/mingling_macros), /// you can use the `dispatcher!("node.subnode", CommandType => Entry)` macro to declare a `Dispatcher` @@ -10,7 +10,7 @@ pub trait Dispatcher<C> { /// Returns a command node for matching user input fn node(&self) -> Node; - /// Returns a [ChainProcess](./enum.ChainProcess.html) based on user input arguments, + /// Returns a [`ChainProcess`](./enum.ChainProcess.html) based on user input arguments, /// to be sent to the specific invocation fn begin(&self, args: Vec<String>) -> ChainProcess<C>; diff --git a/mingling_core/src/asset/enum_tag.rs b/mingling_core/src/asset/enum_tag.rs index 28428a6..d830e62 100644 --- a/mingling_core/src/asset/enum_tag.rs +++ b/mingling_core/src/asset/enum_tag.rs @@ -1,4 +1,4 @@ -/// Marker trait for EnumTag +/// Marker trait for `EnumTag` pub trait EnumTag { /// Get the name and description of this enum fn enum_info(&self) -> (&'static str, &'static str); diff --git a/mingling_core/src/asset/global_resource.rs b/mingling_core/src/asset/global_resource.rs index 98a8160..d03c6ea 100644 --- a/mingling_core/src/asset/global_resource.rs +++ b/mingling_core/src/asset/global_resource.rs @@ -25,11 +25,8 @@ where Res: 'static + Default + ResourceMarker + Send + Sync, Return: Default, { - let mut guard = match self.resources.lock() { - Ok(guard) => guard, - Err(_) => { - return Return::default(); - } + let Ok(mut guard) = self.resources.lock() else { + return Return::default(); }; if let Some(arc_res) = guard .get_mut(&TypeId::of::<Res>()) @@ -56,12 +53,9 @@ where Res: 'static + Default + ResourceMarker + Send + Sync, Return: Into<ChainProcess<C>>, { - let mut guard = match self.resources.lock() { - Ok(guard) => guard, - Err(_) => { - let mut default_res = Res::res_default(); - return f(&mut default_res); - } + let Ok(mut guard) = self.resources.lock() else { + let mut default_res = Res::res_default(); + return f(&mut default_res); }; if let Some(arc_res) = guard .get_mut(&TypeId::of::<Res>()) @@ -81,6 +75,7 @@ where } /// Get an resources by type, returning `Res` if present + #[must_use] pub fn res<Res: 'static + Send + Sync>(&self) -> Option<GlobalResource<Res>> { let guard = self.resources.lock().ok()?; let boxed_any = guard.get(&TypeId::of::<Res>())?; @@ -100,6 +95,7 @@ where } /// Get a resource by type, returning `GlobalResource<Res>` or inserting a default + #[must_use] pub fn res_or_default<Res: 'static + Send + Sync + ResourceMarker>( &self, ) -> GlobalResource<Res> { @@ -144,6 +140,7 @@ impl<ResType: 'static + Send + Sync> AsRef<ResType> for GlobalResource<ResType> /// Resource marker trait, types that implement the Clone and Default traits can be considered as resources pub trait ResourceMarker { + #[must_use] fn res_clone(&self) -> Self; fn res_default() -> Self; fn modify<C>(f: impl FnOnce(&mut Self)) diff --git a/mingling_core/src/asset/node.rs b/mingling_core/src/asset/node.rs index 035d227..4dfdb48 100644 --- a/mingling_core/src/asset/node.rs +++ b/mingling_core/src/asset/node.rs @@ -11,6 +11,7 @@ pub struct Node { impl Node { /// Append a new part to the node path. + #[must_use] pub fn join(self, node: impl Into<String>) -> Node { let mut new_node = self.node; new_node.push(node.into()); diff --git a/mingling_core/src/asset/renderer.rs b/mingling_core/src/asset/renderer.rs index de417a2..1d5a2c1 100644 --- a/mingling_core/src/asset/renderer.rs +++ b/mingling_core/src/asset/renderer.rs @@ -1,6 +1,6 @@ use crate::RenderResult; -/// Takes over a type (Self::Previous) and converts it to a [`RenderResult`](./struct.RenderResult.html) +/// Takes over a type (`Self::Previous`) and converts it to a [`RenderResult`](./struct.RenderResult.html) pub trait Renderer { /// The previous type in the chain type Previous; diff --git a/mingling_core/src/builds/comp.rs b/mingling_core/src/builds/comp.rs index 8b884c8..aa08627 100644 --- a/mingling_core/src/builds/comp.rs +++ b/mingling_core/src/builds/comp.rs @@ -10,7 +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 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 +63,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("../../../").to_path_buf(); + let target_dir = out_dir.join("../../../").clone(); build_comp_script_to(shell_flag, bin_name, &target_dir.to_string_lossy()) } @@ -89,7 +89,7 @@ pub fn build_comp_script_to( tmpl_param!(tmpl, bin_name = bin_name); let target_path = std::path::PathBuf::from(target_dir); std::fs::create_dir_all(&target_path)?; - let output_path = target_path.join(format!("{}_comp{}", bin_name, ext)); + let output_path = target_path.join(format!("{bin_name}_comp{ext}")); std::fs::write(&output_path, tmpl.to_string()) } diff --git a/mingling_core/src/comp.rs b/mingling_core/src/comp.rs index 8d55c5d..4f3890a 100644 --- a/mingling_core/src/comp.rs +++ b/mingling_core/src/comp.rs @@ -43,6 +43,7 @@ pub trait CompletionEntry { /// format appropriate for the target shell. pub struct CompletionHelper; impl CompletionHelper { + #[must_use] pub fn exec_completion<P>(ctx: &ShellContext) -> Suggest where P: ProgramCollect<Enum = P> + Display + PartialEq + 'static + std::fmt::Debug, @@ -114,6 +115,7 @@ impl CompletionHelper { } } + #[allow(clippy::needless_pass_by_value)] pub fn render_suggest<P>(ctx: ShellContext, suggest: Suggest) where P: ProgramCollect<Enum = P> + Display + 'static, @@ -130,15 +132,15 @@ impl CompletionHelper { match ctx.shell_flag { ShellFlag::Zsh | ShellFlag::Powershell => { trace!("using zsh/pwsh format"); - print_suggest_with_description(suggestions) + print_suggest_with_description(suggestions); } ShellFlag::Fish => { trace!("using fish format"); - print_suggest_with_description_fish(suggestions) + print_suggest_with_description_fish(suggestions); } _ => { trace!("using default format"); - print_suggest(suggestions) + print_suggest(suggestions); } } } @@ -162,7 +164,7 @@ where if ctx.word_index < 1 { debug!("word_index < 1, returning file suggestions"); return file_suggest(); - }; + } // Get the current input path let input_end = ctx.word_index.min(ctx.all_words.len()); @@ -178,7 +180,7 @@ where .unwrap_or(&[]) .iter() .filter(|s| !s.is_empty()) - .map(|s| s.as_str()) + .map(std::string::String::as_str) .collect(); debug!( "input_path={:?}, current_word='{}'", diff --git a/mingling_core/src/comp/flags.rs b/mingling_core/src/comp/flags.rs index 452126b..424fe8b 100644 --- a/mingling_core/src/comp/flags.rs +++ b/mingling_core/src/comp/flags.rs @@ -14,7 +14,7 @@ pub enum ShellFlag { Zsh, /// Represents the Fish shell. Fish, - /// Represents PowerShell. + /// Represents `PowerShell`. Powershell, /// A custom or unsupported shell type, identified by the provided string. Other(String), diff --git a/mingling_core/src/comp/shell_ctx.rs b/mingling_core/src/comp/shell_ctx.rs index 3134cd6..35758e9 100644 --- a/mingling_core/src/comp/shell_ctx.rs +++ b/mingling_core/src/comp/shell_ctx.rs @@ -73,8 +73,7 @@ impl TryFrom<Vec<String>> for ShellContext { let shell_flag = arg_map .get("-F") .cloned() - .map(ShellFlag::from) - .unwrap_or(ShellFlag::Other("unknown".to_string())); + .map_or(ShellFlag::Other("unknown".to_string()), ShellFlag::from); let all_words = command_line .split_whitespace() @@ -120,7 +119,7 @@ impl ShellContext { let flag = flag.into(); if self.filling_argument(&flag) { let mut flag_appears = 0; - for w in self.all_words.iter() { + for w in &self.all_words { for f in flag.iter() { if *f == w { flag_appears += 1; @@ -190,6 +189,7 @@ impl ShellContext { /// // } /// } /// ``` + #[must_use] pub fn typing_argument(&self) -> bool { #[cfg(target_os = "windows")] { @@ -207,6 +207,7 @@ impl ShellContext { /// in the command line. It is useful for preventing duplicate flag suggestions /// when the user has already typed certain flags. The method processes both /// regular suggestion sets and file completion suggestions differently. + #[must_use] pub fn strip_typed_argument(&self, suggest: Suggest) -> Suggest { let typed = Self::get_typed_arguments(self); match suggest { @@ -223,11 +224,12 @@ impl ShellContext { /// This method collects all words in the shell context that start with a dash (`-`), /// which typically represent command-line flags or options. It returns a vector /// containing these flag strings, converted to owned `String` values. + #[must_use] pub fn get_typed_arguments(&self) -> HashSet<String> { self.all_words .iter() - .filter(|word| word.starts_with("-")) - .map(|word| word.to_string()) + .filter(|word| word.starts_with('-')) + .cloned() .collect() } } diff --git a/mingling_core/src/comp/suggest.rs b/mingling_core/src/comp/suggest.rs index 6d64341..cd025a4 100644 --- a/mingling_core/src/comp/suggest.rs +++ b/mingling_core/src/comp/suggest.rs @@ -16,17 +16,20 @@ pub enum Suggest { } impl Suggest { - /// Creates a new Suggest variant containing a BTreeSet of suggestions. + /// Creates a new Suggest variant containing a `BTreeSet` of suggestions. + #[must_use] pub fn new() -> Self { Self::Suggest(BTreeSet::new()) } - /// Creates a FileCompletion variant. + /// Creates a `FileCompletion` variant. + #[must_use] pub fn file_comp() -> Self { Self::FileCompletion } /// Filters out already typed flag arguments from suggestion results. + #[must_use] pub fn strip_typed_argument(self, ctx: &ShellContext) -> Self { ctx.strip_typed_argument(self) } @@ -103,40 +106,44 @@ impl Ord for SuggestItem { impl SuggestItem { /// Creates a new simple suggestion without description. + #[must_use] pub fn new(suggest: String) -> Self { Self::Simple(suggest) } /// Creates a new suggestion with a description. + #[must_use] pub fn new_with_desc(suggest: String, description: String) -> Self { Self::WithDescription(suggest, description) } /// Adds a description to this suggestion, replacing any existing description. + #[must_use] pub fn with_desc(self, description: String) -> Self { match self { - Self::Simple(suggest) => Self::WithDescription(suggest, description), - Self::WithDescription(suggest, _) => Self::WithDescription(suggest, description), + Self::Simple(suggest) | Self::WithDescription(suggest, _) => { + Self::WithDescription(suggest, description) + } } } /// Returns the suggestion text. + #[must_use] pub fn suggest(&self) -> &String { match self { - Self::Simple(suggest) => suggest, - Self::WithDescription(suggest, _) => suggest, + Self::Simple(suggest) | Self::WithDescription(suggest, _) => suggest, } } /// Updates the suggestion text. pub fn set_suggest(&mut self, new_suggest: String) { match self { - Self::Simple(suggest) => *suggest = new_suggest, - Self::WithDescription(suggest, _) => *suggest = new_suggest, + Self::Simple(suggest) | Self::WithDescription(suggest, _) => *suggest = new_suggest, } } /// Returns the description if present. + #[must_use] pub fn description(&self) -> Option<&String> { match self { Self::Simple(_) => None, diff --git a/mingling_core/src/program.rs b/mingling_core/src/program.rs index 912975d..2e861e4 100644 --- a/mingling_core/src/program.rs +++ b/mingling_core/src/program.rs @@ -70,6 +70,7 @@ where C: ProgramCollect<Enum = C>, { /// Creates a new Program instance, initializing command-line arguments from the environment. + #[must_use] pub fn new() -> Self { #[cfg(not(windows))] return Self::new_with_args(env::args().collect::<Vec<String>>()); @@ -96,8 +97,8 @@ where #[cfg(not(feature = "dispatch_tree"))] dispatcher: Vec::new(), - stdout_setting: Default::default(), - user_context: Default::default(), + stdout_setting: ProgramStdoutSetting::default(), + user_context: ProgramUserContext::default(), #[cfg(feature = "general_renderer")] general_renderer_name: GeneralRendererSetting::Disable, @@ -109,6 +110,10 @@ where } /// Returns a reference to the current program instance, if set. + /// + /// # Panics + /// + /// Panics if the program has not been initialized yet. pub fn this_program() -> &'static Program<C> where C: 'static, @@ -123,6 +128,7 @@ where } /// Get all registered dispatcher names from the program + #[must_use] pub fn get_nodes( &'static self, ) -> Vec<(String, &'static (dyn Dispatcher<C> + Send + Sync + 'static))> { @@ -130,11 +136,17 @@ where } /// Dynamically dispatch input arguments to registered entry types + /// + /// # Errors + /// + /// Returns `Err(ChainProcessError)` if the dispatch fails, + /// e.g., if no dispatcher is found for the given arguments. pub fn dispatch_args_dynamic( &'static self, args: impl Into<StringVec>, ) -> Result<AnyOutput<C>, ChainProcessError> { - match exec::dispatch_args_dynamic(self, &args.into().into()) { + let sv: Vec<String> = args.into().into(); + match exec::dispatch_args_dynamic(self, &sv) { Ok(ok) => Ok(ok), Err(e) => Err(e.into()), } @@ -229,6 +241,7 @@ macro_rules! __dispatch_program_chains { /// Get all registered dispatcher names from the program #[allow(unused_variables)] +#[must_use] pub fn get_nodes<C: ProgramCollect<Enum = C>>( program: &'static Program<C>, ) -> Vec<(String, &'static (dyn Dispatcher<C> + Send + Sync + 'static))> { diff --git a/mingling_core/src/program/collection.rs b/mingling_core/src/program/collection.rs index ff26411..d3d18d6 100644 --- a/mingling_core/src/program/collection.rs +++ b/mingling_core/src/program/collection.rs @@ -25,23 +25,23 @@ pub trait ProgramCollect { /// Use a prefix tree to quickly match arguments and dispatch to an Entry #[cfg(feature = "dispatch_tree")] fn dispatch_args_trie( - raw: &Vec<String>, + raw: &[String], ) -> Result<AnyOutput<Self::Enum>, crate::error::ProgramInternalExecuteError>; /// Get all registered dispatcher names from the program #[cfg(feature = "dispatch_tree")] fn get_nodes() -> Vec<(String, &'static (dyn Dispatcher<Self::Enum> + Send + Sync))>; - /// Build an [AnyOutput](./struct.AnyOutput.html) to indicate that a renderer was not found + /// Build an [`AnyOutput`](./struct.AnyOutput.html) to indicate that a renderer was not found fn build_renderer_not_found(member_id: Self::Enum) -> AnyOutput<Self::Enum>; - /// Build an [AnyOutput](./struct.AnyOutput.html) to indicate that a dispatcher was not found + /// Build an [`AnyOutput`](./struct.AnyOutput.html) to indicate that a dispatcher was not found fn build_dispatcher_not_found(args: Vec<String>) -> AnyOutput<Self::Enum>; - /// Build an [AnyOutput](./struct.AnyOutput.html) to indicate that the chain returned an empty result + /// Build an [`AnyOutput`](./struct.AnyOutput.html) to indicate that the chain returned an empty result fn build_empty_result() -> AnyOutput<Self::Enum>; - /// Render the input [AnyOutput](./struct.AnyOutput.html) + /// Render the input [`AnyOutput`](./struct.AnyOutput.html) fn render(any: AnyOutput<Self::Enum>, r: &mut RenderResult); /// Render help for Entry @@ -53,7 +53,7 @@ pub trait ProgramCollect { any: AnyOutput<Self::Enum>, ) -> Pin<Box<dyn Future<Output = ChainProcess<Self::Enum>> + Send>>; - /// Find a matching chain to continue execution based on the input [AnyOutput](./struct.AnyOutput.html), returning a new [AnyOutput](./struct.AnyOutput.html) + /// Find a matching chain to continue execution based on the input [`AnyOutput`](./struct.AnyOutput.html), returning a new [`AnyOutput`](./struct.AnyOutput.html) #[cfg(not(feature = "async"))] fn do_chain(any: AnyOutput<Self::Enum>) -> ChainProcess<Self::Enum>; @@ -61,13 +61,18 @@ pub trait ProgramCollect { #[cfg(feature = "comp")] fn do_comp(any: &AnyOutput<Self::Enum>, ctx: &ShellContext) -> Suggest; - /// Whether the program has a renderer that can handle the current [AnyOutput](./struct.AnyOutput.html) + /// Whether the program has a renderer that can handle the current [`AnyOutput`](./struct.AnyOutput.html) fn has_renderer(any: &AnyOutput<Self::Enum>) -> bool; - /// Whether the program has a chain that can handle the current [AnyOutput](./struct.AnyOutput.html) + /// Whether the program has a chain that can handle the current [`AnyOutput`](./struct.AnyOutput.html) fn has_chain(any: &AnyOutput<Self::Enum>) -> bool; /// Perform general rendering and presentation of any type + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization of the + /// output value fails. #[cfg(feature = "general_renderer")] fn general_render( any: AnyOutput<Self::Enum>, diff --git a/mingling_core/src/program/config.rs b/mingling_core/src/program/config.rs index b5b46a0..5c104ab 100644 --- a/mingling_core/src/program/config.rs +++ b/mingling_core/src/program/config.rs @@ -109,7 +109,7 @@ impl std::str::FromStr for GeneralRendererSetting { "ron" => Ok(GeneralRendererSetting::Ron), #[cfg(feature = "ron_serde_fmt")] "ron-pretty" => Ok(GeneralRendererSetting::RonPretty), - _ => Err(format!("Invalid renderer: '{}'", s)), + _ => Err(format!("Invalid renderer: '{s}'")), } } } diff --git a/mingling_core/src/program/error.rs b/mingling_core/src/program/error.rs index 03e9af6..822e429 100644 --- a/mingling_core/src/program/error.rs +++ b/mingling_core/src/program/error.rs @@ -9,9 +9,9 @@ pub struct ProgramPanic { impl fmt::Display for ProgramPanic { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(s) = self.payload.downcast_ref::<&str>() { - write!(f, "{}", s) + write!(f, "{s}") } else if let Some(s) = self.payload.downcast_ref::<String>() { - write!(f, "{}", s) + write!(f, "{s}") } else { write!(f, "") } @@ -19,6 +19,7 @@ impl fmt::Display for ProgramPanic { } impl ProgramPanic { + #[must_use] pub fn new(payload: Box<dyn Any + Send>) -> Self { ProgramPanic { payload } } diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs index 72a20b9..0cadc6a 100644 --- a/mingling_core/src/program/exec.rs +++ b/mingling_core/src/program/exec.rs @@ -15,8 +15,7 @@ pub async fn exec<C>( where C: ProgramCollect<Enum = C>, { - let args = program.args.clone(); - exec_with_args(program, args).await + exec_with_args(program, &program.args).await } #[cfg(not(feature = "async"))] @@ -24,26 +23,25 @@ pub fn exec<C>(program: &'static Program<C>) -> Result<RenderResult, ProgramInte where C: ProgramCollect<Enum = C>, { - let args = program.args.clone(); - exec_with_args(program, args) + exec_with_args(program, &program.args) } #[cfg(feature = "async")] pub async fn exec_with_args<C>( program: &'static Program<C>, - args: Vec<String>, + args: &[String], ) -> Result<RenderResult, ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, { // Run hooks - program.run_hook_pre_dispatch(&args); + program.run_hook_pre_dispatch(args); #[cfg(not(feature = "dispatch_tree"))] - let mut current = dispatch_args_dynamic(program, &args)?; + let mut current = dispatch_args_dynamic(program, args)?; #[cfg(feature = "dispatch_tree")] - let mut current = C::dispatch_args_trie(&args)?; + let mut current = C::dispatch_args_trie(args)?; // Run hook program.run_hook_post_dispatch(¤t.member_id); @@ -125,19 +123,19 @@ where #[cfg(not(feature = "async"))] pub fn exec_with_args<C>( program: &'static Program<C>, - args: Vec<String>, + args: &[String], ) -> Result<RenderResult, ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, { // Run hooks - program.run_hook_pre_dispatch(&args); + program.run_hook_pre_dispatch(args); #[cfg(not(feature = "dispatch_tree"))] - let mut current = dispatch_args_dynamic(program, &args)?; + let mut current = dispatch_args_dynamic(program, args)?; #[cfg(feature = "dispatch_tree")] - let mut current = C::dispatch_args_trie(&args)?; + let mut current = C::dispatch_args_trie(args)?; // Run hook program.run_hook_post_dispatch(¤t.member_id); @@ -221,7 +219,7 @@ where /// Dynamically dispatch input arguments to registered entry types pub(crate) fn dispatch_args_dynamic<C>( program: &'static Program<C>, - args: &Vec<String>, + args: &[String], ) -> Result<AnyOutput<C>, ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, @@ -236,7 +234,7 @@ where } Err(ProgramInternalExecuteError::DispatcherNotFound) => { // No matching Dispatcher is found - C::build_dispatcher_not_found(args.clone()) + C::build_dispatcher_not_found(args.to_vec()) } Err(e) => return Err(e), }; @@ -245,10 +243,9 @@ where /// Match user input against registered dispatchers and return the matched dispatcher and remaining arguments. #[allow(clippy::type_complexity)] -#[allow(clippy::ptr_arg)] pub(crate) fn match_user_input<C>( program: &'static Program<C>, - args: &Vec<String>, + args: &[String], ) -> Result<(&'static (dyn Dispatcher<C> + Send + Sync), Vec<String>), ProgramInternalExecuteError> where C: ProgramCollect<Enum = C>, @@ -260,7 +257,7 @@ where let matching_nodes: Vec<&(String, &(dyn Dispatcher<C> + Send + Sync))> = nodes .iter() // Also add a space to the node string to ensure consistent matching logic - .filter(|(node_str, _)| command.starts_with(&format!("{} ", node_str))) + .filter(|(node_str, _)| command.starts_with(&format!("{node_str} "))) .collect(); match matching_nodes.len() { @@ -289,7 +286,7 @@ where } } -#[inline(always)] +#[inline] #[allow(unused_variables)] fn render<C: ProgramCollect<Enum = C>>(program: &Program<C>, any: AnyOutput<C>) -> RenderResult { #[cfg(not(feature = "general_renderer"))] @@ -312,7 +309,7 @@ fn render<C: ProgramCollect<Enum = C>>(program: &Program<C>, any: AnyOutput<C>) } } -#[inline(always)] +#[inline] #[allow(unused_variables)] fn render_help<C: ProgramCollect<Enum = C>>( program: &Program<C>, diff --git a/mingling_core/src/program/exec/error.rs b/mingling_core/src/program/exec/error.rs index 0f2d875..944e89a 100644 --- a/mingling_core/src/program/exec/error.rs +++ b/mingling_core/src/program/exec/error.rs @@ -26,10 +26,10 @@ impl fmt::Display for ProgramExecuteError { match self { ProgramExecuteError::DispatcherNotFound => write!(f, "No Dispatcher Found"), ProgramExecuteError::RendererNotFound(s) => { - write!(f, "No Renderer (`{}`) Found", s) + write!(f, "No Renderer (`{s}`) Found") } - ProgramExecuteError::Panic(p) => write!(f, "Panic: {:?}", p), - ProgramExecuteError::Other(s) => write!(f, "Other error: {}", s), + ProgramExecuteError::Panic(p) => write!(f, "Panic: {p:?}"), + ProgramExecuteError::Other(s) => write!(f, "Other error: {s}"), } } } @@ -74,12 +74,12 @@ impl fmt::Display for ProgramInternalExecuteError { write!(f, "No Dispatcher Found") } ProgramInternalExecuteError::RendererNotFound(s) => { - write!(f, "No Renderer (`{}`) Found", s) + write!(f, "No Renderer (`{s}`) Found") } - ProgramInternalExecuteError::Other(s) => write!(f, "Other error: {}", s), - ProgramInternalExecuteError::IO(e) => write!(f, "IO error: {}", e), + ProgramInternalExecuteError::Other(s) => write!(f, "Other error: {s}"), + ProgramInternalExecuteError::IO(e) => write!(f, "IO error: {e}"), ProgramInternalExecuteError::REPLPanic(panic) => { - write!(f, "A single REPL execution failed: {}", panic) + write!(f, "A single REPL execution failed: {panic}") } } } @@ -110,11 +110,10 @@ impl From<ProgramInternalExecuteError> for ProgramExecuteError { ProgramExecuteError::RendererNotFound(s) } ProgramInternalExecuteError::Other(s) => ProgramExecuteError::Other(s), - ProgramInternalExecuteError::IO(e) => ProgramExecuteError::Other(format!("{}", e)), - ProgramInternalExecuteError::REPLPanic(p) => ProgramExecuteError::Other(format!( - "A single REPL execution failed: {}", - p - )), + ProgramInternalExecuteError::IO(e) => ProgramExecuteError::Other(format!("{e}")), + ProgramInternalExecuteError::REPLPanic(p) => { + ProgramExecuteError::Other(format!("A single REPL execution failed: {p}")) + } } } } diff --git a/mingling_core/src/program/flag.rs b/mingling_core/src/program/flag.rs index 210f2d6..13f6ea9 100644 --- a/mingling_core/src/program/flag.rs +++ b/mingling_core/src/program/flag.rs @@ -51,7 +51,7 @@ impl From<&Flag> for Flag { } impl From<()> for Flag { - fn from(_: ()) -> Self { + fn from((): ()) -> Self { Flag { vec: vec![] } } } diff --git a/mingling_core/src/program/hook.rs b/mingling_core/src/program/hook.rs index 3520084..929eac2 100644 --- a/mingling_core/src/program/hook.rs +++ b/mingling_core/src/program/hook.rs @@ -16,7 +16,7 @@ where pub begin: Option<fn()>, /// Executes before the program dispatches - pub pre_dispatch: Option<fn(args: &Vec<String>)>, + pub pre_dispatch: Option<fn(args: &[String])>, /// Executes after the program dispatches pub post_dispatch: Option<fn(entry: &C)>, @@ -98,19 +98,19 @@ where for hook in &self.hooks { if let Some(begin) = hook.begin { - begin() + begin(); } } } - pub(crate) fn run_hook_pre_dispatch(&self, args: &Vec<String>) { + pub(crate) fn run_hook_pre_dispatch(&self, args: &[String]) { if !self.user_context.run_hook { return; } for hook in &self.hooks { if let Some(pre_dispatch) = hook.pre_dispatch { - pre_dispatch(args) + pre_dispatch(args); } } } @@ -122,7 +122,7 @@ where for hook in &self.hooks { if let Some(post_dispatch) = hook.post_dispatch { - post_dispatch(entry) + post_dispatch(entry); } } } @@ -134,7 +134,7 @@ where for hook in &self.hooks { if let Some(pre_chain) = hook.pre_chain { - pre_chain(input, raw) + pre_chain(input, raw); } } } @@ -146,7 +146,7 @@ where for hook in &self.hooks { if let Some(post_chain) = hook.post_chain { - post_chain(output) + post_chain(output); } } } @@ -158,7 +158,7 @@ where for hook in &self.hooks { if let Some(pre_render) = hook.pre_render { - pre_render(input, raw) + pre_render(input, raw); } } } @@ -170,7 +170,7 @@ where for hook in &self.hooks { if let Some(post_render) = hook.post_render { - post_render(result) + post_render(result); } } } @@ -184,7 +184,7 @@ where for hook in &self.hooks { if let Some(exec_panic) = hook.exec_panic { - exec_panic(panic_info) + exec_panic(panic_info); } } } @@ -354,6 +354,7 @@ where C: ProgramCollect<Enum = C>, { /// Creates a new empty hook set with no handlers. + #[must_use] pub fn empty() -> Self { Self { begin: None, @@ -390,48 +391,56 @@ where } /// Sets the handler for the `begin` event. + #[must_use] pub fn on_begin(mut self, handler: fn()) -> Self { let _ = self.begin.insert(handler); self } /// Sets the handler for the `pre_dispatch` event. - pub fn on_pre_dispatch(mut self, handler: fn(args: &Vec<String>)) -> Self { + #[must_use] + pub fn on_pre_dispatch(mut self, handler: fn(args: &[String])) -> Self { let _ = self.pre_dispatch.insert(handler); self } /// Sets the handler for the `post_dispatch` event. + #[must_use] pub fn on_post_dispatch(mut self, handler: fn(entry: &C)) -> Self { let _ = self.post_dispatch.insert(handler); self } /// Sets the handler for the `pre_chain` event. + #[must_use] pub fn on_pre_chain(mut self, handler: fn(input: &C, raw: &dyn Any)) -> Self { let _ = self.pre_chain.insert(handler); self } /// Sets the handler for the `post_chain` event. + #[must_use] pub fn on_post_chain(mut self, handler: fn(output: &AnyOutput<C>)) -> Self { let _ = self.post_chain.insert(handler); self } /// Sets the handler for the `pre_render` event. + #[must_use] pub fn on_pre_render(mut self, handler: fn(input: &C, raw: &dyn Any)) -> Self { let _ = self.pre_render.insert(handler); self } /// Sets the handler for the `post_render` event. + #[must_use] pub fn on_post_render(mut self, handler: fn(result: &RenderResult)) -> Self { let _ = self.post_render.insert(handler); self } /// Sets the handler for the `finish` event. + #[must_use] pub fn on_finish(mut self, handler: fn() -> i32) -> Self { let _ = self.finish.insert(handler); self @@ -439,6 +448,7 @@ where /// Sets the handler for the `exec_panic` event. #[cfg(not(feature = "async"))] + #[must_use] pub fn on_exec_panic(mut self, handler: fn(&ProgramPanic)) -> Self { let _ = self.exec_panic.insert(handler); self @@ -446,6 +456,7 @@ where /// Sets the handler for the REPL begin event (only available with `repl` feature). #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_begin(mut self, handler: fn()) -> Self { let _ = self.repl_on_begin.insert(handler); self @@ -454,6 +465,7 @@ where /// Sets the handler for the REPL pre-readline event (only available with `repl` feature). /// This hook runs after `on_repl_begin` but before reading the next input line. #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_pre_readline(mut self, handler: fn()) -> Self { let _ = self.repl_pre_readline.insert(handler); self @@ -463,6 +475,7 @@ where /// If set, this function will be called to read a line instead of the default mechanism. /// Returning `None` signals that there is no input (e.g., EOF). #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_readline(mut self, handler: fn() -> Option<String>) -> Self { let _ = self.repl_readline.insert(handler); self @@ -471,6 +484,7 @@ where /// Sets the handler for the REPL post-readline event (only available with `repl` feature). /// This hook runs after reading a line of input and receives a mutable reference to the line. #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_post_readline(mut self, handler: fn(line: &mut String)) -> Self { let _ = self.repl_post_readline.insert(handler); self @@ -479,6 +493,7 @@ where /// Sets the handler for the REPL pre-exec event (only available with `repl` feature). /// This hook runs before executing a REPL command, receiving the parsed arguments. #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_pre_exec(mut self, handler: fn(args: &[String])) -> Self { let _ = self.repl_pre_exec.insert(handler); self @@ -487,6 +502,7 @@ where /// Sets the handler for the REPL post-exec event (only available with `repl` feature). /// This hook runs after executing a REPL command. #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_post_exec(mut self, handler: fn()) -> Self { let _ = self.repl_post_exec.insert(handler); self @@ -495,6 +511,7 @@ where /// Sets the handler for the REPL receive result event (only available with `repl` feature). /// This hook runs after a command is executed, receiving the render result on success. #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_receive_result(mut self, handler: fn(result: &RenderResult)) -> Self { let _ = self.repl_on_receive_result.insert(handler); self @@ -502,6 +519,7 @@ where /// Sets the handler for the REPL panic event (only available with `repl` feature). #[cfg(all(feature = "repl", not(feature = "async")))] + #[must_use] pub fn on_repl_panic(mut self, handler: fn(panic: &ProgramPanic)) -> Self { let _ = self.repl_on_panic.insert(handler); self @@ -510,6 +528,7 @@ where /// Sets the handler for the REPL exit event (only available with `repl` feature). /// This hook runs when the REPL is about to exit. #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_exit(mut self, handler: fn()) -> Self { let _ = self.repl_exit.insert(handler); self @@ -518,6 +537,7 @@ where /// Sets the handler for the REPL loop_once event (only available with `repl` feature). /// This hook runs after each REPL loop iteration. #[cfg(feature = "repl")] + #[must_use] pub fn on_repl_loop_once(mut self, handler: fn()) -> Self { let _ = self.repl_loop_once.insert(handler); self diff --git a/mingling_core/src/program/once_exec.rs b/mingling_core/src/program/once_exec.rs index e1c0956..f757893 100644 --- a/mingling_core/src/program/once_exec.rs +++ b/mingling_core/src/program/once_exec.rs @@ -29,6 +29,15 @@ where } /// Run the command line program + /// + /// # Errors + /// + /// Returns `Err(ProgramExecuteError)` if execution fails, + /// e.g., if no dispatcher is found or a chain error occurs. + /// + /// # Panics + /// + /// Panics if the program encounters a non-recoverable internal error. pub async fn exec_without_render(mut self) -> Result<RenderResult, ProgramExecuteError> where C: 'static + Send + Sync, @@ -127,6 +136,15 @@ where } /// Run the command line program + /// + /// # Errors + /// + /// Returns `Err(ProgramExecuteError)` if execution fails, + /// e.g., if no dispatcher is found or a chain error occurs. + /// + /// # Panics + /// + /// Panics if the program encounters a non-recoverable internal error. pub fn exec_without_render(mut self) -> Result<RenderResult, ProgramExecuteError> where C: 'static + Send + Sync, @@ -141,7 +159,7 @@ where #[cfg(not(panic = "abort"))] match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - self.exec_wrapper(|p| crate::exec::exec(p).map_err(|e| e.into())) + self.exec_wrapper(|p| crate::exec::exec(p).map_err(std::convert::Into::into)) })) { Ok(result) => result, Err(panic_info) => { @@ -164,6 +182,7 @@ where } /// Run the command line program + #[must_use] pub fn exec(self) -> i32 where C: 'static + Send + Sync, @@ -179,15 +198,15 @@ where return 1; } ProgramExecuteError::RendererNotFound(renderer_name) => { - eprintln!("Renderer `{}` not found", renderer_name); + eprintln!("Renderer `{renderer_name}` not found"); return 1; } ProgramExecuteError::Other(e) => { - eprintln!("{}", e); + eprintln!("{e}"); return 1; } ProgramExecuteError::Panic(unwinded_error) => { - eprintln!("{}", unwinded_error); + eprintln!("{unwinded_error}"); return 1; } }, @@ -196,12 +215,12 @@ where // Render result if stdout_setting.render_output && !result.is_empty() { let exit_code = result.exit_code; - print!("{}", result); + print!("{result}"); if let Err(e) = std::io::Write::flush(&mut std::io::stdout()) && stdout_setting.error_output { - eprintln!("{}", e); + eprintln!("{e}"); 1 } else { exit_code diff --git a/mingling_core/src/program/repl_exec.rs b/mingling_core/src/program/repl_exec.rs index 3d82b74..d7ee8e8 100644 --- a/mingling_core/src/program/repl_exec.rs +++ b/mingling_core/src/program/repl_exec.rs @@ -115,12 +115,12 @@ where C: ProgramCollect<Enum = C> + Send + Sync + 'static, { #[cfg(panic = "abort")] - let exec_result = super::exec::exec_with_args(p, args); + let exec_result = super::exec::exec_with_args(p, &args); #[cfg(not(panic = "abort"))] let exec_result = { let exec_unwind_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - super::exec::exec_with_args(p, args) + super::exec::exec_with_args(p, &args) })); match exec_unwind_result { @@ -153,5 +153,5 @@ async fn exec_once<C>( where C: ProgramCollect<Enum = C> + Send + Sync + 'static, { - super::exec::exec_with_args(p, args).await + super::exec::exec_with_args(p, &args).await } diff --git a/mingling_core/src/program/single_instance.rs b/mingling_core/src/program/single_instance.rs index 45d4d33..70771d5 100644 --- a/mingling_core/src/program/single_instance.rs +++ b/mingling_core/src/program/single_instance.rs @@ -7,6 +7,11 @@ pub(crate) static THIS_PROGRAM: OnceLock<Option<Box<dyn std::any::Any + Send + S OnceLock::new(); /// Returns a reference to the current program instance, panics if not set. +/// +/// # Panics +/// +/// Panics if the program has not been initialized yet. +#[must_use] pub fn this<C>() -> &'static Program<C> where C: ProgramCollect<Enum = C> + 'static, diff --git a/mingling_core/src/renderer/general.rs b/mingling_core/src/renderer/general.rs index 7d07bac..0ea82c1 100644 --- a/mingling_core/src/renderer/general.rs +++ b/mingling_core/src/renderer/general.rs @@ -14,7 +14,11 @@ pub mod error; pub struct GeneralRenderer; impl GeneralRenderer { - // Renders data in the specified format to the given RenderResult. + /// Renders data in the specified format to the given `RenderResult`. + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. #[allow(unused_variables)] pub fn render<T: Serialize + Send>( data: &T, @@ -39,6 +43,10 @@ impl GeneralRenderer { } /// Serializes data to JSON format and writes it to the render result. + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. #[cfg(feature = "json_serde_fmt")] pub fn render_to_json<T: Serialize + Send>( data: &T, @@ -46,11 +54,15 @@ impl GeneralRenderer { ) -> Result<(), GeneralRendererSerializeError> { let json_string = serde_json::to_string(data) .map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; - r.print(json_string.to_string().as_str()); + r.print(json_string.clone().as_str()); Ok(()) } /// Serializes data to pretty-printed JSON format and writes it to the render result. + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. #[cfg(feature = "json_serde_fmt")] pub fn render_to_json_pretty<T: Serialize + Send>( data: &T, @@ -58,11 +70,15 @@ impl GeneralRenderer { ) -> Result<(), GeneralRendererSerializeError> { let json_string = serde_json::to_string_pretty(data) .map_err(|e| GeneralRendererSerializeError::new(e.to_string()))?; - r.print(json_string.to_string().as_str()); + r.print(json_string.clone().as_str()); Ok(()) } /// Serializes data to RON format and writes it to the render result. + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. #[cfg(feature = "ron_serde_fmt")] pub fn render_to_ron<T: Serialize + Send>( data: &T, @@ -75,6 +91,10 @@ impl GeneralRenderer { } /// Serializes data to pretty-printed RON format and writes it to the render result. + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. #[cfg(feature = "ron_serde_fmt")] pub fn render_to_ron_pretty<T: Serialize + Send>( data: &T, @@ -91,6 +111,10 @@ impl GeneralRenderer { } /// Serializes data to TOML format and writes it to the render result. + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. #[cfg(feature = "toml_serde_fmt")] pub fn render_to_toml<T: Serialize + Send>( data: &T, @@ -103,6 +127,10 @@ impl GeneralRenderer { } /// Serializes data to YAML format and writes it to the render result. + /// + /// # Errors + /// + /// Returns `Err(GeneralRendererSerializeError)` if serialization fails. #[cfg(feature = "yaml_serde_fmt")] pub fn render_to_yaml<T: Serialize + Send>( data: &T, diff --git a/mingling_core/src/renderer/general/error.rs b/mingling_core/src/renderer/general/error.rs index a61b19d..eb76a8b 100644 --- a/mingling_core/src/renderer/general/error.rs +++ b/mingling_core/src/renderer/general/error.rs @@ -9,6 +9,7 @@ pub struct GeneralRendererSerializeError { } impl GeneralRendererSerializeError { + #[must_use] pub fn new(error: String) -> Self { Self { error } } diff --git a/mingling_core/src/tester/chain_process_tester.rs b/mingling_core/src/tester/chain_process_tester.rs index 8189c28..ca809e4 100644 --- a/mingling_core/src/tester/chain_process_tester.rs +++ b/mingling_core/src/tester/chain_process_tester.rs @@ -47,7 +47,7 @@ where } } ChainProcess::Err(chain_process_error) => { - panic!("Chain process error: {}", chain_process_error); + panic!("Chain process error: {chain_process_error}"); } } } @@ -87,7 +87,7 @@ where ChainProcess::Ok((any, _next)) => any .downcast_ref::<Type>() .expect("Type mismatch: expected type does not match actual output type"), - ChainProcess::Err(chain_process_error) => panic!("{:?}", chain_process_error), + ChainProcess::Err(chain_process_error) => panic!("{chain_process_error:?}"), } } @@ -187,7 +187,7 @@ macro_rules! assert_render_result { }; } -/// Asserts that the result's output type matches the expected member_id. +/// Asserts that the result's output type matches the expected `member_id`. /// /// This macro checks that the `ChainProcess` result is `Ok` and that its output type identifier /// matches the expected type. It is a convenience wrapper around `assert_next_eq` with the `next` |
