diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-07-17 03:24:51 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-07-17 03:25:24 +0800 |
| commit | b9f208deed7b8e012fbcd84202e2fb1d5eb8eeb9 (patch) | |
| tree | 2e0f00651b0cff09a2f6bafd6ce35046532ffa81 /mingling_picker/src/pickable.rs | |
| parent | 8b2c209c2f111e0e208de5dde9df6c4bd3ea1052 (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.rs')
| -rw-r--r-- | mingling_picker/src/pickable.rs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/mingling_picker/src/pickable.rs b/mingling_picker/src/pickable.rs new file mode 100644 index 0000000..758ae9a --- /dev/null +++ b/mingling_picker/src/pickable.rs @@ -0,0 +1,91 @@ +use crate::{PickerArg, PickerArgAttr, PickerArgInfo, PickerArgResult, PickerArgs}; + +mod single_pickable; +pub use single_pickable::*; + +mod multi_pickable; +pub use multi_pickable::*; + +/// `Pickable` trait defines how to parse a type instance from command-line arguments. +/// +/// This trait is the core abstraction of the `Picker` argument parsing system, dividing the +/// parsing process into two phases: +/// +/// 1. **Tag phase ([`Pickable::tag`])**: Determines which argument positions the `Pickable` needs to handle. +/// 2. **Pick phase ([`Pickable::pick`])**: Converts the raw strings at the tagged positions into the actual type. +/// +/// Types implementing this trait must also implement [`Default`], so that a default value +/// can be used as a fallback when parsing fails. +/// +/// # Type Parameters +/// +/// * `'a` - Lifetime parameter, used to associate references in [`PickerArg`]. +pub trait Pickable<'a> +where + Self: Sized, +{ + /// Returns the parse-order attribute of this flag. + /// + /// This attribute is used to inform the parser about the parse order + /// between different `Pickable` types. + /// See [`PickerArgAttr`] for specific ordering definitions. + /// + /// # Parameters + /// + /// * `flag` - The current flag instance, which contains a reference to `Self`. + /// + /// # Returns + /// + /// Returns a [`PickerArgAttr`] describing the parse-order attribute of this flag. + fn get_attr(flag: &'a PickerArg<'a, Self>) -> PickerArgAttr; + + /// Tag phase: Determines which argument positions the `Pickable` needs to handle. + /// + /// This function receives a [`TagPhaseContext`] containing argument context information. + /// During this phase, the parser invokes each `Pickable` and collects the position indices + /// they return, in order to determine which arguments to parse later. + /// + /// # Parameters + /// + /// * `ctx` - The tag phase context, containing argument information, all parameters of the + /// current Picker, and an availability mask. + /// + /// # Returns + /// + /// Returns a `Vec<usize>` representing the indices of the arguments in the argument list + /// that this `Pickable` needs to handle. + fn tag(ctx: TagPhaseContext) -> Vec<usize>; + + /// Pick phase: Converts the raw string arguments tagged during the `tag` phase into + /// the actual expected type. + /// + /// This function receives a slice of the raw strings that were tagged in the `tag` step + /// and converts them into an instance of `Self`. + /// + /// # Parameters + /// + /// * `raw_strs` - A slice of strings containing the raw argument values to parse. + /// + /// # Returns + /// + /// Returns [`PickerArgResult<Self>`], i.e., the `Self` instance on success, or an appropriate + /// error message on failure. + fn pick(raw_strs: &[&str]) -> PickerArgResult<Self>; +} + +/// Tag phase context, providing the necessary argument and state information for +/// [`Pickable::tag`]. +pub struct TagPhaseContext<'a> { + /// Argument information describing the structure and metadata of the argument + /// to be parsed. + pub arg_info: &'a PickerArgInfo<'a>, + + /// A read-only list of all arguments in the current [`Picker`](crate::Picker). + pub args: &'a PickerArgs<'a>, + + /// Mask indicating which argument positions have already been claimed. + /// + /// For example, if the mask is `[0, 0, 1, 0]`, then the argument at index `2` + /// has already been tagged by another `Pickable`. + pub mask: &'a [u8], +} |
