aboutsummaryrefslogtreecommitdiff
path: root/mingling_picker/src/pickable/single_pickable.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-17 03:24:51 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-17 03:25:24 +0800
commitb9f208deed7b8e012fbcd84202e2fb1d5eb8eeb9 (patch)
tree2e0f00651b0cff09a2f6bafd6ce35046532ffa81 /mingling_picker/src/pickable/single_pickable.rs
parent8b2c209c2f111e0e208de5dde9df6c4bd3ea1052 (diff)
feat(picker2): complete Picker2 prototype
Picker2 replaces the original Picker1 with a two-phase (tag → pick) + mask-bitmap architecture, decoupling argument matching from type conversion via a composable matcher pipeline. Architecture - FlagMatcher — boolean flags (--verbose) - ArgMatcher — single flag+value pairs (--name Alice) - MultiArgMatcher — multi-value flag groups (--files a.txt b.txt) - PositionalMatcher — positional arguments, respects `--` - SingleMatcher — composite for Single-type Pickables Types - Flag (Active/Inactive) — semantic bool flag value - String + 14 numeric types via SinglePickable trait - Vec<T> — greedy multi-value (all SinglePickable types) - VecUntil<T> — bounded multi-value via BoundaryCheck trait - VecUntil<T>, pick_string, pick_numbers, pick_bool, pick_flag Style system - UNIX_STYLE (kebab), POWERSHELL_STYLE (Pascal), WINDOWS_STYLE (Pascal) - naming_case auto-conversion via just_fmt integration - Style-aware separator (= for Unix, : for PS/Windows) Infrastructure - internal_repeat! macro generates PickerPattern1..=32 - SinglePickable blanket impl → Pickable - MultiPickableWithBoundary trait with greedy/bounded variants - 151 integration tests - Docs updated for parser feature
Diffstat (limited to 'mingling_picker/src/pickable/single_pickable.rs')
-rw-r--r--mingling_picker/src/pickable/single_pickable.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/mingling_picker/src/pickable/single_pickable.rs b/mingling_picker/src/pickable/single_pickable.rs
new file mode 100644
index 0000000..8a5b3e6
--- /dev/null
+++ b/mingling_picker/src/pickable/single_pickable.rs
@@ -0,0 +1,69 @@
+use crate::{Pickable, PickerArg, PickerArgAttr, PickerArgResult, TagPhaseContext};
+
+/// `SinglePickable` trait defines how to parse a type from a single command-line argument.
+///
+/// This trait provides a simplified interface for types that consume exactly one argument value.
+/// It is automatically implemented by the blanket `impl` of [`Pickable`], so types implementing
+/// `SinglePickable` will work with the full `Pickable` argument parsing system.
+///
+/// Additionally, `Option<S>` where `S: SinglePickable` also implements [`Pickable`], allowing
+/// optional arguments to be parsed naturally.
+///
+/// # Type Parameters
+///
+/// * `Self` - The type to be parsed from a single argument string.
+pub trait SinglePickable
+where
+ Self: Sized,
+{
+ /// Parse a single optional string value into an instance of `Self`.
+ ///
+ /// # Parameters
+ ///
+ /// * `str` - An `Option<&str>` representing the raw argument value. If `None`,
+ /// it indicates that no argument value was provided (e.g., for flag-like arguments).
+ ///
+ /// # Returns
+ ///
+ /// Returns [`PickerArgResult<Self>`], i.e., the parsed `Self` instance on success,
+ /// or an appropriate error message on failure.
+ fn pick_single(str: Option<&str>) -> PickerArgResult<Self>;
+}
+
+impl<'a, S> Pickable<'a> for S
+where
+ S: SinglePickable,
+{
+ fn get_attr(flag: &'a PickerArg<'a, Self>) -> PickerArgAttr {
+ PickerArgAttr::positional_or_single(flag)
+ }
+
+ fn tag(ctx: TagPhaseContext) -> Vec<usize> {
+ crate::parselib::SingleMatcher::tag(ctx)
+ }
+
+ fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> {
+ Self::pick_single(crate::parselib::seek_single(raw_strs))
+ }
+}
+
+impl<'a, S> Pickable<'a> for Option<S>
+where
+ S: SinglePickable,
+{
+ fn get_attr(flag: &'a PickerArg<'a, Self>) -> PickerArgAttr {
+ PickerArgAttr::positional_or_single(flag)
+ }
+
+ fn tag(ctx: TagPhaseContext) -> Vec<usize> {
+ crate::parselib::SingleMatcher::tag(ctx)
+ }
+
+ fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> {
+ match S::pick(raw_strs) {
+ PickerArgResult::Unparsed => PickerArgResult::Unparsed,
+ PickerArgResult::Parsed(r) => PickerArgResult::Parsed(Some(r)),
+ PickerArgResult::NotFound => PickerArgResult::Parsed(None),
+ }
+ }
+}