aboutsummaryrefslogtreecommitdiff
path: root/mingling
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-18 22:48:16 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-18 22:48:16 +0800
commit0f7b2a50b05f38d886234ff6b031766c7af1dabb (patch)
tree9c9b5d4aa11c91c117b08e829ec33361c4aa6275 /mingling
parentdd28430b67dcfda6dd2e91750a4c1a62c085150a (diff)
Add `pack_err!` macro for error structs with automatic name field
Diffstat (limited to 'mingling')
-rw-r--r--mingling/src/example_docs.rs125
-rw-r--r--mingling/src/lib.rs6
2 files changed, 131 insertions, 0 deletions
diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs
index f4a27bd..b1d693b 100644
--- a/mingling/src/example_docs.rs
+++ b/mingling/src/example_docs.rs
@@ -1550,6 +1550,131 @@ pub mod example_implicit_dispatcher {}
/// gen_program!();
/// ```
pub mod example_lazy_resources {}
+/// Example `pack_err!`
+///
+/// > This example demonstrates how to use the `pack_err!` macro to define error types
+/// > with automatic `name` field (set to snake_case at compile time) and optional `info` field.
+/// > Also demonstrates `--json` serialization when `general_renderer` is enabled.
+///
+/// Run:
+/// ```bash
+/// cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find
+/// cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find --json
+/// cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find Cargo.toml
+/// cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find Cargo.toml --json
+/// cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find src
+/// cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find src --json
+/// ```
+///
+/// Output:
+/// ```plaintext
+/// Search path not provided
+/// {"name":"error_not_found"}
+/// Not a directory: Cargo.toml
+/// {"name":"error_not_dir","info":"Cargo.toml"}
+/// Found directory: src
+/// {"inner":"src"}
+/// ```
+///
+/// Source code (./Cargo.toml)
+/// ```toml
+/// [package]
+/// name = "example-pack-err"
+/// version = "0.1.0"
+/// edition = "2024"
+///
+/// [dependencies]
+/// serde = { version = "1.0.228", features = ["derive"] }
+///
+/// [dependencies.mingling]
+/// path = "../../mingling"
+/// features = [
+/// "general_renderer",
+/// "extra_macros",
+/// ]
+///
+/// [workspace]
+/// ```
+///
+/// Source code (./src/main.rs)
+/// ```ignore
+/// use mingling::prelude::*;
+/// use mingling::setup::GeneralRendererSetup;
+/// use std::path::PathBuf;
+///
+/// dispatcher!("find", CMDFind => EntryFind);
+///
+/// // --------- IMPORTANT ---------
+/// // `pack_err!` is a convenient macro for defining error types.
+/// //
+/// // Simple form: pack_err!(ErrorNotFound);
+/// // Typed form: pack_err!(ErrorNotDir = PathBuf);
+/// //
+/// // The simple form generates a struct with `name: String` and `impl Default`.
+/// // name = "error_not_found" (automatically snake_cased at compile time)
+/// //
+/// // The typed form additionally generates `pub fn new(info)`.
+/// // name = "error_not_dir"
+/// //
+/// // When `general_renderer` is enabled, the struct also gets
+/// // `#[derive(serde::Serialize)]` for --json / --yaml output.
+/// // --------- IMPORTANT ---------
+///
+/// // Simple form — name = "error_not_found"
+/// pack_err!(ErrorNotFound);
+///
+/// // Typed form — name = "error_not_dir"
+/// pack_err!(ErrorNotDir = PathBuf);
+///
+/// // Success type using traditional pack!
+/// pack!(ResultPath = PathBuf);
+///
+/// #[chain]
+/// fn handle_find(args: EntryFind) -> Next {
+/// let Some(path_str) = args.inner.first().cloned() else {
+/// // No path provided → use the simple error form (Default)
+/// return ErrorNotFound::default().to_render();
+/// };
+///
+/// let path = PathBuf::from(&path_str);
+/// if path.is_dir() {
+/// // Is a directory → success
+/// ResultPath::new(path).to_render()
+/// } else {
+/// // Not a directory (or doesn't exist) → use the typed error form
+/// ErrorNotDir::new(path).to_render()
+/// }
+/// }
+///
+/// /// Renders the successful result with the found directory path.
+/// #[renderer]
+/// fn render_result_path(path: ResultPath) {
+/// r_println!("Found directory: {}", path.display());
+/// }
+///
+/// /// Renders the error when no search path is provided.
+/// #[renderer]
+/// fn render_error_not_found(_: ErrorNotFound) {
+/// r_println!("Search path not provided");
+/// }
+///
+/// /// Renders the error when the given path is not a directory.
+/// #[renderer]
+/// fn render_error_not_dir(err: ErrorNotDir) {
+/// r_println!("Not a directory: {}", err.info.display());
+/// }
+///
+/// gen_program!();
+///
+/// fn main() {
+/// let mut program = ThisProgram::new();
+/// // Add GeneralRendererSetup to support --json / --yaml flags
+/// program.with_setup(GeneralRendererSetup);
+/// program.with_dispatcher(CMDFind);
+/// let _ = program.exec();
+/// }
+/// ```
+pub mod example_pack_err {}
/// Example Panic Unwind
///
/// > This example introduces how to catch Panic in the Mingling program loop
diff --git a/mingling/src/lib.rs b/mingling/src/lib.rs
index 7b96d34..f1232d3 100644
--- a/mingling/src/lib.rs
+++ b/mingling/src/lib.rs
@@ -99,6 +99,9 @@ pub mod macros {
pub use mingling_macros::node;
/// Used to create a wrapper type for use with `Chain` and `Renderer`
pub use mingling_macros::pack;
+ /// Used to create an error struct with automatic `name` field
+ #[cfg(feature = "extra_macros")]
+ pub use mingling_macros::pack_err;
#[cfg(feature = "comp")]
/// Internal macro for '`gen_program`' used to finally generate the completion structure
pub use mingling_macros::program_comp_gen;
@@ -192,6 +195,9 @@ pub mod prelude {
pub use crate::macros::gen_program;
/// Re-export of the `pack` macro for creating wrapper types.
pub use crate::macros::pack;
+ /// Re-export of the `pack_err` macro for creating error types.
+ #[cfg(feature = "extra_macros")]
+ pub use crate::macros::pack_err;
/// Re-export of the `r_print` macro for printing within a renderer context.
pub use crate::macros::r_print;
/// Re-export of the `r_println` macro for printing with a newline within a renderer