From aa251efb87b561f62266628f06ad341253fbbdc5 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 17 Aug 2026 04:05:41 +0800 Subject: refactor!: remove legacy parser feature and migrate to picker The legacy `parser` feature and its module tree (`mingling::parser`, `Argument`, `Picker`, `Pickable`, etc.) have been fully removed and replaced by the `picker` feature powered by `arg-picker`. BREAKING CHANGE: Remove `parser` feature and use `picker` instead. Migration guide: Replace `features = ["parser"]` with `features = ["picker"]` and update API usage per the provided table. --- examples/example-argument-parse/Cargo.lock | 223 ----------------------- examples/example-argument-parse/Cargo.toml | 12 -- examples/example-argument-parse/page.toml | 10 - examples/example-argument-parse/src/main.rs | 102 ----------- examples/example-argument-parse/test.toml | 29 --- examples/example-async-support/Cargo.lock | 25 ++- examples/example-async-support/Cargo.toml | 4 +- examples/example-async-support/src/main.rs | 2 +- examples/example-completion/Cargo.lock | 25 ++- examples/example-completion/Cargo.toml | 2 +- examples/example-completion/src/main.rs | 20 +- examples/example-custom-pickable/Cargo.lock | 223 ----------------------- examples/example-custom-pickable/Cargo.toml | 11 -- examples/example-custom-pickable/page.toml | 10 - examples/example-custom-pickable/src/main.rs | 130 ------------- examples/example-custom-pickable/test.toml | 17 -- examples/example-enum-tag/Cargo.lock | 25 ++- examples/example-enum-tag/Cargo.toml | 2 +- examples/example-enum-tag/src/main.rs | 40 +++- examples/example-panic-unwind/Cargo.lock | 25 ++- examples/example-panic-unwind/Cargo.toml | 2 +- examples/example-panic-unwind/src/main.rs | 2 +- examples/example-repl-basic/Cargo.lock | 25 ++- examples/example-repl-basic/Cargo.toml | 2 +- examples/example-repl-basic/src/main.rs | 2 +- examples/example-resources/Cargo.lock | 25 ++- examples/example-resources/Cargo.toml | 2 +- examples/example-resources/src/main.rs | 2 +- examples/example-structural-renderer/Cargo.lock | 25 ++- examples/example-structural-renderer/Cargo.toml | 2 +- examples/example-structural-renderer/src/main.rs | 12 +- examples/full-todolist/Cargo.lock | 25 ++- examples/full-todolist/Cargo.toml | 2 +- examples/full-todolist/src/main.rs | 15 +- 34 files changed, 215 insertions(+), 865 deletions(-) delete mode 100644 examples/example-argument-parse/Cargo.lock delete mode 100644 examples/example-argument-parse/Cargo.toml delete mode 100644 examples/example-argument-parse/page.toml delete mode 100644 examples/example-argument-parse/src/main.rs delete mode 100644 examples/example-argument-parse/test.toml delete mode 100644 examples/example-custom-pickable/Cargo.lock delete mode 100644 examples/example-custom-pickable/Cargo.toml delete mode 100644 examples/example-custom-pickable/page.toml delete mode 100644 examples/example-custom-pickable/src/main.rs delete mode 100644 examples/example-custom-pickable/test.toml (limited to 'examples') diff --git a/examples/example-argument-parse/Cargo.lock b/examples/example-argument-parse/Cargo.lock deleted file mode 100644 index 146e227..0000000 --- a/examples/example-argument-parse/Cargo.lock +++ /dev/null @@ -1,223 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "example-argument-parse" -version = "0.1.0" -dependencies = [ - "mingling", -] - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "just_fmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6170dccbc3ea15dfb7f2da964097f814aba1dd8f746d4ffc56f33245c38e6d96" - -[[package]] -name = "memchr" -version = "2.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" - -[[package]] -name = "might_be_async" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca871cea620b07bd2e6da0c883891a25bead698c43a9ab64b0fd663a7a78d5f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", - "toml", -] - -[[package]] -name = "mingling" -version = "0.5.0" -dependencies = [ - "mingling_core", - "mingling_macros", - "size", -] - -[[package]] -name = "mingling_core" -version = "0.5.0" -dependencies = [ - "just_fmt", - "might_be_async", -] - -[[package]] -name = "mingling_macros" -version = "0.5.0" -dependencies = [ - "just_fmt", - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "serde" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_core" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.3", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - -[[package]] -name = "syn" -version = "2.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] diff --git a/examples/example-argument-parse/Cargo.toml b/examples/example-argument-parse/Cargo.toml deleted file mode 100644 index e08adcd..0000000 --- a/examples/example-argument-parse/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "example-argument-parse" -version = "0.1.0" -edition = "2024" - -[dependencies.mingling] -path = "../../mingling" - -# Enable `parser` features -features = ["parser", "extras"] - -[workspace] diff --git a/examples/example-argument-parse/page.toml b/examples/example-argument-parse/page.toml deleted file mode 100644 index fc4d646..0000000 --- a/examples/example-argument-parse/page.toml +++ /dev/null @@ -1,10 +0,0 @@ -[example] -id = "example-argument-parse" -name = "Argument Parse" -icon = "📋" -category = "parsing" -desc = """ -Shows how to use Mingling's `parser` feature with a `Picker` to extract and validate typed arguments from the command line. -""" -tags = ["pick", "Pickable"] -files = ["src/main.rs", "Cargo.toml"] diff --git a/examples/example-argument-parse/src/main.rs b/examples/example-argument-parse/src/main.rs deleted file mode 100644 index d45c4af..0000000 --- a/examples/example-argument-parse/src/main.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! Example Argument Parse -//! -//! > This example demonstrates how to use the `parser` feature to parse user input -//! -//! Run: -//! ```bash -//! cargo run --manifest-path examples/example-argument-parse/Cargo.toml --quiet -- transfer README.md --size 32kib -//! cargo run --manifest-path examples/example-argument-parse/Cargo.toml --quiet -- transfer src/ --dir -//! cargo run --manifest-path examples/example-argument-parse/Cargo.toml --quiet -- strict-transfer README.md -//! cargo run --manifest-path examples/example-argument-parse/Cargo.toml --quiet -- strict-transfer --dir -//! ``` -//! -//! Output: -//! ```plaintext -//! file: README.md (32768) -//! dir: src/ (1048576) -//! file: README.md (1048576) -//! Error: name is not provided -//! ``` - -use mingling::{macros::route, prelude::*}; -use std::io::Write; - -dispatcher!("transfer", EntryTransfer); -dispatcher!("strict-transfer", EntryStrictTransfer); - -pack!(ResultFile = (bool, usize, String)); // (IsDir, Size, Name) - -#[chain] -fn handle_transfer_parse(args: EntryTransfer) -> Next { - // --------- IMPORTANT --------- - // First parse flag arguments (like --dir/-D), then positional arguments - let result: ResultFile = args - // Name --dir --size 20mib - // ^^^^^^^^^^^^_ first - .pick::(["--dir", "-D"]) - // Name --dir - // ^^^^^_ second (or `-D`) - .pick_or::("--size", 1024 * 1024_usize) - // Name - // ^^^^_ finally, pick positional arg - .pick::(()) - .after(|str| str.trim().replace(' ', "")) - // Unpack to tuple (is_dir, size, name) - .unpack() - // Convert into ResultFile - .into(); - // --------- IMPORTANT --------- - result.into() -} - -pack!(ErrorNoNameProvided = ()); - -#[chain] -fn handle_strict_transfer_parse(args: EntryStrictTransfer) -> Next { - // --------- IMPORTANT --------- - // Strict parsing: error immediately if the name is not provided - let result: ResultFile = route! { // Use `route!` to wrap a Picker that contains `or_route` - args - .pick::(["--dir", "-D"]) - .pick_or::("--size", 1024 * 1024_usize) - // Finally parse the positional argument; if not found, route to `ErrorNoNameProvided` - .pick_or_route::((), ErrorNoNameProvided::default()) - .after(|str| str.trim().replace(' ', "")) - .unpack() - } - // Convert into ResultFile - .into(); - // --------- IMPORTANT --------- - result.to_chain() -} - -/// Renders the parsed transfer result (file/dir, size, name). -#[renderer] -fn render_result_file(result: ResultFile) -> RenderResult { - let (is_dir, size, name) = result.into(); - let mut result = RenderResult::new(); - writeln!( - result, - "{}: {} ({})", - if is_dir { "dir" } else { "file" }, - name, - size - ) - .ok(); - result -} - -/// Renders the error when no name is provided. -#[renderer] -fn render_error_no_name_provided(_: ErrorNoNameProvided) -> RenderResult { - let mut result = RenderResult::new(); - writeln!(result, "Error: name is not provided").ok(); - result -} - -gen_program!(); - -fn main() { - let program = ThisProgram::new(); - program.exec_and_exit(); -} diff --git a/examples/example-argument-parse/test.toml b/examples/example-argument-parse/test.toml deleted file mode 100644 index a405bd9..0000000 --- a/examples/example-argument-parse/test.toml +++ /dev/null @@ -1,29 +0,0 @@ -[[runs]] -input = [ "transfer" ] - -expect.exit-code = 0 -expect.result = "file: (1048576)" - -[[runs]] -input = [ "transfer", "--dir", "src" ] - -expect.exit-code = 0 -expect.result = "dir: src (1048576)" - -[[runs]] -input = [ "transfer", "--size", "500", "myfile.txt" ] - -expect.exit-code = 0 -expect.result = "file: myfile.txt (500)" - -[[runs]] -input = [ "strict-transfer", "README.md" ] - -expect.exit-code = 0 -expect.result = "file: README.md (1048576)" - -[[runs]] -input = [ "strict-transfer" ] - -expect.exit-code = 0 -expect.result = "Error: name is not provided" diff --git a/examples/example-async-support/Cargo.lock b/examples/example-async-support/Cargo.lock index a2751be..f122f6d 100644 --- a/examples/example-async-support/Cargo.lock +++ b/examples/example-async-support/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -60,9 +77,9 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", - "size", ] [[package]] @@ -145,12 +162,6 @@ dependencies = [ "serde", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/example-async-support/Cargo.toml b/examples/example-async-support/Cargo.toml index d1b952d..a0d2a75 100644 --- a/examples/example-async-support/Cargo.toml +++ b/examples/example-async-support/Cargo.toml @@ -6,8 +6,8 @@ edition = "2024" [dependencies.mingling] path = "../../mingling" -# Enable `parser` features -features = ["async", "parser"] +# Enable `picker` features +features = ["async", "picker"] # Import any async runtime, e.g. Tokio [dependencies.tokio] diff --git a/examples/example-async-support/src/main.rs b/examples/example-async-support/src/main.rs index ac1bcc1..090602a 100644 --- a/examples/example-async-support/src/main.rs +++ b/examples/example-async-support/src/main.rs @@ -47,7 +47,7 @@ pack!(ResultDownloaded = String); #[chain] // vvvvv_ `async` keyword can be used directly here pub async fn handle_download(args: EntryDownload) -> Next { - let file_name = args.pick(()).unpack(); + let file_name = args.pick_or_default(&arg![String]).unwrap(); fake_download(file_name).await.into() } diff --git a/examples/example-completion/Cargo.lock b/examples/example-completion/Cargo.lock index 97401e7..d4b2f33 100644 --- a/examples/example-completion/Cargo.lock +++ b/examples/example-completion/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt 0.2.0", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -86,9 +103,9 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", - "size", ] [[package]] @@ -166,12 +183,6 @@ dependencies = [ "serde", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/example-completion/Cargo.toml b/examples/example-completion/Cargo.toml index 00c7f8c..9884f4e 100644 --- a/examples/example-completion/Cargo.toml +++ b/examples/example-completion/Cargo.toml @@ -9,7 +9,7 @@ path = "../../mingling" features = [ # Enable `comp` features "comp", - "parser", + "picker", ] [build-dependencies.mingling] diff --git a/examples/example-completion/src/main.rs b/examples/example-completion/src/main.rs index 7de41f6..d363697 100644 --- a/examples/example-completion/src/main.rs +++ b/examples/example-completion/src/main.rs @@ -74,18 +74,22 @@ fn complete_greet_entry(ctx: &ShellContext) -> Suggest { } // When the user is typing `--repeat` - if ctx.filling_argument(["-r", "--repeat"]) { + if ctx.previous_word == "-r" || ctx.previous_word == "--repeat" { return suggest! {}; // Don't suggest anything } // When the user is typing `-` - if ctx.typing_argument() { - return suggest! { + if ctx.current_word.starts_with('-') { + // Remove arguments that have already been typed by the user + let typed: Vec<&str> = ctx.all_words.iter().map(String::as_str).collect(); + let mut set = suggest! { "-r": "Number of repetitions", "--repeat": "Number of repetitions", + }; + if let Suggest::Suggest(items) = &mut set { + items.retain(|item| !typed.contains(&item.suggest().as_str())); } - // Remove arguments that have already been typed by the user - .strip_typed_argument(ctx); + return set; } // Otherwise, suggest nothing @@ -102,9 +106,9 @@ pack!(ResultName = (u8, String)); #[chain] fn handle_greet(args: EntryGreet) -> Next { let result: ResultName = args - .pick_or(["-r", "--repeat"], 1) - .pick_or((), "World") - .unpack() + .pick_or(&arg![repeat: u8, 'r'], || 1) + .pick_or(&arg![String], || "World".to_string()) + .unwrap() .into(); result.into() } diff --git a/examples/example-custom-pickable/Cargo.lock b/examples/example-custom-pickable/Cargo.lock deleted file mode 100644 index 3aa6236..0000000 --- a/examples/example-custom-pickable/Cargo.lock +++ /dev/null @@ -1,223 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "example-custom-pickable" -version = "0.1.0" -dependencies = [ - "mingling", -] - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "indexmap" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "just_fmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6170dccbc3ea15dfb7f2da964097f814aba1dd8f746d4ffc56f33245c38e6d96" - -[[package]] -name = "memchr" -version = "2.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" - -[[package]] -name = "might_be_async" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca871cea620b07bd2e6da0c883891a25bead698c43a9ab64b0fd663a7a78d5f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", - "toml", -] - -[[package]] -name = "mingling" -version = "0.5.0" -dependencies = [ - "mingling_core", - "mingling_macros", - "size", -] - -[[package]] -name = "mingling_core" -version = "0.5.0" -dependencies = [ - "just_fmt", - "might_be_async", -] - -[[package]] -name = "mingling_macros" -version = "0.5.0" -dependencies = [ - "just_fmt", - "proc-macro2", - "quote", - "syn 2.0.118", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "serde" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" -dependencies = [ - "serde_core", -] - -[[package]] -name = "serde_core" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.3", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - -[[package]] -name = "syn" -version = "2.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] diff --git a/examples/example-custom-pickable/Cargo.toml b/examples/example-custom-pickable/Cargo.toml deleted file mode 100644 index 9324bd6..0000000 --- a/examples/example-custom-pickable/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "example-custom-pickable" -version = "0.1.0" -edition = "2024" - -[dependencies.mingling] -path = "../../mingling" - -features = ["parser", "extras"] - -[workspace] diff --git a/examples/example-custom-pickable/page.toml b/examples/example-custom-pickable/page.toml deleted file mode 100644 index 1c3bfa0..0000000 --- a/examples/example-custom-pickable/page.toml +++ /dev/null @@ -1,10 +0,0 @@ -[example] -id = "example-custom-pickable" -name = "Custom Pickable" -icon = "🎯" -category = "parsing" -desc = """ -Shows how to implement the `Pickable` trait on custom types for seamless extraction from CLI arguments via Picker. -""" -tags = ["Pickable", "custom"] -files = ["src/main.rs", "Cargo.toml"] diff --git a/examples/example-custom-pickable/src/main.rs b/examples/example-custom-pickable/src/main.rs deleted file mode 100644 index 8265b09..0000000 --- a/examples/example-custom-pickable/src/main.rs +++ /dev/null @@ -1,130 +0,0 @@ -//! Example Custom Pickable -//! -//! > This example demonstrates how to use the Pickable trait to add parsing for your types -//! -//! Run: -//! ```bash -//! cargo run --manifest-path examples/example-custom-pickable/Cargo.toml --quiet -- connect 127.0.0.1:5012 -//! cargo run --manifest-path examples/example-custom-pickable/Cargo.toml --quiet -- connect 127.0.0.1 -//! ``` -//! -//! Output: -//! ```plaintext -//! Connected to "127.0.0.1:5012" -//! Failed to parse address -//! ``` - -use mingling::{macros::route, parser::Pickable, prelude::*, Grouped}; -use std::io::Write; - -// Define types that can be recognized by Mingling -// ________________________ `Pickable` trait needs to implement Default -// / ________ The Grouped derive macro registers an ID for this type -// | / Mingling uses this ID to identify the type -// vvvvvvv vvvvvvv -#[derive(Debug, Default, Clone, Grouped)] -pub struct Address { - pub ip: [u8; 4], - pub port: u16, -} - -// --------- IMPORTANT --------- -impl Pickable for Address { - type Output = Address; - fn pick(args: &mut mingling::parser::Argument, flag: mingling::Flag) -> Option { - // Extract the raw string from Argument using the Flag - let raw: String = args.pick_argument(flag)?.clone(); - - // Use TryFrom to parse the address - Address::try_from(raw).ok() - } -} -// --------- IMPORTANT --------- - -dispatcher!("connect", EntryConnect); -pack!(ErrorParseAddressFailed = ()); - -#[chain] -fn handle_connect(prev: EntryConnect) -> Next { - let connect: Address = - route! { prev.pick_or_route((), ErrorParseAddressFailed::default()).unpack() }; - connect.to_chain() -} - -/// Renders the connected address. -#[renderer] -pub fn render_address(addr: Address) -> RenderResult { - let mut render_result = RenderResult::new(); - write!(render_result, "Connected to \"{}\"", addr).ok(); - render_result -} - -/// Renders the error message when address parsing fails. -#[renderer] -pub fn render_error_parse_address_failed(_: ErrorParseAddressFailed) -> RenderResult { - let mut render_result = RenderResult::new(); - write!(render_result, "Failed to parse address").ok(); - render_result -} - -gen_program!(); - -fn main() { - ThisProgram::new().exec_and_exit(); -} - -// Address conversion - -impl TryFrom for Address { - type Error = String; - - fn try_from(raw: String) -> Result { - // Expected format: "192.168.1.1:8080" - let parts: Vec<&str> = raw.split(':').collect(); - if parts.len() != 2 { - return Err("Invalid format: expected 'IP:PORT'".to_string()); - } - - let ip_str = parts[0]; - let port_str = parts[1]; - - // Parse IP address (4 octets separated by dots) - let ip_parts: Vec<&str> = ip_str.split('.').collect(); - if ip_parts.len() != 4 { - return Err("Invalid IP address format".to_string()); - } - - let mut ip = [0u8; 4]; - for (i, part) in ip_parts.iter().enumerate() { - ip[i] = part - .parse::() - .map_err(|_| format!("Invalid IP octet: {part}"))?; - } - - // Parse port - let port = port_str - .parse::() - .map_err(|_| format!("Invalid port: {port_str}"))?; - - Ok(Address { ip, port }) - } -} - -impl From
for String { - fn from(addr: Address) -> String { - format!( - "{}.{}.{}.{}:{}", - addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3], addr.port - ) - } -} - -impl std::fmt::Display for Address { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}.{}.{}.{}:{}", - self.ip[0], self.ip[1], self.ip[2], self.ip[3], self.port - ) - } -} diff --git a/examples/example-custom-pickable/test.toml b/examples/example-custom-pickable/test.toml deleted file mode 100644 index 8fc20eb..0000000 --- a/examples/example-custom-pickable/test.toml +++ /dev/null @@ -1,17 +0,0 @@ -[[runs]] -input = [ "connect", "192.168.1.1:8080" ] - -expect.exit-code = 0 -expect.result = "Connected to \"192.168.1.1:8080\"" - -[[runs]] -input = [ "connect" ] - -expect.exit-code = 0 -expect.result = "Failed to parse address" - -[[runs]] -input = [ "connect", "invalid" ] - -expect.exit-code = 0 -expect.result = "Failed to parse address" diff --git a/examples/example-enum-tag/Cargo.lock b/examples/example-enum-tag/Cargo.lock index 868af79..492d708 100644 --- a/examples/example-enum-tag/Cargo.lock +++ b/examples/example-enum-tag/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt 0.2.0", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -86,9 +103,9 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", - "size", ] [[package]] @@ -166,12 +183,6 @@ dependencies = [ "serde", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/example-enum-tag/Cargo.toml b/examples/example-enum-tag/Cargo.toml index 9c0a0ff..489f401 100644 --- a/examples/example-enum-tag/Cargo.toml +++ b/examples/example-enum-tag/Cargo.toml @@ -8,7 +8,7 @@ path = "../../mingling" features = [ "comp", - "parser" + "picker" ] [workspace] diff --git a/examples/example-enum-tag/src/main.rs b/examples/example-enum-tag/src/main.rs index 2966036..c7fb502 100644 --- a/examples/example-enum-tag/src/main.rs +++ b/examples/example-enum-tag/src/main.rs @@ -16,8 +16,10 @@ //! ``` use mingling::{ - macros::suggest_enum, parser::PickableEnum, prelude::*, EnumTag, Grouped, ShellContext, - Suggest, + EnumTag, Grouped, ShellContext, Suggest, + macros::suggest_enum, + picker::{PickerArgResult, SinglePickable}, + prelude::*, }; use std::io::Write; @@ -57,9 +59,7 @@ pub enum ProgrammingLanguages { #[enum_desc("A general-purpose programming language with clean syntax, known for readability")] Python, - #[enum_desc( - "An object-oriented scripting language, famous for its concise and elegant syntax" - )] + #[enum_desc("An object-oriented scripting language, famous for its concise and elegant syntax")] Ruby, #[default] @@ -68,9 +68,31 @@ pub enum ProgrammingLanguages { } // --------- IMPORTANT --------- -// Implement the PickableEnum trait for ProgrammingLanguages, -// so that `Picker` can parse this enum -impl PickableEnum for ProgrammingLanguages {} +// NOTE: Due to the migration from the legacy `parser` to `picker`, the `EnumTag` -> `Picker` path +// is not yet complete, so a manual implementation is used for now. +// Once that path is complete, `#[derive(EnumTag)]` can automatically implement `SinglePickable`, +// replacing this manual implementation. +impl SinglePickable for ProgrammingLanguages { + fn pick_single(str: Option<&str>) -> PickerArgResult { + let Some(str) = str else { + return PickerArgResult::NotFound; + }; + let lang = match str.to_lowercase().as_str() { + "c" => Self::C, + "c++" | "cpp" => Self::CPlusPlus, + "c#" | "csharp" => Self::Csharp, + "java" => Self::Java, + "javascript" | "js" => Self::JavaScript, + "kotlin" => Self::Kotlin, + "ocaml" => Self::OCaml, + "python" => Self::Python, + "ruby" => Self::Ruby, + "rust" => Self::Rust, + _ => return PickerArgResult::NotFound, + }; + PickerArgResult::Parsed(lang) + } +} // --------- IMPORTANT --------- dispatcher!("lang-select", EntryLanguageSelection); @@ -78,7 +100,7 @@ dispatcher!("lang-select", EntryLanguageSelection); #[chain] fn handle_language_selection(args: EntryLanguageSelection) -> Next { // You can use Picker to directly parse ProgrammingLanguages - let lang: ProgrammingLanguages = args.pick(()).unpack(); + let lang: ProgrammingLanguages = args.pick_or_default(&arg![ProgrammingLanguages]).unwrap(); lang.into() } diff --git a/examples/example-panic-unwind/Cargo.lock b/examples/example-panic-unwind/Cargo.lock index ec5492d..20671f5 100644 --- a/examples/example-panic-unwind/Cargo.lock +++ b/examples/example-panic-unwind/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -59,9 +76,9 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", - "size", ] [[package]] @@ -138,12 +155,6 @@ dependencies = [ "serde", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/example-panic-unwind/Cargo.toml b/examples/example-panic-unwind/Cargo.toml index 559bdb9..463a288 100644 --- a/examples/example-panic-unwind/Cargo.toml +++ b/examples/example-panic-unwind/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies.mingling] path = "../../mingling" -features = ["parser"] +features = ["picker"] # Enable panic unwinding in release builds [profile.release] diff --git a/examples/example-panic-unwind/src/main.rs b/examples/example-panic-unwind/src/main.rs index e1aa15c..59adf07 100644 --- a/examples/example-panic-unwind/src/main.rs +++ b/examples/example-panic-unwind/src/main.rs @@ -41,7 +41,7 @@ fn main() { #[chain] fn handle_panic(prev: EntryPanic) -> Next { - let panic_info = prev.pick::>(()).unpack(); + let panic_info = prev.pick_or_default(&arg![Option]).unwrap(); match panic_info { Some(s) => { // Panic happens here, will be caught diff --git a/examples/example-repl-basic/Cargo.lock b/examples/example-repl-basic/Cargo.lock index e85083d..9764a85 100644 --- a/examples/example-repl-basic/Cargo.lock +++ b/examples/example-repl-basic/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt 0.2.0", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -66,9 +83,9 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", - "size", ] [[package]] @@ -145,12 +162,6 @@ dependencies = [ "serde", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/example-repl-basic/Cargo.toml b/examples/example-repl-basic/Cargo.toml index 3289939..7f2e463 100644 --- a/examples/example-repl-basic/Cargo.toml +++ b/examples/example-repl-basic/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies.mingling] path = "../../mingling" -features = ["repl", "parser", "extras"] +features = ["repl", "picker", "extras"] [dependencies] just_fmt = "0.1.2" diff --git a/examples/example-repl-basic/src/main.rs b/examples/example-repl-basic/src/main.rs index 325619e..d0fad6d 100644 --- a/examples/example-repl-basic/src/main.rs +++ b/examples/example-repl-basic/src/main.rs @@ -87,7 +87,7 @@ pack!(ResultList = Vec); // Parse cd command arguments #[chain] fn parse_cd_args(prev: EntryCd) -> Next { - let join = prev.pick(()).unpack(); + let join = prev.pick_or_default(&arg![String]).unwrap(); StateChangeDirectory::new(join).into() } diff --git a/examples/example-resources/Cargo.lock b/examples/example-resources/Cargo.lock index 9623e25..bfc04f0 100644 --- a/examples/example-resources/Cargo.lock +++ b/examples/example-resources/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -59,9 +76,9 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", - "size", ] [[package]] @@ -138,12 +155,6 @@ dependencies = [ "serde", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/example-resources/Cargo.toml b/examples/example-resources/Cargo.toml index faf24e4..72a530e 100644 --- a/examples/example-resources/Cargo.toml +++ b/examples/example-resources/Cargo.toml @@ -5,6 +5,6 @@ edition = "2024" [dependencies.mingling] path = "../../mingling" -features = ["parser"] +features = ["picker"] [workspace] diff --git a/examples/example-resources/src/main.rs b/examples/example-resources/src/main.rs index bb07d74..4d792b3 100644 --- a/examples/example-resources/src/main.rs +++ b/examples/example-resources/src/main.rs @@ -49,7 +49,7 @@ dispatcher!("modify-current", EntryModifyCurrent); fn render_modify_current(args: EntryModifyCurrent, current_dir: &mut ResCurrentDir) -> Next { current_dir.current_dir = current_dir .current_dir - .join(args.pick::(()).unpack()); + .join(args.pick_or_default(&arg![String]).unwrap()); EntryCurrent::default().into() } diff --git a/examples/example-structural-renderer/Cargo.lock b/examples/example-structural-renderer/Cargo.lock index ac4cbba..cf2cfe3 100644 --- a/examples/example-structural-renderer/Cargo.lock +++ b/examples/example-structural-renderer/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -66,10 +83,10 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", "serde", - "size", ] [[package]] @@ -182,12 +199,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/example-structural-renderer/Cargo.toml b/examples/example-structural-renderer/Cargo.toml index e29e9c3..2851303 100644 --- a/examples/example-structural-renderer/Cargo.toml +++ b/examples/example-structural-renderer/Cargo.toml @@ -11,7 +11,7 @@ path = "../../mingling" features = [ "structural_renderer", "yaml_serde_fmt", - "parser", + "picker", ] [workspace] diff --git a/examples/example-structural-renderer/src/main.rs b/examples/example-structural-renderer/src/main.rs index eca87fc..a1bddbd 100644 --- a/examples/example-structural-renderer/src/main.rs +++ b/examples/example-structural-renderer/src/main.rs @@ -17,8 +17,8 @@ //! member_age: 22 //! ``` -use mingling::prelude::*; -use mingling::{parser::Picker, setup::StructuralRendererSetup, Grouped, StructuralData}; +use mingling::setup::picker::StructuralRendererSetup; +use mingling::{Grouped, StructuralData, prelude::*}; use serde::Serialize; use std::io::Write; @@ -55,10 +55,10 @@ struct Info { #[chain] fn parse_render(prev: EntryRender) -> Next { - let (name, age) = Picker::new(prev.inner) - .pick::(()) - .pick::(()) - .unpack(); + let (name, age) = prev + .pick_or_default(&arg![String]) + .pick_or_default(&arg![i32]) + .unwrap(); Info { name, age }.to_render() } diff --git a/examples/full-todolist/Cargo.lock b/examples/full-todolist/Cargo.lock index 4fc964d..ad9f475 100644 --- a/examples/full-todolist/Cargo.lock +++ b/examples/full-todolist/Cargo.lock @@ -2,6 +2,23 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arg-picker" +version = "0.2.0" +dependencies = [ + "arg-picker-macros", + "just_fmt", +] + +[[package]] +name = "arg-picker-macros" +version = "0.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -67,10 +84,10 @@ dependencies = [ name = "mingling" version = "0.5.0" dependencies = [ + "arg-picker", "mingling_core", "mingling_macros", "serde", - "size", ] [[package]] @@ -163,12 +180,6 @@ dependencies = [ "serde", ] -[[package]] -name = "size" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6709c7b6754dca1311b3c73e79fcce40dd414c782c66d88e8823030093b02b" - [[package]] name = "syn" version = "2.0.118" diff --git a/examples/full-todolist/Cargo.toml b/examples/full-todolist/Cargo.toml index 9d6f1a7..fb3d3be 100644 --- a/examples/full-todolist/Cargo.toml +++ b/examples/full-todolist/Cargo.toml @@ -10,7 +10,7 @@ serde_json = "1.0.150" [dependencies.mingling] path = "../../mingling" features = [ - "parser", + "picker", "extras", "structural_renderer", ] diff --git a/examples/full-todolist/src/main.rs b/examples/full-todolist/src/main.rs index c0df1df..eea417a 100644 --- a/examples/full-todolist/src/main.rs +++ b/examples/full-todolist/src/main.rs @@ -9,9 +9,10 @@ use mingling::{ LazyInit, LazyRes, macros::route, + picker::value::Flag, prelude::*, res::ResExitCode, - setup::{ExitCodeSetup, HelpFlagSetup, StructuralRendererSetup}, + setup::{ExitCodeSetup, picker::HelpFlagSetup, picker::StructuralRendererSetup}, }; use std::io::Write; @@ -51,7 +52,7 @@ fn main() { // Setups program.with_setup(ExitCodeSetup::default()); program.with_setup(StructuralRendererSetup); - program.with_setup(HelpFlagSetup::new(["--help", "-h"])); + program.with_setup(HelpFlagSetup::new(&arg![help: Flag, 'h'])); // Flags let all = program.pick_global_flag(["-A", "--all"]); @@ -74,9 +75,10 @@ fn main() { #[chain] fn handle_add(args: EntryAdd) -> Next { let task: String = route! { - args - .pick_or_route((), ErrorNoTaskDescriptionProvided::new(())) - .unpack() + args.pick_or_route(&arg![String], || { + ErrorNoTaskDescriptionProvided::new(()).to_chain() + }) + .to_result() }; StateAddTodo::new(task).to_chain() } @@ -115,7 +117,8 @@ fn handle_list(_args: EntryList, todolist: &mut LazyRes) -> Next { #[chain] fn handle_complete(args: EntryComplete) -> Next { let index: i32 = route! { - args.pick_or_route((), ErrorNoIndexProvided::new(())).unpack() + args.pick_or_route(&arg![i32], || ErrorNoIndexProvided::new(()).to_chain()) + .to_result() }; StateCompleteTodo::new(index).to_chain() } -- cgit