aboutsummaryrefslogtreecommitdiff
path: root/mingling_picker/src/parselib/multi_arg_matcher.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-17 11:08:07 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-17 11:11:28 +0800
commit79ec6878877f0fd9246d67d3cd4f8cc2d1200150 (patch)
treee3cd8cfc7ef5cd2a6a7ceb93d9a4b1764fa21b61 /mingling_picker/src/parselib/multi_arg_matcher.rs
parente6136f22cff446b16dbebf3b26a6fdea6dbc0e83 (diff)
refactor: rename `mingling_picker` to `arg_picker`
Diffstat (limited to 'mingling_picker/src/parselib/multi_arg_matcher.rs')
-rw-r--r--mingling_picker/src/parselib/multi_arg_matcher.rs141
1 files changed, 0 insertions, 141 deletions
diff --git a/mingling_picker/src/parselib/multi_arg_matcher.rs b/mingling_picker/src/parselib/multi_arg_matcher.rs
deleted file mode 100644
index 748b1be..0000000
--- a/mingling_picker/src/parselib/multi_arg_matcher.rs
+++ /dev/null
@@ -1,141 +0,0 @@
-use crate::{
- matcher_needed::*,
- parselib::{build_possible_flags, seek_end_of_options},
-};
-
-/// `MultiArgMatcher` matches a named flag and **all** consecutive arguments
-/// that follow it, stopping at the next flag, the `--` marker, or the end
-/// of the argument list.
-///
-/// This is the tag implementation for `Multi` and `GreedyMulti` types
-/// such as `Vec<String>` (`--files a.txt b.txt`).
-///
-/// # Behavior
-///
-/// | Input | `on_match_all` |
-/// |-------|----------------|
-/// | `--val a b --val d e` | `[0, 1, 2, 5, 6]` (two groups) |
-/// | `--val=1 2` | `[0, 1]` (eq mode + one extra value) |
-///
-/// Args after `--` are ignored.
-pub struct MultiArgMatcher;
-
-impl Matcher for MultiArgMatcher {
- fn on_match_one(
- args: &[MaskedArg],
- style: &ParserStyle,
- arg_info: &PickerArgInfo,
- ) -> Option<usize> {
- if arg_info.positional {
- return args.first().map(|a| a.raw_idx);
- }
-
- let possible_flags = build_possible_flags(style, arg_info);
- let end = seek_end_of_options(args, style);
- let sep = style.value_separator;
-
- for arg in args {
- if end.is_some_and(|e| arg.raw_idx >= e) {
- break;
- }
- let matched = possible_flags
- .iter()
- .any(|f| Self::flag_match(arg.raw, f, style.case_sensitive, sep));
- if matched {
- return Some(arg.raw_idx);
- }
- }
- None
- }
-
- fn on_match_all(
- args: &[MaskedArg],
- style: &ParserStyle,
- arg_info: &PickerArgInfo,
- ) -> Vec<usize> {
- if arg_info.positional {
- let end = seek_end_of_options(args, style);
- return args
- .iter()
- .take_while(|a| end.is_none_or(|e| a.raw_idx < e))
- .map(|a| a.raw_idx)
- .collect();
- }
-
- let possible_flags = build_possible_flags(style, arg_info);
- let end = seek_end_of_options(args, style);
- let sep = style.value_separator;
- let is_flag =
- |raw: &str| raw.starts_with(style.long_prefix) || raw.starts_with(style.short_prefix);
- let is_our_flag = |raw: &str| {
- possible_flags
- .iter()
- .any(|f| Self::flag_match(raw, f, style.case_sensitive, sep))
- };
-
- let mut result = Vec::new();
- let mut i = 0;
- while i < args.len() {
- if end.is_some_and(|e| args[i].raw_idx >= e) {
- break;
- }
-
- let matched = is_our_flag(args[i].raw);
-
- if matched {
- result.push(args[i].raw_idx);
-
- if Self::is_eq_match(args[i].raw, &possible_flags, style.case_sensitive, sep) {
- i += 1;
- while i < args.len()
- && end.is_none_or(|e| args[i].raw_idx < e)
- && !is_flag(args[i].raw)
- {
- result.push(args[i].raw_idx);
- i += 1;
- }
- continue;
- }
-
- i += 1;
- while i < args.len()
- && end.is_none_or(|e| args[i].raw_idx < e)
- && !is_flag(args[i].raw)
- {
- result.push(args[i].raw_idx);
- i += 1;
- }
- continue;
- }
- i += 1;
- }
-
- result
- }
-}
-
-impl MultiArgMatcher {
- #[inline(always)]
- fn flag_match(raw: &str, flag_str: &str, case_sensitive: bool, sep: char) -> bool {
- let eq =
- |r: &str, f: &str| r.len() > f.len() && r.as_bytes().get(f.len()) == Some(&(sep as u8));
-
- if case_sensitive {
- raw == flag_str || (raw.starts_with(flag_str) && eq(raw, flag_str))
- } else {
- raw.eq_ignore_ascii_case(flag_str)
- || (raw.len() > flag_str.len()
- && raw[..flag_str.len()].eq_ignore_ascii_case(flag_str)
- && raw.as_bytes()[flag_str.len()] == sep as u8)
- }
- }
-
- #[inline(always)]
- fn is_eq_match(raw: &str, flags: &[String], case_sensitive: bool, sep: char) -> bool {
- flags.iter().any(|f| {
- Self::flag_match(raw, f, case_sensitive, sep)
- && raw.len() > f.len()
- && raw.as_bytes().get(f.len()) == Some(&(sep as u8))
- })
- }
-}