diff options
Diffstat (limited to 'mingling/src/picker')
| -rw-r--r-- | mingling/src/picker/entry_picker.rs | 126 | ||||
| -rw-r--r-- | mingling/src/picker/global.rs | 35 |
2 files changed, 161 insertions, 0 deletions
diff --git a/mingling/src/picker/entry_picker.rs b/mingling/src/picker/entry_picker.rs new file mode 100644 index 0000000..7364c50 --- /dev/null +++ b/mingling/src/picker/entry_picker.rs @@ -0,0 +1,126 @@ +use mingling_core::{ChainProcess, Grouped, ProgramCollect}; + +use crate::{picker::Pickable, picker::Picker, picker::PickerArg, picker::PickerPattern1}; + +/// Trait for converting Mingling entry types (types that implement `Grouped<R>` and `Into<Vec<String>>`) +/// into [`Picker`] instances for a given route type `R`. +/// +/// This trait provides a bridge between entry definitions created with the `mingling` framework +/// and the picker argument system used for CLI argument parsing and routing. +/// +/// # Type Parameters +/// +/// * `'a` — The lifetime of the picker and its references to argument definitions. +/// * `This` — The program type used for dispatching runtime routes; must implement [`ProgramCollect`]. +/// * `Route` — The route type used for dispatching; must implement [`Grouped<This>`]. +pub trait EntryPicker<'a, This> { + /// Converts `self` into a [`Picker`] for the given route type `Route`. + fn to_picker(self) -> Picker<'a, ChainProcess<This>>; + + /// Starts building a picker pattern with the first argument. + /// + /// Returns a [`PickerPattern1`] that can be further chained with additional + /// arguments, defaults, routes, and post-processing. + /// + /// # Type Parameters + /// + /// * `Next` — The nominal type of the first argument; must implement [`Pickable`]. + /// + /// # Parameters + /// + /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`]. + fn pick<Next>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + ) -> PickerPattern1<'a, Next, ChainProcess<This>> + where + Self: Sized, + Next: Pickable<'a> + Default + Sized, + { + let picker = Self::to_picker(self); + Picker::build_pattern1(picker.into_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, ChainProcess<This>> + where + Self: Sized, + Next: Pickable<'a> + Default + 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, ChainProcess<This>> + 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>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + func: F, + ) -> PickerPattern1<'a, Next, ChainProcess<This>> + where + Self: Sized, + Next: Pickable<'a> + Default + Sized, + F: FnMut() -> ChainProcess<This> + 'static, + { + self.pick(arg).or_route(func) + } +} + +impl<'a, This, Bind> EntryPicker<'a, This> for Bind +where + This: ProgramCollect<Enum = This>, + Bind: Grouped<This> + Into<Vec<String>>, +{ + fn to_picker(self) -> Picker<'a, ChainProcess<This>> { + let args = self.into(); + Picker::from(args) + } +} diff --git a/mingling/src/picker/global.rs b/mingling/src/picker/global.rs new file mode 100644 index 0000000..c203524 --- /dev/null +++ b/mingling/src/picker/global.rs @@ -0,0 +1,35 @@ +use arg_picker::{IntoPicker, Pickable, PickerArg, value::Flag}; +use mingling_core::{Program, ProgramCollect}; + +use crate::consts::REMAINS; + +/// Picks a global flag from the program's arguments. +/// +/// This function takes ownership of the program's current arguments, picks the specified `flag` +/// from them, and then returns the remaining arguments back to the program. It returns the +/// boolean value of the flag. +pub fn pick_global_flag<C>(program: &mut Program<C>, flag: &PickerArg<Flag>) -> bool +where + C: ProgramCollect<Enum = C>, +{ + let args = program.take_args(); + let (flag, args) = args.pick(flag).pick(&REMAINS).unwrap(); + program.replace_args(args.into()); + *flag +} + +/// Picks a global argument from the program's arguments. +/// +/// This function takes ownership of the program's current arguments, picks the specified `arg` +/// from them, and then returns the remaining arguments back to the program. It returns the +/// picked argument value, or `None` if the argument was not present. +pub fn pick_global_argument<C, A>(program: &mut Program<C>, arg: &PickerArg<A>) -> Option<A> +where + A: for<'a> Pickable<'a> + Default, + C: ProgramCollect<Enum = C>, +{ + let args = program.take_args(); + let (arg, remains) = args.pick(arg).pick(&REMAINS).unpack(); + program.replace_args(remains.unwrap().into()); + arg +} |
