aboutsummaryrefslogtreecommitdiff
path: root/arg_picker
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-18 05:31:20 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-18 05:31:20 +0800
commite89608805efe7a24ab72b8030bc307b6a4f6d6fc (patch)
treefc722c41194d28f694ece2a21fd3902a0246c9cd /arg_picker
parente525ad90af0295e7f6b4f16367ba12a6d88abfb4 (diff)
feat(arg_picker): add preprocessing and postprocessing priority levels
Add `Begin`, `Preprocess`, `Final`, and `Postprocess` variants to `PickerArgAttr` enum, and implement `Pickable` for `PickerArgs` as a built-in picker that consumes all remaining unclaimed arguments at lowest priority. Expose `is_masked` and `build_masked_args` as public functions for use by custom pickers.
Diffstat (limited to 'arg_picker')
-rw-r--r--arg_picker/src/arg.rs26
-rw-r--r--arg_picker/src/builtin.rs1
-rw-r--r--arg_picker/src/builtin/pick_picker_args.rs21
-rw-r--r--arg_picker/src/parselib.rs23
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| {