diff options
| -rw-r--r-- | arg_picker/src/arg.rs | 26 | ||||
| -rw-r--r-- | arg_picker/src/builtin.rs | 1 | ||||
| -rw-r--r-- | arg_picker/src/builtin/pick_picker_args.rs | 21 | ||||
| -rw-r--r-- | arg_picker/src/parselib.rs | 23 |
4 files changed, 68 insertions, 3 deletions
diff --git a/arg_picker/src/arg.rs b/arg_picker/src/arg.rs index 78ad539..a352418 100644 --- a/arg_picker/src/arg.rs +++ b/arg_picker/src/arg.rs @@ -138,9 +138,27 @@ where /// Describes the attribute (behavior) of a command-line parameter. /// /// The ordering reflects parse priority (higher = parsed first): -/// `PositionalMulti < Positional < Flag < Single < Multi` +/// `Postprocess < Final < PositionalMulti < Positional < Flag < Single < Multi < Begin < Preprocess` +/// +/// # Variants +/// +/// - `Postprocess` — Reserved lowest priority, used only in special cases. +/// - `Final` — Reserved post-processing priority, used only in special cases. +/// - `PositionalMulti` — Positional argument that accepts multiple values (e.g., multiple input files). +/// - `Positional` — Positional argument matched by its position (e.g., an input file). +/// - `Flag` — Boolean flag with no associated value (e.g., `--verbose`). +/// - `Single` — Accepts a single value (e.g., `--name Alice`). +/// - `Multi` — Accepts multiple values (e.g., `--file a.txt --file b.txt`). +/// - `Begin` — Reserved pre-processing priority, used only in special cases. +/// - `Preprocess` — Reserved highest priority, used only in special cases. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum PickerArgAttr { + /// Reserved lowest priority, used only in special cases. + Postprocess, + + /// Reserved post-processing priority, used only in special cases. + Final, + /// Positional argument that accepts multiple values (e.g., multiple input files). PositionalMulti, @@ -156,6 +174,12 @@ pub enum PickerArgAttr { /// Accepts multiple values (e.g., `--file a.txt --file b.txt`). Multi, + + /// Reserved pre-processing priority, used only in special cases. + Begin, + + /// Reserved highest priority, used only in special cases. + Preprocess, } impl PickerArgAttr { diff --git a/arg_picker/src/builtin.rs b/arg_picker/src/builtin.rs index e855b08..1c698ba 100644 --- a/arg_picker/src/builtin.rs +++ b/arg_picker/src/builtin.rs @@ -1,4 +1,5 @@ mod pick_bool; mod pick_flag; mod pick_numbers; +mod pick_picker_args; mod pick_string; diff --git a/arg_picker/src/builtin/pick_picker_args.rs b/arg_picker/src/builtin/pick_picker_args.rs new file mode 100644 index 0000000..419cbc8 --- /dev/null +++ b/arg_picker/src/builtin/pick_picker_args.rs @@ -0,0 +1,21 @@ +use crate::{PickerArgResult::Parsed, PickerArgs, parselib::build_masked_args, pickable_needed::*}; + +impl<'a> Pickable<'a> for PickerArgs<'a> { + fn get_attr(_flag: &'a PickerArg<'a, Self>) -> PickerArgAttr { + // Use the lowest priority attribute + PickerArgAttr::Postprocess + } + + fn tag(ctx: TagPhaseContext) -> Vec<usize> { + // Collect all remaining raw index values + build_masked_args(ctx.args, ctx.mask) + .iter() + .map(|m| m.raw_idx) + .collect() + } + + fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> { + let remains: Vec<String> = raw_strs.iter().map(|s| s.to_string()).collect(); + Parsed(PickerArgs::Owned(remains)) + } +} diff --git a/arg_picker/src/parselib.rs b/arg_picker/src/parselib.rs index 7fbd606..0fcd583 100644 --- a/arg_picker/src/parselib.rs +++ b/arg_picker/src/parselib.rs @@ -117,13 +117,32 @@ impl<'a> From<crate::TagPhaseContext<'a>> for MatcherContext<'a> { } } +/// Checks whether the argument at index `idx` is already claimed (masked). +/// +/// Returns `true` if `idx` is within the mask bounds and the mask value is non-zero, +/// indicating the argument has been claimed by a previous matcher. +/// +/// # Arguments +/// +/// * `mask` - A byte slice where non-zero values indicate claimed arguments. +/// * `idx` - The index to check in the mask. #[inline(always)] -fn is_masked(mask: &[u8], idx: usize) -> bool { +pub fn is_masked(mask: &[u8], idx: usize) -> bool { idx < mask.len() && mask[idx] != 0 } +/// Builds a vector of [`MaskedArg`] from the given `PickerArgs` and mask. +/// +/// Only arguments whose mask entry is `0` (i.e., available/not yet claimed) are included. +/// Each resulting [`MaskedArg`] retains its original raw string and its index in the full +/// argument list for later reference. +/// +/// # Arguments +/// +/// * `args` - The full set of parsed arguments. +/// * `mask` - A byte slice where `0` means available and non-zero means already claimed. #[inline(always)] -fn build_masked_args<'a>(args: &'a PickerArgs, mask: &'a [u8]) -> Vec<MaskedArg<'a>> { +pub fn build_masked_args<'a>(args: &'a PickerArgs, mask: &'a [u8]) -> Vec<MaskedArg<'a>> { let mut cidx = 0; args.iter() .filter_map(|r| { |
