diff options
Diffstat (limited to 'arg_picker/src/pickable')
| -rw-r--r-- | arg_picker/src/pickable/multi_pickable.rs | 93 | ||||
| -rw-r--r-- | arg_picker/src/pickable/single_pickable.rs | 70 |
2 files changed, 0 insertions, 163 deletions
diff --git a/arg_picker/src/pickable/multi_pickable.rs b/arg_picker/src/pickable/multi_pickable.rs deleted file mode 100644 index 81d1571..0000000 --- a/arg_picker/src/pickable/multi_pickable.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Doc Not Optimize -use crate::{ - Pickable, PickerArg, PickerArgAttr, PickerArgResult, SinglePickable, TagPhaseContext, - matcher_needed::Matcher, - parselib::{MultiArgMatcher, ParserStyle}, -}; - -/// Boundary check for multi-value positional parameters. -/// -/// Determines whether a raw string marks the end of a multi-value -/// parameter's input range. -pub trait BoundaryCheck { - /// Returns `true` if `raw` indicates a boundary (i.e., the start of - /// a new parameter), stopping greedy collection. - fn check_boundary(raw: &str) -> bool; -} - -/// Trait for multi-value parameters. -/// -/// Implementors define how a sequence of raw strings is converted into -/// a single value, with an associated [`BoundaryCheck`] to control where -/// collection stops. -pub trait MultiPickableWithBoundary: Sized { - /// The boundary checker type that determines when to stop consuming - /// positional arguments. - type Checker: BoundaryCheck; - - /// Parse and collect multiple raw string values into `Self`. - /// - /// The caller should stop passing additional items once the - /// associated [`Checker`](Self::Checker) signals a boundary. - fn pick_multi(raw: Vec<String>) -> PickerArgResult<Self>; -} - -/// Marker: unit type that always accepts — no boundary. -pub struct NoBoundary; - -impl BoundaryCheck for NoBoundary { - #[inline] - fn check_boundary(_raw: &str) -> bool { - false - } -} - -/// `Vec<T>` is greedy — it takes everything with `NoBoundary`. -impl<T: SinglePickable> MultiPickableWithBoundary for Vec<T> { - type Checker = NoBoundary; - - fn pick_multi(raw: Vec<String>) -> PickerArgResult<Self> { - let mut result = Self::with_capacity(raw.len()); - for s in &raw { - match T::pick_single(Some(s)) { - PickerArgResult::Parsed(v) => result.push(v), - PickerArgResult::NotFound => return PickerArgResult::NotFound, - PickerArgResult::Unparsed => {} - } - } - PickerArgResult::Parsed(result) - } -} - -/// If the first raw string looks like a named flag (starts with the -/// style's long or short prefix), strip it — it's the flag, not a value. -fn strip_flag<'a>(raw_strs: &'a [&'a str]) -> &'a [&'a str] { - if let Some(first) = raw_strs.first() { - let style = ParserStyle::global_style(); - if first.starts_with(style.long_prefix) || first.starts_with(style.short_prefix) { - return &raw_strs[1..]; - } - } - raw_strs -} - -// Pickable impl for Vec<T> - -impl<'a, T> Pickable<'a> for Vec<T> -where - T: SinglePickable, -{ - fn get_attr(flag: &'a PickerArg<'a, Self>) -> PickerArgAttr { - PickerArgAttr::positional_or_multi(flag) - } - - fn tag(ctx: TagPhaseContext) -> Vec<usize> { - MultiArgMatcher::match_all(ctx.into()) - } - - fn pick(raw_strs: &[&str]) -> PickerArgResult<Self> { - let strs = strip_flag(raw_strs); - let owned: Vec<String> = strs.iter().map(|&s| s.to_string()).collect(); - <Self as MultiPickableWithBoundary>::pick_multi(owned) - } -} diff --git a/arg_picker/src/pickable/single_pickable.rs b/arg_picker/src/pickable/single_pickable.rs deleted file mode 100644 index d916bcc..0000000 --- a/arg_picker/src/pickable/single_pickable.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Doc Not Optimize -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), - } - } -} |
