diff options
Diffstat (limited to 'GETTING_STARTED.md')
| -rw-r--r-- | GETTING_STARTED.md | 95 |
1 files changed, 26 insertions, 69 deletions
diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index dbea3d2..1aad8d5 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -126,72 +126,26 @@ fn render_dispatcher_not_found(err: ErrorDispatcherNotFound) -> RenderResult { --- -## 4. Parsing Arguments — The Picker +## 4. Argument Parsing — Picker -Mingling provides a **Picker** for zero-cost argument extraction. You use `pick()` or `pick_or()` on an entry to extract typed values, then `unpack()` to get the final tuple. +Mingling provides a **Picker** for argument extraction. You can use `pick()` or `pick_or()` on an entry to tag typed values, then parse them into a tuple type all at once. ```rust -// Features: ["parser"] - -use mingling::parser::Picker; - +// Features: ["picker"] dispatcher!("greet", CMDGreet => EntryGreet); pack!(ResultGreeting = String); #[chain] fn handle_greet(args: EntryGreet) -> Next { - let (name, count) = Picker::new(args.inner) - .pick::<String>(()) // positional: first string - .pick_or::<u8>(["-r", "--repeat"], 1) // optional flag with default - .unpack(); - ResultGreeting::new(format!("{} x{}", name, count)).into() -} -``` - -With the `parser` feature, the `AsPicker` trait provides a shorthand directly on entries: - -```rust -// Features: ["parser"] - -dispatcher!("greet", CMDGreet => EntryGreet); -pack!(ResultGreeting = String); - -#[chain] -fn handle(args: EntryGreet) -> Next { let (name, count) = args - .pick::<Option<String>>(()) - .pick_or::<u8>(["-r", "--repeat"], 1) - .unpack(); - ResultGreeting::new(format!("{} x{}", name.unwrap_or_default(), count)).into() + .pick(&arg![String]) // positional argument: first string + .pick_or(&arg![repeat: u8, 'r'], || 1) // optional flag with default value + .unwrap(); + ResultGreeting::new(format!("{} x{}", name, count)).into() } ``` -For enums, derive `EnumTag` and implement `PickableEnum` to parse enum variants from strings: - -```rust -// Features: ["parser", "extra_macros"] - -use mingling::{EnumTag, Groupped}; -use mingling::parser::PickableEnum; - -dispatcher!("lang.select", CMDLang => EntryLang); - -#[derive(Debug, Default, EnumTag, Groupped)] -pub enum Language { - #[default] - Rust, - #[enum_rename("C++")] - CPlusPlus, -} - -impl PickableEnum for Language {} - -#[chain] -fn handle(args: EntryLang) -> Next { - let lang: Language = args.pick(()).unpack(); - lang.into() -} -``` +For more details on the Picker, see [arg-picker](https://github.com/mingling-rs/mingling/tree/main/arg_picker) --- @@ -369,7 +323,7 @@ Two built-in fallback types are always available: Chain and renderer functions can accept **additional parameters** for the program's global state. Resources are singleton values registered with `program.with_resource(...)`. ```rust -// Features: ["parser", "extra_macros"] +// Features: ["picker", "extra_macros"] use std::path::PathBuf; @@ -401,7 +355,7 @@ fn show_current(_prev: EntryCurrent, current_dir: &ResCurrentDir) -> Next { // Mutable access: #[chain] fn change_dir(prev: EntryCd, current_dir: &mut ResCurrentDir) -> Next { - let path: String = prev.pick(()).unpack(); + let path = prev.pick_or_default(&arg![String]).unwrap(); current_dir.current_dir = current_dir.current_dir.join(path); empty_result!() } @@ -473,7 +427,7 @@ use mingling::macros::dispatcher_clap; use mingling::prelude::*; use std::io::Write; -#[derive(Default, clap::Parser, Groupped)] +#[derive(Default, clap::Parser, Grouped)] #[dispatcher_clap( "greet", CMDGreet, help = true, // auto-generate #[help] from clap @@ -618,19 +572,21 @@ fn main() { With the `structural_renderer` feature, users can add `--json` or `--yaml` flags to get structured output instead of human-readable text. ```rust -// Features: ["structural_renderer", "parser"] +// Features: ["structural_renderer", "picker"] // Dependencies: // serde = "1" -use mingling::{prelude::*, setup::StructuralRendererSetup}; -use mingling::Groupped; +use mingling::prelude::*; +use mingling::macros::buffer; +use mingling::setup::picker::StructuralRendererSetup; +use mingling::Grouped; use mingling::StructuralData; use serde::Serialize; use std::io::Write; dispatcher!("render", CMDRender => EntryRender); -#[derive(Default, StructuralData, Serialize, Groupped)] +#[derive(Default, StructuralData, Serialize, Grouped)] struct ResultInfo { name: String, age: i32, @@ -638,15 +594,16 @@ struct ResultInfo { #[chain] fn render_info(args: EntryRender) -> Next { - let (name, age) = args.pick::<String>(()).pick::<i32>(()).unpack(); + let (name, age) = args + .pick_or_default(&arg![String]) + .pick_or_default(&arg![i32]) + .unwrap(); ResultInfo { name, age }.to_chain() } -#[renderer] -fn render_info_result(info: ResultInfo) -> RenderResult { - let mut result = RenderResult::new(); - writeln!(result, "{} is {} years old", info.name, info.age).ok(); - result +#[renderer(buffer)] +fn render_info_result(info: ResultInfo) { + r_println!("{} is {} years old", info.name, info.age); } fn main() { @@ -678,7 +635,7 @@ age: 22 Enable the `async` feature to use `async fn` inside `#[chain]`: ```rust -// Features: ["async", "parser"] +// Features: ["async", "picker"] // Dependencies: // tokio = { version = "1", features = ["full"] } @@ -690,7 +647,7 @@ pack!(ResultDownloaded = String); #[chain] pub async fn handle_download(args: EntryDownload) -> Next { - let file = args.pick(()).unpack(); + let file = args.pick_or_default(&arg![String]).unwrap(); download_file(file).await.into() } |
