diff options
| -rw-r--r-- | CHANGELOG.md | 10 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | mingling/src/parser/picker.rs | 66 |
3 files changed, 77 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index eb30d4b..f66dbd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,16 @@ this::<ThisProgram>().modify_res(|r: &mut Global| { }); ``` +11. **\[picker\]** For any type that can `Into<Vec<String>>`, `.pick()`, `.pick_or()`, and `.pick_or_route()` functions are now supported + +```rust +// Before +let name: String = Picker::new(prev.inner).pick("--name").unpack(); + +// Now +let name: String = prev.pick("--name").unpack(); +``` + #### **BREAKING CHANGES**: 1. **\[macros\]** Removed macro `dispatcher_render!` from `mingling_macros` @@ -161,7 +161,7 @@ fn comp_greet_command(ctx: &ShellContext) -> Suggest { // Define chain, parsing `GreetEntry` into `StateGreeting` #[chain] fn parse_name_to_greet(prev: GreetEntry) -> NextProcess { - let state_greeting: StateGreeting = Picker::<()>::new(prev.inner) + let state_greeting: StateGreeting = Picker::new(prev.inner) .pick_or::<String>((), "World") .unpack_directly() .into(); diff --git a/mingling/src/parser/picker.rs b/mingling/src/parser/picker.rs index 4641a49..915bc35 100644 --- a/mingling/src/parser/picker.rs +++ b/mingling/src/parser/picker.rs @@ -719,3 +719,69 @@ where T::build_enum(name) } } + +pub trait AsPicker +where + Self: Into<Vec<String>>, +{ + /// Converts the value into a `Picker` by first converting it into a `Vec<String>`. + fn as_picker(self) -> Picker + where + Self: Sized, + Vec<String>: From<Self>, + { + let vec: Vec<String> = self.into(); + Picker { args: vec.into() } + } + + /// Extracts a value for the given flag and returns a `Pick1` builder (no route). + /// + /// The extracted type `TNext` must implement `Pickable` and `Default`. + /// If the flag is not present, the default value for `TNext` is used. + fn pick<TNext>(self, val: impl Into<Flag>) -> Pick1<TNext> + where + Self: Sized, + TNext: Pickable<Output = TNext> + Default, + { + let vec: Vec<String> = self.into(); + let picker: Picker = vec.into(); + picker.pick(val) + } + + /// Extracts a value for the given flag, returning the provided default value if not present, + /// and returns a `Pick1` builder (no route). + /// + /// The extracted type `TNext` must implement `Pickable`. + /// If the flag is not present, the provided `or` value is used. + fn pick_or<TNext>(self, val: impl Into<Flag>, or: impl Into<TNext>) -> Pick1<TNext> + where + TNext: Pickable<Output = TNext>, + { + let vec: Vec<String> = self.into(); + let picker: Picker = vec.into(); + picker.pick_or(val, or) + } + + /// Extracts a value for the given flag, storing the provided route if the flag is not present, + /// and returns a `PickWithRoute1` builder (with route). + /// + /// The extracted type `TNext` must implement `Pickable` and `Default`. + /// If the flag is not present, the default value for `TNext` is used and the provided `route` + /// is stored in the returned builder for later error handling. + fn pick_or_route<TNext, R>(self, val: impl Into<Flag>, route: R) -> PickWithRoute1<TNext, R> + where + TNext: Pickable<Output = TNext> + Default, + { + let vec: Vec<String> = self.into(); + let picker: Picker = vec.into(); + picker.pick_or_route(val, route) + } +} + +// Implement AsPicker for any type that can be converted into a Vec<String> +impl<T> AsPicker for T +where + T: Sized, + Vec<String>: From<T>, +{ +} |
