diff options
Diffstat (limited to 'docs/dev/pages/issues/add-picker2.md')
| -rw-r--r-- | docs/dev/pages/issues/add-picker2.md | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/docs/dev/pages/issues/add-picker2.md b/docs/dev/pages/issues/add-picker2.md new file mode 100644 index 0000000..f5c3ca7 --- /dev/null +++ b/docs/dev/pages/issues/add-picker2.md @@ -0,0 +1,100 @@ +<h1 align="center">The Picker2 Arguments Parser</h1> +<p align="center"> + A smarter, faster alternative to Picker +</p> + +## Intro + +Mingling's `parser` feature is a temporary argument parsing solution created in the early stages of the project. While it can handle basic argument parsing tasks, its functionality is incomplete and has many limitations. + +This article aims to propose the design and development plan for the new Picker2 (feature name: `picker`). + +### Picker2 Expected Syntax + +1. **Pos args & flag args no longer depend on parsing order:** In `parser`, all flag args must be parsed before pos args. Picker2 removes this restriction. +2. **Declare flags with declarative macros:** Use `positional!()`, `flag![-X, --x]` etc. to declare flags — cleaner and more concise. +3. **One-shot `parse()` replaces step-by-step `unpack()`:** Defers the entire parsing flow to the final step, leaving more room for compile-time optimization. + +```rust +#[chain] +fn handle_hello(args: EntryHello) { + let parsed = args + .pick::<String>(positional!()) + .pick::<String>(flag![--help, -h]) + .parse(); +} +``` + +4. **Post-processing & routing control:** Use `after`, `after_route` to control post-processing logic. The route type is explicitly specified by the first `route` method. + +```rust +#[chain] +fn handle_hello(args: EntryHello) { + let parsed = args + .pick::<String>(positional!()) + .after(|v| format!("\"{}\"", v)) // post-processing + .parse(); +} +``` + +```rust +#[chain] +fn handle_hello(args: EntryHello) -> Next { + // requires impl Groupped<_> + // | + let parsed = args // vvvvvvvvvvvvvvvvvvv + .pick_route::<String, _>(positional!(), ErrorNoNameProvided) + .after_route(|v| Ok(format!("\"{}\"", v))) // post-process & route + .parse(); + let routed_parsed = route!(parsed); + empty_result!() +} +``` + +5. **Keep the `Pickable` Trait** +6. **Keep `PickableEnum` & provide a derive macro** +7. **Use `pick_optional`, `pick_vec` instead of implementing trait separately for `Option<T>`, `Vec<T>`** +8. **Use `pick_flag` instead of `pick::<bool>`** +9. **Provide `YesOrNo`, `TrueOrFalse` etc. that implement the `BoolFlag` trait for explicit bool extraction** +10. **Provide a `MultiFlag` derive macro, supporting arg modes like `pacman`** + +```rust +#[derive(MultiFlag)] +pub struct SomeToggles { + // default [-i] + pub install: bool, + + #[flag('U')] + pub uninstall: bool, + + #[flag('X')] + pub execute: bool, +} + +// Auto-implements Pickable, supports parsing args like `-iUX` +``` + +11. **Support multiple arg formats:** e.g. `--key=value`, `/Key=Value`, controlled by global config `PickerConfig` (or: `Picker::from_with_cfg(prev.inner, PickerConfig::default())`) + +12. `.parse()` no longer returns a bare tuple, but instead returns: + +```rust +pub struct PickerResult<Tuple> { + pub result: Tuple, + pub remains_argument: Arguments, +} +``` + +--- + +## 🕘 Progress + +- [x] In Progress + - [x] Added `Picker` struct and related call chain + - [x] Added `parselib` providing parsing logic + - [x] Added `Pickable` for extensibility + - [ ] Comprehensive testing! + - [ ] Improve documentation + - [ ] Add examples + - [ ] Update README +- [ ] Complete |
