diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-17 11:08:07 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-17 11:11:28 +0800 |
| commit | 79ec6878877f0fd9246d67d3cd4f8cc2d1200150 (patch) | |
| tree | e3cd8cfc7ef5cd2a6a7ceb93d9a4b1764fa21b61 /mingling_picker/src/parselib/arg_matcher.rs | |
| parent | e6136f22cff446b16dbebf3b26a6fdea6dbc0e83 (diff) | |
refactor: rename `mingling_picker` to `arg_picker`
Diffstat (limited to 'mingling_picker/src/parselib/arg_matcher.rs')
| -rw-r--r-- | mingling_picker/src/parselib/arg_matcher.rs | 142 |
1 files changed, 0 insertions, 142 deletions
diff --git a/mingling_picker/src/parselib/arg_matcher.rs b/mingling_picker/src/parselib/arg_matcher.rs deleted file mode 100644 index 38bb9cc..0000000 --- a/mingling_picker/src/parselib/arg_matcher.rs +++ /dev/null @@ -1,142 +0,0 @@ -use crate::{ - matcher_needed::*, - parselib::{build_possible_flags, seek_end_of_options}, -}; - -/// `ArgMatcher` is used for parameters that carry a single value. -/// -/// It handles two scenarios: -/// -/// **Named** — `--name Alice` or `--name=Alice`. -/// Each flag occurrence consumes **one** following argument as its value, -/// regardless of what it is (even if it looks like a flag). -/// This ensures the mask correctly claims the value slot; validation is -/// the `Pickable`'s responsibility. -/// -/// **Positional** — no flag prefix, matched by position. -/// -/// # Examples -/// -/// | Input | `on_match_one` | `on_match_all` | -/// |-------|----------------|----------------| -/// | `--name Alice` | `[0, 1]` (via Pickable tag) | `[0, 1]` | -/// | `--name=Alice` | `[0]` | `[0]` | -/// | `--val a --val b` | `[0, 1]` | `[0, 1, 2, 3]` | -/// -/// Args after `--` are ignored. -pub struct ArgMatcher; - -impl ArgMatcher { - /// Check whether `raw` matches `flag_str`, optionally with an inline value - /// separated by the style's value separator (`=` for Unix, `:` for PowerShell). - #[inline(always)] - fn matches(raw: &str, flag_str: &str, case_sensitive: bool, sep: char) -> bool { - let eq_match = - |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_match(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) - } - } - - /// Check whether the argument contains its value inline via the style's - /// value separator (eq mode), so no extra mask slot is needed. - #[inline(always)] - fn is_inline_value(raw: &str, flag_str: &str, sep: char) -> bool { - raw.len() > flag_str.len() && raw.as_bytes().get(flag_str.len()) == Some(&(sep as u8)) - } -} - -impl Matcher for ArgMatcher { - 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::matches(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 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 = possible_flags - .iter() - .any(|f| Self::matches(args[i].raw, f, style.case_sensitive, sep)); - - if matched { - let flag_str = possible_flags - .iter() - .find(|f| Self::matches(args[i].raw, f, style.case_sensitive, sep)) - .expect("already matched"); - - result.push(args[i].raw_idx); - - if !Self::is_inline_value(args[i].raw, flag_str, sep) { - if i + 1 < args.len() - // Don't consume `--` (end-of-options marker) as a value. - && end.is_none_or(|e| args[i + 1].raw_idx < e) - { - result.push(args[i + 1].raw_idx); - i += 2; - continue; - } - i += 1; - continue; - } - i += 1; - continue; - } - i += 1; - } - - result - } -} |
