diff options
| -rw-r--r-- | arg_picker/src/picker.rs | 74 | ||||
| -rw-r--r-- | arg_picker_macros/src/arg.rs | 11 | ||||
| -rw-r--r-- | mingling/src/picker/entry_picker.rs | 6 |
3 files changed, 86 insertions, 5 deletions
diff --git a/arg_picker/src/picker.rs b/arg_picker/src/picker.rs index f31a5b6..f722fb5 100644 --- a/arg_picker/src/picker.rs +++ b/arg_picker/src/picker.rs @@ -369,11 +369,83 @@ pub trait IntoPicker<'a> { fn pick<N>(self, arg: impl Into<&'a PickerArg<'a, N>>) -> PickerPattern1<'a, N, ()> where Self: Sized, - N: Pickable<'a> + Default + Sized, + N: Pickable<'a> + Sized, { Picker::build_pattern1(self.to_picker().args, arg.into(), None::<()>) } + /// Starts building a picker pattern with the first argument, using a default value provider. + /// + /// This is a shorthand for calling `.pick(arg).or(func)`. + /// + /// # Type Parameters + /// + /// * `Next` — The nominal type of the first argument; must implement [`Pickable`]. + /// + /// # Parameters + /// + /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`]. + /// * `func` — A closure that provides a default value if the arg is not provided by the user. + fn pick_or<Next, F>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + func: F, + ) -> PickerPattern1<'a, Next, ()> + where + Self: Sized, + Next: Pickable<'a> + Sized, + F: FnMut() -> Next + 'static, + { + self.pick(arg).or(func) + } + + /// Starts building a picker pattern with the first argument, using a default value. + /// + /// This is a shorthand for calling `.pick(arg).or_default()`. + /// + /// # Type Parameters + /// + /// * `Next` — The nominal type of the first argument; must implement [`Pickable`] and [`Default`]. + /// + /// # Parameters + /// + /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`]. + fn pick_or_default<Next>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + ) -> PickerPattern1<'a, Next, ()> + where + Self: Sized, + Next: Pickable<'a> + Default + Sized, + { + self.pick(arg).or_default() + } + + /// Starts building a picker pattern with the first argument, using a route if the arg is not provided. + /// + /// This is a shorthand for calling `.pick(arg).or_route(func)`. + /// + /// # Type Parameters + /// + /// * `Next` — The nominal type of the first argument; must implement [`Pickable`]. + /// + /// # Parameters + /// + /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`]. + /// * `func` — A closure that produces a route value if the arg is not provided by the user. + fn pick_or_route<Next, F, Route>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + func: F, + ) -> PickerPattern1<'a, Next, Route> + where + Self: Sized, + Next: Pickable<'a> + Sized, + F: FnMut() -> Route + 'static, + { + self.pick(arg).with_route::<Route>().or_route(func) + } + /// Converts the value into a `Picker` with a specified route type. /// /// This method allows changing the route (phantom type parameter) of the picker. diff --git a/arg_picker_macros/src/arg.rs b/arg_picker_macros/src/arg.rs index 55860c4..20731b1 100644 --- a/arg_picker_macros/src/arg.rs +++ b/arg_picker_macros/src/arg.rs @@ -119,6 +119,7 @@ pub(crate) fn arg(input: TokenStream) -> TokenStream { fn split_at_commas(tokens: &[TokenTree]) -> Vec<Vec<TokenTree>> { let mut result = vec![Vec::new()]; let mut depth = 0u32; + let mut angle_depth = 0u32; for t in tokens { match t { TokenTree::Group(_g) => { @@ -126,7 +127,15 @@ fn split_at_commas(tokens: &[TokenTree]) -> Vec<Vec<TokenTree>> { result.last_mut().unwrap().push(t.clone()); depth -= 1; } - TokenTree::Punct(p) if p.as_char() == ',' && depth == 0 => { + TokenTree::Punct(p) if p.as_char() == '<' => { + angle_depth += 1; + result.last_mut().unwrap().push(t.clone()); + } + TokenTree::Punct(p) if p.as_char() == '>' && angle_depth > 0 => { + angle_depth -= 1; + result.last_mut().unwrap().push(t.clone()); + } + TokenTree::Punct(p) if p.as_char() == ',' && depth == 0 && angle_depth == 0 => { result.push(Vec::new()); } _ => result.last_mut().unwrap().push(t.clone()), diff --git a/mingling/src/picker/entry_picker.rs b/mingling/src/picker/entry_picker.rs index 7364c50..d9fb37c 100644 --- a/mingling/src/picker/entry_picker.rs +++ b/mingling/src/picker/entry_picker.rs @@ -35,7 +35,7 @@ pub trait EntryPicker<'a, This> { ) -> PickerPattern1<'a, Next, ChainProcess<This>> where Self: Sized, - Next: Pickable<'a> + Default + Sized, + Next: Pickable<'a> + Sized, { let picker = Self::to_picker(self); Picker::build_pattern1(picker.into_args(), arg.into(), None) @@ -60,7 +60,7 @@ pub trait EntryPicker<'a, This> { ) -> PickerPattern1<'a, Next, ChainProcess<This>> where Self: Sized, - Next: Pickable<'a> + Default + Sized, + Next: Pickable<'a> + Sized, F: FnMut() -> Next + 'static, { self.pick(arg).or(func) @@ -107,7 +107,7 @@ pub trait EntryPicker<'a, This> { ) -> PickerPattern1<'a, Next, ChainProcess<This>> where Self: Sized, - Next: Pickable<'a> + Default + Sized, + Next: Pickable<'a> + Sized, F: FnMut() -> ChainProcess<This> + 'static, { self.pick(arg).or_route(func) |
