aboutsummaryrefslogtreecommitdiff
path: root/examples
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 /examples
parentdd28430b67dcfda6dd2e91750a4c1a62c085150a (diff)
Add `pack_err!` macro for error structs with automatic name field
Diffstat (limited to 'examples')
-rw-r--r--examples/example-pack-err/Cargo.lock141
-rw-r--r--examples/example-pack-err/Cargo.toml16
-rw-r--r--examples/example-pack-err/page.toml10
-rw-r--r--examples/example-pack-err/src/main.rs101
-rw-r--r--examples/test-examples.toml20
5 files changed, 288 insertions, 0 deletions
diff --git a/examples/example-pack-err/Cargo.lock b/examples/example-pack-err/Cargo.lock
new file mode 100644
index 0000000..36d4b6f
--- /dev/null
+++ b/examples/example-pack-err/Cargo.lock
@@ -0,0 +1,141 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "example-pack-err"
+version = "0.1.0"
+dependencies = [
+ "mingling",
+ "serde",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+
+[[package]]
+name = "just_fmt"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
+
+[[package]]
+name = "memchr"
+version = "2.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
+
+[[package]]
+name = "mingling"
+version = "0.2.0"
+dependencies = [
+ "mingling_core",
+ "mingling_macros",
+ "serde",
+]
+
+[[package]]
+name = "mingling_core"
+version = "0.2.0"
+dependencies = [
+ "just_fmt",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "mingling_macros"
+version = "0.2.0"
+dependencies = [
+ "just_fmt",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.150"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+dependencies = [
+ "itoa",
+ "memchr",
+ "serde",
+ "serde_core",
+ "zmij",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+
+[[package]]
+name = "zmij"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/examples/example-pack-err/Cargo.toml b/examples/example-pack-err/Cargo.toml
new file mode 100644
index 0000000..883fc89
--- /dev/null
+++ b/examples/example-pack-err/Cargo.toml
@@ -0,0 +1,16 @@
+[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]
diff --git a/examples/example-pack-err/page.toml b/examples/example-pack-err/page.toml
new file mode 100644
index 0000000..5534236
--- /dev/null
+++ b/examples/example-pack-err/page.toml
@@ -0,0 +1,10 @@
+[example]
+id = "example-pack-err"
+name = "pack_err!"
+icon = "🛑"
+category = "macros"
+desc = """
+Demonstrates how to use the `pack_err!` macro to define error types with automatic `name` field (snake_case at compile time) and optional `info` field. Also shows `--json` serialization when `general_renderer` is enabled.
+"""
+tags = ["pack_err!", "extra_macros", "general_renderer", "--json"]
+files = ["src/main.rs", "Cargo.toml"]
diff --git a/examples/example-pack-err/src/main.rs b/examples/example-pack-err/src/main.rs
new file mode 100644
index 0000000..72fecd6
--- /dev/null
+++ b/examples/example-pack-err/src/main.rs
@@ -0,0 +1,101 @@
+//! 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"}
+//! ```
+
+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();
+}
diff --git a/examples/test-examples.toml b/examples/test-examples.toml
index 8d2cf0d..4a50ab1 100644
--- a/examples/test-examples.toml
+++ b/examples/test-examples.toml
@@ -207,3 +207,23 @@ expect.result = "Hello, Alice!"
command = "greet Alice -r 5"
expect.exit-code = 0
expect.result = "Hello, Alice, Alice, Alice, Alice, Alice!"
+
+[[test.example-pack-err]]
+command = "find"
+expect.exit-code = 0
+expect.result = "Search path not provided"
+
+[[test.example-pack-err]]
+command = "find --json"
+expect.exit-code = 0
+expect.result = '{"name":"error_not_found"}'
+
+[[test.example-pack-err]]
+command = "find Cargo.toml"
+expect.exit-code = 0
+expect.result = "Not a directory: Cargo.toml"
+
+[[test.example-pack-err]]
+command = "find Cargo.toml --json"
+expect.exit-code = 0
+expect.result = '{"name":"error_not_dir","info":"Cargo.toml"}'