aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeicao-CatilGrass <1992414357@qq.com>2026-06-01 19:16:28 +0800
committerWeicao-CatilGrass <1992414357@qq.com>2026-06-01 19:16:28 +0800
commitbfe10f7805b3edf4f69fd764c324dd6ddcb5609f (patch)
tree2acd30f79e606f6018a3f5293fd20bd1decb1ccd
parent7c86f55f5a3f497d566b64b32babbdc9c971c9f3 (diff)
Refactor flag argument macros for better performance
-rw-r--r--CHANGELOG.md3
-rw-r--r--mingling_core/src/program/flag.rs52
2 files changed, 26 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e7b9257..a888cc2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,7 +10,7 @@
#### Optimizations:
-None
+1. **\[core:flag\]** Refactored the `special_argument!` and `special_arguments!` macros to replace index‑based `while` loops with iterator `position` and `drain`, improving both performance and readability.
#### Features:
@@ -22,6 +22,7 @@ This macro wraps `::mingling::test::unpack_chain_process_result` to downcast a `
let result = some_chain_function(args).into();
let value: MyType = unpack_chain_process!(result, MyType);
```
+
2. **\[core\]** Refactored the built-in flag system in `BasicProgramSetup` into individual, reusable setup structs (`HelpFlagSetup`, `QuietFlagSetup`, `ConfirmFlagSetup`). These setups are now separate implementations of `ProgramSetup`, each with customizable flag aliases and `Default` implementations. `BasicProgramSetup` now composes them via `with_setup` instead of defining flags inline.
```rust
diff --git a/mingling_core/src/program/flag.rs b/mingling_core/src/program/flag.rs
index 13f6ea9..bc1c922 100644
--- a/mingling_core/src/program/flag.rs
+++ b/mingling_core/src/program/flag.rs
@@ -116,21 +116,15 @@ macro_rules! special_flag {
macro_rules! special_argument {
($args:expr, $flag:expr) => {{
let flag = $flag;
- let mut value: Option<String> = None;
- let mut i = 0;
- while i < $args.len() {
- if &$args[i] == flag {
- if i + 1 < $args.len() {
- value = Some($args[i + 1].clone());
- $args.remove(i + 1);
- $args.remove(i);
- } else {
- value = None;
- $args.remove(i);
- }
- break;
+ let mut value = None;
+ if let Some(pos) = $args.iter().position(|arg| arg == flag) {
+ if pos + 1 < $args.len() {
+ let mut drained = $args.drain(pos..=pos + 1);
+ drained.next();
+ value = drained.next();
+ } else {
+ $args.remove(pos);
}
- i += 1;
}
value
}};
@@ -142,21 +136,23 @@ macro_rules! special_arguments {
($args:expr, $flag:expr) => {{
let flag = $flag;
let mut values: Vec<String> = Vec::new();
- let mut i = 0;
- while i < $args.len() {
- if &$args[i] == flag {
- $args.remove(i);
- while i < $args.len() && (flag.is_empty() || !$args[i].starts_with('-')) {
- values.push($args[i].clone());
- $args.remove(i);
- }
- break;
- }
- i += 1;
- }
+
if flag.is_empty() {
- while !$args.is_empty() && !$args[0].starts_with('-') {
- values.push($args.remove(0));
+ let end = $args
+ .iter()
+ .position(|a| a.starts_with('-'))
+ .unwrap_or($args.len());
+ values.extend($args.drain(0..end));
+ } else {
+ if let Some(start) = $args.iter().position(|a| a == flag) {
+ let end = $args[start + 1..]
+ .iter()
+ .position(|a| a.starts_with('-'))
+ .map_or($args.len(), |p| start + 1 + p);
+
+ let mut drained = $args.drain(start..end);
+ drained.next();
+ values.extend(drained);
}
}
values