diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-06-26 06:08:12 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-06-26 06:08:12 +0800 |
| commit | e735671acb3a81e1b7e334e56b9ef3963ba0c2fc (patch) | |
| tree | 46562d6630bb1582b41b6741a7a4f482febf84da /examples | |
| parent | 473cd8e575d03d8bd5439e81cb6835f56a1e964f (diff) | |
feat(core): decouple structured output from Groupped trait
Introduce `StructuralData` sealed trait and `pack_structural!` /
`group_structural!` / `derive(StructuralData)` macros to control
structured rendering separately from grouping. `Groupped` no longer
requires `Serialize`.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/example-general-renderer/src/main.rs | 13 | ||||
| -rw-r--r-- | examples/example-pack-err/src/main.rs | 53 | ||||
| -rw-r--r-- | examples/test-examples.toml | 22 |
3 files changed, 69 insertions, 19 deletions
diff --git a/examples/example-general-renderer/src/main.rs b/examples/example-general-renderer/src/main.rs index c923d28..1e02afb 100644 --- a/examples/example-general-renderer/src/main.rs +++ b/examples/example-general-renderer/src/main.rs @@ -18,7 +18,7 @@ //! ``` use mingling::prelude::*; -use mingling::{parser::Picker, setup::GeneralRendererSetup, Groupped}; +use mingling::{parser::Picker, setup::GeneralRendererSetup, StructuralData, Groupped}; use serde::Serialize; dispatcher!("render", CMDRender => EntryRender); @@ -34,11 +34,12 @@ fn main() { // --------- IMPORTANT --------- // For beautiful output structure, do not use `pack!` to wrap the types that need to be output. // Instead, manually implement -// ____________________ Implement serde::Serialize -// / _________ Implement mingling::Groupped -// | / to ensure Mingling can recognize the type -// vvvvvvvvv vvvvvvvv -#[derive(Serialize, Groupped)] +// __________________________________ Mark as structured data so it can be rendered +// / ____________________ Implement serde::Serialize +// | / _________ Implement mingling::Groupped +// | | / to ensure Mingling can recognize the type +// vvvvvvvvvvvv vvvvvvvvv vvvvvvvv +#[derive(StructuralData, Serialize, Groupped)] struct Info { #[serde(rename = "member_name")] name: String, diff --git a/examples/example-pack-err/src/main.rs b/examples/example-pack-err/src/main.rs index 72fecd6..f859fae 100644 --- a/examples/example-pack-err/src/main.rs +++ b/examples/example-pack-err/src/main.rs @@ -7,21 +7,23 @@ //! 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 +//! cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find-structural --json +//! cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find-structural Cargo.toml --json +//! cargo run --manifest-path examples/example-pack-err/Cargo.toml --quiet -- find-structural 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 +//! {"name":"error_not_found"} +//! {"name":"error_not_dir","info":"Cargo.toml"} //! {"inner":"src"} +//! {"name":"error_not_found_structural"} +//! {"name":"error_not_dir_structural","info":"Cargo.toml"} //! ``` use mingling::prelude::*; @@ -29,6 +31,7 @@ use mingling::setup::GeneralRendererSetup; use std::path::PathBuf; dispatcher!("find", CMDFind => EntryFind); +dispatcher!("find-structural", CMDFindStructural => EntryFindStructural); // --------- IMPORTANT --------- // `pack_err!` is a convenient macro for defining error types. @@ -52,8 +55,14 @@ pack_err!(ErrorNotFound); // Typed form — name = "error_not_dir" pack_err!(ErrorNotDir = PathBuf); -// Success type using traditional pack! -pack!(ResultPath = PathBuf); +// Simple form — with StructuralData support for --json / --yaml +pack_err_structural!(ErrorNotFoundStructural); + +// Typed form — with StructuralData support for --json / --yaml +pack_err_structural!(ErrorNotDirStructural = PathBuf); + +// Success type with StructuralData support +pack_structural!(ResultPath = PathBuf); #[chain] fn handle_find(args: EntryFind) -> Next { @@ -72,6 +81,23 @@ fn handle_find(args: EntryFind) -> Next { } } +#[chain] +fn handle_find_structural(args: EntryFindStructural) -> Next { + let Some(path_str) = args.inner.first().cloned() else { + // No path provided → use the simple error form (Default) + return ErrorNotFoundStructural::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 + ErrorNotDirStructural::new(path).to_render() + } +} + /// Renders the successful result with the found directory path. #[renderer] fn render_result_path(path: ResultPath) { @@ -90,6 +116,18 @@ fn render_error_not_dir(err: ErrorNotDir) { r_println!("Not a directory: {}", err.info.display()); } +/// Renders the structural error when no search path is provided. +#[renderer] +fn render_error_not_found_structural(_: ErrorNotFoundStructural) { + r_println!("Search path not provided"); +} + +/// Renders the structural error when the given path is not a directory. +#[renderer] +fn render_error_not_dir_structural(err: ErrorNotDirStructural) { + r_println!("Not a directory: {}", err.info.display()); +} + gen_program!(); fn main() { @@ -97,5 +135,6 @@ fn main() { // Add GeneralRendererSetup to support --json / --yaml flags program.with_setup(GeneralRendererSetup); program.with_dispatcher(CMDFind); + program.with_dispatcher(CMDFindStructural); let _ = program.exec(); } diff --git a/examples/test-examples.toml b/examples/test-examples.toml index 9c25781..149f2c6 100644 --- a/examples/test-examples.toml +++ b/examples/test-examples.toml @@ -234,16 +234,26 @@ expect.exit-code = 0 expect.result = "Search path not provided" [[test.example-pack-err]] -command = "find --json" +command = "find Cargo.toml" expect.exit-code = 0 -expect.result = '{"name":"error_not_found"}' +expect.result = "Not a directory: Cargo.toml" [[test.example-pack-err]] -command = "find Cargo.toml" +command = "find examples" expect.exit-code = 0 -expect.result = "Not a directory: Cargo.toml" +expect.result = "Found directory: examples" + +[[test.example-pack-err]] +command = "find-structural --json" +expect.exit-code = 0 +expect.result = '{"name":"error_not_found_structural"}' + +[[test.example-pack-err]] +command = "find-structural Cargo.toml --json" +expect.exit-code = 0 +expect.result = '{"name":"error_not_dir_structural","info":"Cargo.toml"}' [[test.example-pack-err]] -command = "find Cargo.toml --json" +command = "find-structural examples --json" expect.exit-code = 0 -expect.result = '{"name":"error_not_dir","info":"Cargo.toml"}' +expect.result = '{"inner":"examples"}' |
