diff options
Diffstat (limited to 'arg_picker')
| -rw-r--r-- | arg_picker/Cargo.toml | 3 | ||||
| -rw-r--r-- | arg_picker/src/arg.rs | 31 | ||||
| -rw-r--r-- | arg_picker/src/constants.rs | 16 | ||||
| -rw-r--r-- | arg_picker/src/infos.rs | 75 | ||||
| -rw-r--r-- | arg_picker/src/lib.rs | 11 | ||||
| -rw-r--r-- | arg_picker/src/pickable/multi_pickable.rs | 16 | ||||
| -rw-r--r-- | arg_picker/src/picker.rs | 74 | ||||
| -rw-r--r-- | arg_picker/src/value/vec_until.rs | 1 |
8 files changed, 202 insertions, 25 deletions
diff --git a/arg_picker/Cargo.toml b/arg_picker/Cargo.toml index 913719e..d87a844 100644 --- a/arg_picker/Cargo.toml +++ b/arg_picker/Cargo.toml @@ -8,6 +8,9 @@ authors = ["Weicao-CatilGrass"] readme = "README.md" description = "A lightweight, type-safe CLI argument parser" +[features] +mingling_support = ["arg-picker-macros/mingling_support"] + [dependencies] arg-picker-macros.workspace = true just_fmt.workspace = true diff --git a/arg_picker/src/arg.rs b/arg_picker/src/arg.rs index a352418..4fa21b5 100644 --- a/arg_picker/src/arg.rs +++ b/arg_picker/src/arg.rs @@ -1,4 +1,4 @@ -use crate::Pickable; +use crate::{Pickable, PickerArgInfo}; use std::marker::PhantomData; /// Represents a constraint definition for a parameter selection. @@ -133,6 +133,35 @@ where self.positional = positional; self } + + /// Converts this `PickerArg` into a `PickerArgInfo` value. + /// + /// This is a convenience method equivalent to calling `PickerArgInfo::from(self)`. + pub fn into_info(self) -> PickerArgInfo<'a> { + let value = self; + let (long, alias) = match value.full.len() { + 0 => (None, None), + _ => { + let long = Some(value.full[0]); + let alias = if value.full.len() > 1 { + Some(value.full[1..].to_vec()) + } else { + None + }; + (long, alias) + } + }; + + PickerArgInfo { + short: value.short, + long, + alias, + positional: value.positional, + optional: false, + multi: false, + is_flag: false, + } + } } /// Describes the attribute (behavior) of a command-line parameter. diff --git a/arg_picker/src/constants.rs b/arg_picker/src/constants.rs new file mode 100644 index 0000000..39250f8 --- /dev/null +++ b/arg_picker/src/constants.rs @@ -0,0 +1,16 @@ +use std::marker::PhantomData; + +use crate::{PickerArg, PickerArgs}; + +/// Remaining positional arguments (anything not consumed as an option). +/// - `full`: `[]` (empty — not triggered by any `--` prefix). +/// - `short`: (none) +/// - `positional`: `false` (this is a meta‑argument that collects everything left). +/// This constant is used internally to access any leftover arguments after +/// all defined flags/options have been processed. +pub const REMAINS: PickerArg<PickerArgs> = PickerArg::<PickerArgs> { + full: &[], + short: None, + positional: false, + internal_type: PhantomData, +}; diff --git a/arg_picker/src/infos.rs b/arg_picker/src/infos.rs index 074539a..c17b6a2 100644 --- a/arg_picker/src/infos.rs +++ b/arg_picker/src/infos.rs @@ -1,4 +1,4 @@ -use crate::{Pickable, PickerArg}; +use crate::{Pickable, PickerArg, parselib::ParserStyle}; /// Represents the result of parsing or looking up a value. /// @@ -288,28 +288,7 @@ where T: Pickable<'a>, { fn from(value: PickerArg<'a, T>) -> Self { - let (long, alias) = match value.full.len() { - 0 => (None, None), - _ => { - let long = Some(value.full[0]); - let alias = if value.full.len() > 1 { - Some(value.full[1..].to_vec()) - } else { - None - }; - (long, alias) - } - }; - - Self { - short: value.short, - long, - alias, - positional: value.positional, - optional: false, - multi: false, - is_flag: false, - } + value.into_info() } } @@ -437,6 +416,56 @@ impl<'a> PickerArgInfo<'a> { self.is_flag = is_flag; self } + + /// Returns the short flag string, e.g. `-n` for short `n`. + /// + /// Uses [`ParserStyle::global_style()`] to format the flag. + /// + /// # Returns + /// + /// - `Some(String)` if `self.short` is set. + /// - `None` if `self.short` is `None`. + /// + /// # Examples + /// + /// ``` + /// use arg_picker::PickerArgInfo; + /// + /// let info = PickerArgInfo::new().with_short('n'); + /// assert_eq!(info.short_flag(), Some("-n".to_string())); + /// + /// let info = PickerArgInfo::new(); + /// assert_eq!(info.short_flag(), None); + /// ``` + pub fn short_flag(&self) -> Option<String> { + let short = self.short?; + Some(ParserStyle::global_style().flag_string(short)) + } + + /// Returns the long flag string, e.g. `--name` for long `"name"`. + /// + /// Uses [`ParserStyle::global_style()`] to format the flag. + /// + /// # Returns + /// + /// - `Some(String)` if `self.long` is set. + /// - `None` if `self.long` is `None`. + /// + /// # Examples + /// + /// ``` + /// use arg_picker::PickerArgInfo; + /// + /// let info = PickerArgInfo::new().with_long("name"); + /// assert_eq!(info.long_flag(), Some("--name".to_string())); + /// + /// let info = PickerArgInfo::new(); + /// assert_eq!(info.long_flag(), None); + /// ``` + pub fn long_flag(&self) -> Option<String> { + let long = self.long?; + Some(ParserStyle::global_style().flag_string(long)) + } } impl<'a> Default for PickerArgInfo<'a> { diff --git a/arg_picker/src/lib.rs b/arg_picker/src/lib.rs index c65e793..d292826 100644 --- a/arg_picker/src/lib.rs +++ b/arg_picker/src/lib.rs @@ -1,4 +1,5 @@ #![doc = include_str!("../README.md")] +#![deny(missing_docs)] mod builtin; @@ -48,3 +49,13 @@ pub mod matcher_needed { pub use crate::PickerArgInfo; pub use crate::parselib::{MaskedArg, Matcher, ParserStyle}; } + +mod constants; + +/// Re-export of constants used by `arg-picker`. +/// +/// This module provides access to various constants defined internally, such as +/// default values, configuration limits, and other static parameters. +pub mod consts { + pub use crate::constants::*; +} diff --git a/arg_picker/src/pickable/multi_pickable.rs b/arg_picker/src/pickable/multi_pickable.rs index 84a8068..404c23b 100644 --- a/arg_picker/src/pickable/multi_pickable.rs +++ b/arg_picker/src/pickable/multi_pickable.rs @@ -5,13 +5,29 @@ use crate::{ }; /// 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>; } diff --git a/arg_picker/src/picker.rs b/arg_picker/src/picker.rs index f31a5b6..f722fb5 100644 --- a/arg_picker/src/picker.rs +++ b/arg_picker/src/picker.rs @@ -369,11 +369,83 @@ pub trait IntoPicker<'a> { fn pick<N>(self, arg: impl Into<&'a PickerArg<'a, N>>) -> PickerPattern1<'a, N, ()> where Self: Sized, - N: Pickable<'a> + Default + Sized, + N: Pickable<'a> + Sized, { Picker::build_pattern1(self.to_picker().args, arg.into(), None::<()>) } + /// Starts building a picker pattern with the first argument, using a default value provider. + /// + /// This is a shorthand for calling `.pick(arg).or(func)`. + /// + /// # Type Parameters + /// + /// * `Next` — The nominal type of the first argument; must implement [`Pickable`]. + /// + /// # Parameters + /// + /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`]. + /// * `func` — A closure that provides a default value if the arg is not provided by the user. + fn pick_or<Next, F>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + func: F, + ) -> PickerPattern1<'a, Next, ()> + where + Self: Sized, + Next: Pickable<'a> + Sized, + F: FnMut() -> Next + 'static, + { + self.pick(arg).or(func) + } + + /// Starts building a picker pattern with the first argument, using a default value. + /// + /// This is a shorthand for calling `.pick(arg).or_default()`. + /// + /// # Type Parameters + /// + /// * `Next` — The nominal type of the first argument; must implement [`Pickable`] and [`Default`]. + /// + /// # Parameters + /// + /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`]. + fn pick_or_default<Next>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + ) -> PickerPattern1<'a, Next, ()> + where + Self: Sized, + Next: Pickable<'a> + Default + Sized, + { + self.pick(arg).or_default() + } + + /// Starts building a picker pattern with the first argument, using a route if the arg is not provided. + /// + /// This is a shorthand for calling `.pick(arg).or_route(func)`. + /// + /// # Type Parameters + /// + /// * `Next` — The nominal type of the first argument; must implement [`Pickable`]. + /// + /// # Parameters + /// + /// * `arg` — The argument definition, typically obtained from [`crate::macros::arg`]. + /// * `func` — A closure that produces a route value if the arg is not provided by the user. + fn pick_or_route<Next, F, Route>( + self, + arg: impl Into<&'a PickerArg<'a, Next>>, + func: F, + ) -> PickerPattern1<'a, Next, Route> + where + Self: Sized, + Next: Pickable<'a> + Sized, + F: FnMut() -> Route + 'static, + { + self.pick(arg).with_route::<Route>().or_route(func) + } + /// Converts the value into a `Picker` with a specified route type. /// /// This method allows changing the route (phantom type parameter) of the picker. diff --git a/arg_picker/src/value/vec_until.rs b/arg_picker/src/value/vec_until.rs index 1b79641..04d87ce 100644 --- a/arg_picker/src/value/vec_until.rs +++ b/arg_picker/src/value/vec_until.rs @@ -21,6 +21,7 @@ pub struct VecUntil<T> { } impl<T> VecUntil<T> { + /// Consumes `self` and returns the underlying [`Vec<T>`]. pub fn into_inner(self) -> Vec<T> { self.inner } |
