aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-08-03 14:46:37 +0800
committer魏曹先生 <1992414357@qq.com>2026-08-03 14:48:59 +0800
commit0ddfcbd044aa2a35f716f8d9b18c056dd6ec46af (patch)
tree4b26fa053cea41ef730c0da72f1d796ac785ef0f
parent52a448ca246d60f4cf88bdcde73bfed0f989c848 (diff)
refactor(picker): replace global picker functions with PickerHelper
trait
-rw-r--r--CHANGELOG.md8
-rw-r--r--mingling/src/picker/global.rs72
-rw-r--r--mingling/src/setups/picker/basic.rs8
-rw-r--r--mingling/src/setups/picker/structural_renderer.rs19
4 files changed, 72 insertions, 35 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6062103..acb3a1d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -235,6 +235,14 @@ None
_No behavioral changes — this is a pure rename of the internal fallback type and its associated `ProgramCollect` methods. The type's semantics, shape (wrapping `Vec<String>`), and rendering behavior are unchanged.
+3. **[`picker:global`]** **[`setups:picker`]** Refactored the global picker utility functions into a trait-based API. The standalone functions `pick_global_flag(program, flag)` and `pick_global_argument(program, arg)` in `mingling::picker` have been replaced by the `PickerHelper<C>` trait, implemented for `Program<C>`. This trait provides `pick_flag(&mut self, flag: &PickerArg<Flag>) -> bool` and `pick_argument<A>(&mut self, arg: &PickerArg<A>) -> Option<A>`, and is backed by the `take_args` / `replace_args` methods on `Program`.
+
+ **Migration guide:**
+
+ - `pick_global_flag(program, flag)` → `program.pick_flag(flag)`
+ - `pick_global_argument(program, arg)` → `program.pick_argument(arg)`
+ - Import `mingling::picker::PickerHelper` instead of `mingling::picker::{pick_global_flag, pick_global_argument}`
+
---
### Release 0.3.0 (2026-07-27)
diff --git a/mingling/src/picker/global.rs b/mingling/src/picker/global.rs
index c203524..f062671 100644
--- a/mingling/src/picker/global.rs
+++ b/mingling/src/picker/global.rs
@@ -3,33 +3,65 @@ use mingling_core::{Program, ProgramCollect};
use crate::consts::REMAINS;
-/// Picks a global flag from the program's arguments.
+/// Provides helper methods for picking arguments from a [`Program`]'s argument list.
///
-/// This function takes ownership of the program's current arguments, picks the specified `flag`
-/// from them, and then returns the remaining arguments back to the program. It returns the
-/// boolean value of the flag.
-pub fn pick_global_flag<C>(program: &mut Program<C>, flag: &PickerArg<Flag>) -> bool
+/// This trait abstracts the functionality of extracting specific arguments or flags
+/// from the program's current arguments, while restoring any remaining arguments
+/// back into the program.
+pub trait PickerHelper<C>
where
C: ProgramCollect<Enum = C>,
{
- let args = program.take_args();
- let (flag, args) = args.pick(flag).pick(&REMAINS).unwrap();
- program.replace_args(args.into());
- *flag
+ /// Takes ownership of the program's current arguments.
+ ///
+ /// Returns the program's argument list as a [`Vec<String>`], leaving the program
+ /// with no arguments until [`replace_args`] is called.
+ ///
+ /// [`replace_args`]: PickerHelper::replace_args
+ fn take_args(&mut self) -> Vec<String>;
+
+ /// Replaces the program's current arguments with the provided list.
+ ///
+ /// Returns the previous argument list that was replaced.
+ fn replace_args(&mut self, args: Vec<String>) -> Vec<String>;
+
+ /// Picks a flag from the program's arguments.
+ ///
+ /// This function takes ownership of the program's current arguments, picks the specified `flag`
+ /// from them, and then returns the remaining arguments back to the program. It returns the
+ /// boolean value of the flag.
+ fn pick_flag(&mut self, flag: &PickerArg<Flag>) -> bool {
+ let args = self.take_args();
+ let (flag, args) = args.pick(flag).pick(&REMAINS).unwrap();
+ self.replace_args(args.into());
+ *flag
+ }
+
+ /// Picks a argument from the program's arguments.
+ ///
+ /// This function takes ownership of the program's current arguments, picks the specified `arg`
+ /// from them, and then returns the remaining arguments back to the program. It returns the
+ /// picked argument value, or `None` if the argument was not present.
+ fn pick_argument<A>(&mut self, arg: &PickerArg<A>) -> Option<A>
+ where
+ A: for<'a> Pickable<'a> + Default,
+ {
+ let args = self.take_args();
+ let (arg, remains) = args.pick(arg).pick(&REMAINS).unpack();
+ self.replace_args(remains.unwrap().into());
+ arg
+ }
}
-/// Picks a global argument from the program's arguments.
-///
-/// This function takes ownership of the program's current arguments, picks the specified `arg`
-/// from them, and then returns the remaining arguments back to the program. It returns the
-/// picked argument value, or `None` if the argument was not present.
-pub fn pick_global_argument<C, A>(program: &mut Program<C>, arg: &PickerArg<A>) -> Option<A>
+impl<C> PickerHelper<C> for Program<C>
where
- A: for<'a> Pickable<'a> + Default,
C: ProgramCollect<Enum = C>,
{
- let args = program.take_args();
- let (arg, remains) = args.pick(arg).pick(&REMAINS).unpack();
- program.replace_args(remains.unwrap().into());
- arg
+ fn take_args(&mut self) -> Vec<String> {
+ self.take_args()
+ }
+
+ fn replace_args(&mut self, args: Vec<String>) -> Vec<String> {
+ self.replace_args(args)
+ }
}
diff --git a/mingling/src/setups/picker/basic.rs b/mingling/src/setups/picker/basic.rs
index c9f82b3..52bda3d 100644
--- a/mingling/src/setups/picker/basic.rs
+++ b/mingling/src/setups/picker/basic.rs
@@ -3,7 +3,7 @@ use mingling_core::{Program, ProgramCollect, setup::ProgramSetup};
use crate::{
consts::{CONFIRM_FLAG, HELP_FLAG, QUIET_FLAG},
- picker::pick_global_flag,
+ picker::PickerHelper,
};
/// Performs basic program initialization:
@@ -43,7 +43,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- let help = pick_global_flag(program, self.flag);
+ let help = program.pick_flag(self.flag);
if help {
program.user_context.help = true;
}
@@ -75,7 +75,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- let help = pick_global_flag(program, self.flag);
+ let help = program.pick_flag(self.flag);
if help {
program.stdout_setting.quiet = true;
}
@@ -107,7 +107,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- let help = pick_global_flag(program, self.flag);
+ let help = program.pick_flag(self.flag);
if help {
program.user_context.confirm = true;
}
diff --git a/mingling/src/setups/picker/structural_renderer.rs b/mingling/src/setups/picker/structural_renderer.rs
index 1fa48fd..91848e4 100644
--- a/mingling/src/setups/picker/structural_renderer.rs
+++ b/mingling/src/setups/picker/structural_renderer.rs
@@ -1,9 +1,6 @@
use mingling_core::{Program, ProgramCollect, setup::ProgramSetup};
-use crate::{
- consts::RENDERER_ARG,
- picker::{pick_global_argument, pick_global_flag},
-};
+use crate::{consts::RENDERER_ARG, picker::PickerHelper};
/// Sets up the structural renderer for the program:
///
@@ -15,7 +12,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- if let Some(renderer) = pick_global_argument(program, &RENDERER_ARG) {
+ if let Some(renderer) = program.pick_argument(&RENDERER_ARG) {
program.structural_renderer_name = renderer.into();
}
}
@@ -49,27 +46,27 @@ where
{
fn setup(self, program: &mut Program<C>) {
#[cfg(feature = "json_serde_fmt")]
- if pick_global_flag(program, &crate::consts::JSON_FLAG) {
+ if program.pick_flag(&crate::consts::JSON_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Json;
}
#[cfg(feature = "json_serde_fmt")]
- if pick_global_flag(program, &crate::consts::JSON_PRETTY_FLAG) {
+ if program.pick_flag(&crate::consts::JSON_PRETTY_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::JsonPretty;
}
#[cfg(feature = "yaml_serde_fmt")]
- if pick_global_flag(program, &crate::consts::YAML_FLAG) {
+ if program.pick_flag(&crate::consts::YAML_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Yaml;
}
#[cfg(feature = "toml_serde_fmt")]
- if pick_global_flag(program, &crate::consts::TOML_FLAG) {
+ if program.pick_flag(&crate::consts::TOML_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Toml;
}
#[cfg(feature = "ron_serde_fmt")]
- if pick_global_flag(program, &crate::consts::RON_FLAG) {
+ if program.pick_flag(&crate::consts::RON_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Ron;
}
#[cfg(feature = "ron_serde_fmt")]
- if pick_global_flag(program, &crate::consts::RON_PRETTY_FLAG) {
+ if program.pick_flag(&crate::consts::RON_PRETTY_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::RonPretty;
}
}