aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-15 16:53:56 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-15 16:53:56 +0800
commit5209f78e3a1b6c067c210c31c1d2679f78851a40 (patch)
tree67aaf4a80d6d0caa6cc78f2cc53f22fdbf42021d
parent53fc28520c1314cd1bd223628c30d6a4423756a1 (diff)
feat(picker): add argument-position mask to tag phase
Pass a mutable mask to tag functions so Pickable implementations can detect which argument positions have already been claimed by other Pickables during the same parsing pass
-rw-r--r--mingling_picker/src/pickable.rs6
-rw-r--r--mingling_picker/src/picker/parse.rs12
2 files changed, 15 insertions, 3 deletions
diff --git a/mingling_picker/src/pickable.rs b/mingling_picker/src/pickable.rs
index 808830c..3f86745 100644
--- a/mingling_picker/src/pickable.rs
+++ b/mingling_picker/src/pickable.rs
@@ -78,4 +78,10 @@ pub struct TagPhaseContext<'a> {
/// A read-only list of all arguments in the current [`Picker`].
pub args: &'a PickerArgs<'a>,
+
+ /// Mask indicating which argument positions have already been claimed.
+ ///
+ /// For example, if the mask is `[0, 0, 1, 0]`, then the argument at index `2`
+ /// has already been tagged by another `Pickable`.
+ pub mask: &'a [u8],
}
diff --git a/mingling_picker/src/picker/parse.rs b/mingling_picker/src/picker/parse.rs
index f9a59d7..ec3c08c 100644
--- a/mingling_picker/src/picker/parse.rs
+++ b/mingling_picker/src/picker/parse.rs
@@ -36,7 +36,7 @@ internal_repeat!(1..=32 => {
PickerFlagAttr,
// Tag Func
- Box<dyn FnOnce(&PickerArgs<'a>) -> Vec<usize>>,
+ Box<dyn FnOnce(&PickerArgs<'a>, &[u8]) -> Vec<usize>>,
// Pick Func
Box<dyn FnOnce(&[&str], &mut Option<Route>)>,
@@ -51,10 +51,11 @@ internal_repeat!(1..=32 => {
T$::get_attr(self.flag_$),
// Tag Func
- Box::new(|args| {
+ Box::new(|args, mask| {
let ctx = TagPhaseContext {
arg_info: &arg_infos[$],
args,
+ mask
};
T$::tag(ctx)
}),
@@ -104,11 +105,16 @@ internal_repeat!(1..=32 => {
// Parsing
for (_, tag_func, pick_func, _idx) in bundle {
+ // Mask
+ let mut mask: Vec<u8> = vec![0u8; $];
+
// Tag phase
- let tagged = tag_func(&self.args);
+ let tagged = tag_func(&self.args, mask.as_slice());
let mut args_to_pick: Vec<&str> = vec![];
for i in tagged {
+ mask[i] = 1;
+
// Update args to pick
args_to_pick.push(self.args.get(i).unwrap_or_default());
}