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