aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-07-17 00:11:51 +0800
committer魏曹先生 <1992414357@qq.com>2026-07-17 00:11:51 +0800
commit3f653ba743d1fb22e662e28ec9532b0adf8e9ba2 (patch)
tree465257680a651baf7eb98587bc01da5098d3e458
parent2217cd356fe6ee5571c661a9aef3696547473c65 (diff)
feat(pickable): extract SinglePickable into its own module
-rw-r--r--mingling_picker/src/pickable.rs47
-rw-r--r--mingling_picker/src/pickable/single_pickable.rs69
2 files changed, 72 insertions, 44 deletions
diff --git a/mingling_picker/src/pickable.rs b/mingling_picker/src/pickable.rs
index 7424e6f..463edc0 100644
--- a/mingling_picker/src/pickable.rs
+++ b/mingling_picker/src/pickable.rs
@@ -1,5 +1,8 @@
use crate::{PickerArg, PickerArgAttr, PickerArgInfo, PickerArgResult, PickerArgs};
+mod single_pickable;
+pub use single_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
@@ -83,47 +86,3 @@ pub struct TagPhaseContext<'a> {
/// has already been tagged by another `Pickable`.
pub mask: &'a [u8],
}
-
-/// `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.
-///
-/// # 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))
- }
-}
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),
+ }
+ }
+}