From 559ff1a4d5d164c2fdbc29a9957e3db38651705f Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Wed, 15 Jul 2026 03:52:25 +0800 Subject: refactor(pickable): redesign Pickable trait with two-phase parse API Introduce `get_attr`, `tag`, and `pick` as the new trait methods, replacing the single `tag` method that returned a `PickerTag`. This enables the parser to first collect all argument position requirements and then resolve them in a second pass. Rename `PickerTag` to `PickerArgInfo` and reorder `PickerFlagAttr` variants to reflect parse priority (`Positional < Flag < Single < Multi`). Add `positional_or_else` helper to `PickerFlagAttr`. --- mingling_picker/src/flag.rs | 54 ++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'mingling_picker/src/flag.rs') diff --git a/mingling_picker/src/flag.rs b/mingling_picker/src/flag.rs index 3fa3dc1..aebbc81 100644 --- a/mingling_picker/src/flag.rs +++ b/mingling_picker/src/flag.rs @@ -123,31 +123,49 @@ where /// Describes the attribute (behavior) of a command-line parameter. /// -/// This enum specifies how a parameter is parsed and processed: -/// -/// - `Single`: The parameter accepts a single value. For example, `--name Alice`. -/// -/// - `Multi`: The parameter accepts multiple values. For example, `--file a.txt --file b.txt`. -/// -/// - `Flag`: The parameter is a boolean flag with no associated value. -/// For example, `--verbose` sets a flag to `true`. -/// -/// - `Positional`: The parameter is matched by its position in the command line, -/// without requiring a `--name` or `-n` flag. For example, an input filename as the first argument. +/// The ordering reflects parse priority (higher = parsed first): +/// `Positional < Flag < Single < Multi` #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum PickerFlagAttr { - /// Accepts multiple values (e.g., `--file a.txt --file b.txt`). - Multi, + /// Positional argument matched by its position (e.g., an input file). + #[default] + Positional, + + /// Boolean flag with no associated value (e.g., `--verbose`). + Flag, /// Accepts a single value (e.g., `--name Alice`). Single, - /// Boolean flag with no associated value (e.g., `--verbose`). - Flag, + /// Accepts multiple values (e.g., `--file a.txt --file b.txt`). + Multi, +} - /// Positional argument matched by its position (e.g., an input file). - #[default] - Positional, +impl PickerFlagAttr { + /// Determines if the given `PickerFlag` represents a positional parameter. + /// + /// If the flag is positional (determined by `flag.is_positional()`), returns + /// `PickerFlagAttr::Positional`. Otherwise, invokes the `other` closure to + /// produce and return a `PickerFlagAttr`. + /// + /// # Parameters + /// + /// - `flag`: A reference to the [`PickerFlag`] to evaluate. + /// - `other`: A closure that returns a [`PickerFlagAttr`] when the flag is + /// **not** positional. + pub fn positional_or_else<'a, T>( + flag: &PickerFlag<'a, T>, + other: fn() -> PickerFlagAttr, + ) -> PickerFlagAttr + where + T: Pickable<'a> + Default, + { + if flag.is_positional() { + PickerFlagAttr::Positional + } else { + other() + } + } } #[cfg(test)] -- cgit