aboutsummaryrefslogtreecommitdiff
path: root/mingling_picker/src/builtin/pick_string.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-16 19:58:30 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-16 19:58:30 +0800
commit81049b3abd83115374cfc51b26fb5d5054263f81 (patch)
treebea8e56ebacf96d685b545bc7ea3c8d152910bf9 /mingling_picker/src/builtin/pick_string.rs
parent4f4a61d493547660260a5aa1db1af8a6ec42bbb6 (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.rs48
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())
+ }
+ }
+ }
+}