From 57c53affe3542cb6bd4e79ee4c18f20a1bd76b2d Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 17 Aug 2026 05:49:19 +0800 Subject: refactor!: replace pack! macros with derive-based pipeline types Remove the `pack!`, `pack_err!`, `pack_structural!`, and `pack_err_structural!` macros, replacing all pipeline type definitions with `#[derive(Grouped)]` and `#[derive(Grouped, Wrap)]` attributes. This changes the generated struct shape from named-field structs with an `inner` field to tuple structs accessed via `.0`, and removes the auto-generated `name` and `info` fields from error types. --- docs/pages/6-argument-parse-picker.md | 64 +++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 25 deletions(-) (limited to 'docs/pages/6-argument-parse-picker.md') diff --git a/docs/pages/6-argument-parse-picker.md b/docs/pages/6-argument-parse-picker.md index da0fff1..9fe74eb 100644 --- a/docs/pages/6-argument-parse-picker.md +++ b/docs/pages/6-argument-parse-picker.md @@ -3,7 +3,7 @@ Use Picker to perform basic argument parsing

-In previous tutorials, we manually extracted parameters from `EntryGreet.inner` (`Vec`). +In previous tutorials, we manually extracted parameters from `EntryGreet.0` (`Vec`). ```rust @@@ fn main() { @@ -27,14 +27,15 @@ Now let's see how `Picker` is written: ```rust // Features: ["picker"] @@@dispatcher!("greet", EntryGreet); -@@@pack!(ResultName = String); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultName(String); #[chain] fn handle_greet_entry(prev: EntryGreet) -> Next { let name = prev .pick_or(&arg![String], || "World".to_string()) .unwrap(); - ResultName::new(name).into() + ResultName(name).into() } ``` @@ -45,13 +46,14 @@ For the code above: ```rust // Features: ["picker"] @@@dispatcher!("greet", EntryGreet); -@@@pack!(ResultName = String); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultName(String); @@@#[chain] @@@fn handle_greet_entry(prev: EntryGreet) -> Next { let name = prev .pick_or(&arg![String], || "World".to_string()) .unwrap(); -@@@ResultName::new(name).into() +@@@ResultName(name).into() @@@} ``` @@ -60,7 +62,8 @@ Its semantics are: ```rust // Features: ["picker"] @@@dispatcher!("greet", EntryGreet); -@@@pack!(ResultName = String); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultName(String); @@@#[chain] @@@fn handle_greet_entry(prev: EntryGreet) { @@@let name: String = @@ -81,14 +84,15 @@ If your program needs to parse flag arguments (e.g. `greet --name Alice`), decla ```rust // Features: ["picker"] @@@dispatcher!("greet", EntryGreet); -@@@pack!(ResultName = String); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultName(String); #[chain] fn handle_greet_entry(prev: EntryGreet) -> Next { let name = prev .pick_or(&arg![name: String, 'n'], || "World".to_string()) .unwrap(); - ResultName::new(name).into() + ResultName(name).into() } ``` @@ -99,7 +103,8 @@ Its semantics: ```rust // Features: ["picker"] @@@dispatcher!("greet", EntryGreet); -@@@pack!(ResultName = String); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultName(String); @@@#[chain] @@@fn handle_greet_entry(prev: EntryGreet) { @@@let name: String = @@ -122,7 +127,8 @@ For a single pick, `.unwrap()` returns the value directly; for multiple picks, i ```rust // Features: ["picker"] @@@dispatcher!("test", EntryTest); -@@@pack!(ResultInfo = (String, u8, u32)); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultInfo((String, u8, u32)); #[chain] fn handle_test_entry(prev: EntryTest) -> Next { @@ -132,7 +138,7 @@ fn handle_test_entry(prev: EntryTest) -> Next { .pick_or_default(&arg![id: u32, 'I']) .unwrap(); - ResultInfo::new((name, age, id)).into() + ResultInfo((name, age, id)).into() } ``` @@ -150,8 +156,10 @@ Here's a simple example: @@@use mingling::macros::buffer; @@@use mingling::macros::route; @@@dispatcher!("greet", EntryGreet); -@@@pack!(ResultName = String); -@@@pack!(ErrorNoName = ()); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultName(String); +@@@#[derive(Grouped, Wrap, Default)] +@@@pub struct ErrorNoName(()); #[chain] fn handle_greet_entry(prev: EntryGreet) -> Next { @@ -162,7 +170,7 @@ fn handle_greet_entry(prev: EntryGreet) -> Next { }) .to_result() ); - ResultName::new(name).into() + ResultName(name).into() } #[renderer(buffer)] @@ -177,12 +185,13 @@ However, **Mingling**'s `extras` feature provides the `route!` macro for simplif ```rust // Features: ["picker", "extras"] -@@@ pack!(ErrorFail = ()); +@@@ #[derive(Grouped, Wrap)] +@@@ pub struct ErrorFail(()); @@@ use mingling::macros::route; @@@ use mingling::picker::IntoPicker; @@@ fn func() -> mingling::ChainProcess { @@@ let args: Vec = vec![]; -let name = route!(args.pick_or_route(&arg![String], || ErrorFail::new(()).to_chain()).to_result()); +let name = route!(args.pick_or_route(&arg![String], || ErrorFail(()).to_chain()).to_result()); @@@ mingling::macros::empty_result!() @@@ } ``` @@ -191,11 +200,12 @@ It expands to: ```rust // Features: ["picker", "extras"] -@@@ pack!(ErrorFail = ()); +@@@ #[derive(Grouped, Wrap)] +@@@ pub struct ErrorFail(()); @@@ use mingling::picker::IntoPicker; @@@ fn func() -> mingling::ChainProcess { @@@ let args: Vec = vec![]; -let name = match args.pick_or_route(&arg![String], || ErrorFail::new(()).to_chain()).to_result() { +let name = match args.pick_or_route(&arg![String], || ErrorFail(()).to_chain()).to_result() { Ok(r) => r, Err(e) => return e, }; @@ -210,7 +220,8 @@ After picking user input with `pick`, you can use `post` to process it immediate ```rust // Features: ["picker"] @@@dispatcher!("greet", EntryGreet); -@@@pack!(ResultName = String); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultName(String); #[chain] fn handle_greet_entry(prev: EntryGreet) -> Next { @@ -225,7 +236,7 @@ fn handle_greet_entry(prev: EntryGreet) -> Next { }) .unwrap(); - ResultName::new(name).into() + ResultName(name).into() } ``` @@ -237,7 +248,8 @@ fn handle_greet_entry(prev: EntryGreet) -> Next { // Features: ["picker"] @@@use mingling::picker::value::Flag; @@@dispatcher!("test", EntryTest); -@@@pack!(ResultDone = ()); +@@@#[derive(Grouped, Wrap, Default)] +@@@pub struct ResultDone(()); #[chain] fn handle_entry(prev: EntryTest) -> Next { @@ -280,12 +292,13 @@ impl SinglePickable for Address { } } @@@dispatcher!("connect", EntryConnect); -@@@pack!(ResultConnected = Address); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultConnected(Address); #[chain] fn handle_connect_entry(prev: EntryConnect) -> Next { let address: Address = prev.pick_or_default(&arg![Address]).unwrap(); - ResultConnected::new(address).into() + ResultConnected(address).into() } #[renderer(buffer)] @@ -333,12 +346,13 @@ impl SinglePickable for Fruits { } } @@@dispatcher!("eat", EntryEat); -@@@pack!(ResultFruit = Fruits); +@@@#[derive(Grouped, Wrap)] +@@@pub struct ResultFruit(Fruits); #[chain] fn handle_eat_entry(prev: EntryEat) -> Next { let fruit: Fruits = prev.pick_or_default(&arg![Fruits]).unwrap(); - ResultFruit::new(fruit).into() + ResultFruit(fruit).into() } #[renderer(buffer)] -- cgit