diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-15 16:53:56 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-15 16:53:56 +0800 |
| commit | 5209f78e3a1b6c067c210c31c1d2679f78851a40 (patch) | |
| tree | 67aaf4a80d6d0caa6cc78f2cc53f22fdbf42021d | |
| parent | 53fc28520c1314cd1bd223628c30d6a4423756a1 (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.rs | 6 | ||||
| -rw-r--r-- | mingling_picker/src/picker/parse.rs | 12 |
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()); } |
