diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-16 19:58:30 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-16 19:58:30 +0800 |
| commit | 81049b3abd83115374cfc51b26fb5d5054263f81 (patch) | |
| tree | bea8e56ebacf96d685b545bc7ea3c8d152910bf9 /mingling_picker/src/builtin/pick_string.rs | |
| parent | 4f4a61d493547660260a5aa1db1af8a6ec42bbb6 (diff) | |
feat(picker): add string value support with inline value matching
Implement `Pickable` for `String` supporting both positional and named
flags, and generalize value matching to use style-specific separators
Diffstat (limited to 'mingling_picker/src/builtin/pick_string.rs')
| -rw-r--r-- | mingling_picker/src/builtin/pick_string.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/mingling_picker/src/builtin/pick_string.rs b/mingling_picker/src/builtin/pick_string.rs new file mode 100644 index 0000000..688ac0a --- /dev/null +++ b/mingling_picker/src/builtin/pick_string.rs @@ -0,0 +1,48 @@ +use crate::parselib::{ArgMatcher, Matcher, ParserStyle}; +use crate::pickable_needed::*; + +impl<'a> Pickable<'a> for String { + fn get_attr(flag: &'a PickerArg<'a, Self>) -> PickerArgAttr { + PickerArgAttr::positional_or_single(flag) + } + + fn tag(ctx: TagPhaseContext) -> Vec<usize> { + if ctx.arg_info.positional { + // Positional: take the first available position only. + ArgMatcher::match_one(ctx.into()) + .map(|i| vec![i]) + .unwrap_or_default() + } else { + // Named: find each flag + its single value. + ArgMatcher::match_all(ctx.into()) + } + } + + fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> { + match raw_strs.len() { + 0 => PickerArgResult::NotFound, + 1 => { + let s = raw_strs[0]; + let style = ParserStyle::global_style(); + + // Inline value via style separator (e.g., --name=Alice, -Name:Alice). + if let Some(pos) = s.rfind(style.value_separator) { + return PickerArgResult::Parsed(s[pos + 1..].to_string()); + } + + // If the single element looks like a named flag (starts with a prefix + // such as `--`, `-`, or `/`), it's a flag with no value → NotFound. + if s.starts_with(style.long_prefix) || s.starts_with(style.short_prefix) { + return PickerArgResult::NotFound; + } + + // Positional value. + PickerArgResult::Parsed(s.to_string()) + } + _ => { + // flag + value as separate args: take the second element. + PickerArgResult::Parsed(raw_strs[1].to_string()) + } + } + } +} |
