aboutsummaryrefslogtreecommitdiff
path: root/mingling_core
diff options
context:
space:
mode:
authorWeicao-CatilGrass <1992414357@qq.com>2026-05-31 02:42:52 +0800
committer魏曹先生 <1992414357@qq.com>2026-05-31 17:19:20 +0800
commit2aa7bda3cb21ce6c052b82e08bcab79a625d04f2 (patch)
treef10b89007fc67ca1a948f34abe6869b49296b932 /mingling_core
parent3aa409a55e4f2f0ab41b0949cc06eb13c2da4a43 (diff)
Enhance code quality across the entire codebase
Diffstat (limited to 'mingling_core')
-rw-r--r--mingling_core/Cargo.toml4
-rw-r--r--mingling_core/src/any.rs18
-rw-r--r--mingling_core/src/asset/chain.rs2
-rw-r--r--mingling_core/src/asset/chain/error.rs10
-rw-r--r--mingling_core/src/asset/dispatcher.rs4
-rw-r--r--mingling_core/src/asset/enum_tag.rs2
-rw-r--r--mingling_core/src/asset/global_resource.rs19
-rw-r--r--mingling_core/src/asset/node.rs1
-rw-r--r--mingling_core/src/asset/renderer.rs2
-rw-r--r--mingling_core/src/builds/comp.rs6
-rw-r--r--mingling_core/src/comp.rs12
-rw-r--r--mingling_core/src/comp/flags.rs2
-rw-r--r--mingling_core/src/comp/shell_ctx.rs12
-rw-r--r--mingling_core/src/comp/suggest.rs23
-rw-r--r--mingling_core/src/program.rs19
-rw-r--r--mingling_core/src/program/collection.rs21
-rw-r--r--mingling_core/src/program/config.rs2
-rw-r--r--mingling_core/src/program/error.rs5
-rw-r--r--mingling_core/src/program/exec.rs35
-rw-r--r--mingling_core/src/program/exec/error.rs23
-rw-r--r--mingling_core/src/program/flag.rs2
-rw-r--r--mingling_core/src/program/hook.rs42
-rw-r--r--mingling_core/src/program/once_exec.rs31
-rw-r--r--mingling_core/src/program/repl_exec.rs6
-rw-r--r--mingling_core/src/program/single_instance.rs5
-rw-r--r--mingling_core/src/renderer/general.rs34
-rw-r--r--mingling_core/src/renderer/general/error.rs1
-rw-r--r--mingling_core/src/tester/chain_process_tester.rs6
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(&current.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(&current.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`