summaryrefslogtreecommitdiff
path: root/mingling_core
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-04-04 17:52:19 +0800
committer魏曹先生 <1992414357@qq.com>2026-04-04 17:52:19 +0800
commitf0475c2207181c13dabcd4e78a163cde70573ade (patch)
treec659e766f038e8a609d174c4eba85be12791cdd7 /mingling_core
parent15028700581ee15d60e0fdbc28aa8ace539ad293 (diff)
Add vector pickers
Diffstat (limited to 'mingling_core')
-rw-r--r--mingling_core/Cargo.lock2
-rw-r--r--mingling_core/Cargo.toml2
-rw-r--r--mingling_core/src/program/flag.rs320
3 files changed, 322 insertions, 2 deletions
diff --git a/mingling_core/Cargo.lock b/mingling_core/Cargo.lock
index 5def9e6..a938576 100644
--- a/mingling_core/Cargo.lock
+++ b/mingling_core/Cargo.lock
@@ -16,7 +16,7 @@ checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e"
[[package]]
name = "mingling_core"
-version = "0.1.2"
+version = "0.1.3"
dependencies = [
"just_fmt",
"serde",
diff --git a/mingling_core/Cargo.toml b/mingling_core/Cargo.toml
index 40b4c41..4660f78 100644
--- a/mingling_core/Cargo.toml
+++ b/mingling_core/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "mingling_core"
-version = "0.1.2"
+version = "0.1.3"
edition = "2024"
license = "MIT OR Apache-2.0"
description = "Core of the mingling library"
diff --git a/mingling_core/src/program/flag.rs b/mingling_core/src/program/flag.rs
index a520495..edc3dfd 100644
--- a/mingling_core/src/program/flag.rs
+++ b/mingling_core/src/program/flag.rs
@@ -131,6 +131,326 @@ macro_rules! special_argument {
}};
}
+#[macro_export]
+#[doc(hidden)]
+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() && !$args[i].starts_with('-') {
+ values.push($args[i].clone());
+ $args.remove(i);
+ }
+ break;
+ }
+ i += 1;
+ }
+ values
+ }};
+}
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn test_special_flag() {
+ // Test flag found and removed
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--help".to_string(),
+ "c".to_string(),
+ ];
+ let result = special_flag!(args, "--help");
+ assert!(result);
+ assert_eq!(args, vec!["a", "b", "c"]);
+
+ // Test flag found at beginning
+ let mut args = vec![
+ "--help".to_string(),
+ "a".to_string(),
+ "b".to_string(),
+ "c".to_string(),
+ ];
+ let result = special_flag!(args, "--help");
+ assert!(result);
+ assert_eq!(args, vec!["a", "b", "c"]);
+
+ // Test flag found at end
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "c".to_string(),
+ "--help".to_string(),
+ ];
+ let result = special_flag!(args, "--help");
+ assert!(result);
+ assert_eq!(args, vec!["a", "b", "c"]);
+
+ // Test flag not found
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--other".to_string(),
+ "c".to_string(),
+ ];
+ let result = special_flag!(args, "--help");
+ assert!(!result);
+ assert_eq!(args, vec!["a", "b", "--other", "c"]);
+
+ // Test multiple same flags all removed
+ let mut args = vec![
+ "--help".to_string(),
+ "a".to_string(),
+ "--help".to_string(),
+ "b".to_string(),
+ "--help".to_string(),
+ ];
+ let result = special_flag!(args, "--help");
+ assert!(result);
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test empty args
+ let mut args: Vec<String> = Vec::new();
+ let result = special_flag!(args, "--help");
+ assert!(!result);
+ assert_eq!(args, Vec::<String>::new());
+
+ // Test flag with empty string
+ let mut args = vec!["a".to_string(), "".to_string(), "b".to_string()];
+ let result = special_flag!(args, "");
+ assert!(result);
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test flag with dash in middle
+ let mut args = vec!["a".to_string(), "test-flag".to_string(), "b".to_string()];
+ let result = special_flag!(args, "test-flag");
+ assert!(result);
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test flag that's a substring of another flag (should not match)
+ let mut args = vec!["a".to_string(), "--helpful".to_string(), "b".to_string()];
+ let result = special_flag!(args, "--help");
+ assert!(!result);
+ assert_eq!(args, vec!["a", "--helpful", "b"]);
+ }
+
+ #[test]
+ fn test_special_argument() {
+ // Test extracting value after flag
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--file".to_string(),
+ "test.txt".to_string(),
+ "c".to_string(),
+ ];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, Some("test.txt".to_string()));
+ assert_eq!(args, vec!["a", "b", "c"]);
+
+ // Test extracting value when flag is at beginning
+ let mut args = vec![
+ "--file".to_string(),
+ "test.txt".to_string(),
+ "a".to_string(),
+ "b".to_string(),
+ ];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, Some("test.txt".to_string()));
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test extracting value when flag is at end
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--file".to_string(),
+ "test.txt".to_string(),
+ ];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, Some("test.txt".to_string()));
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test flag without value (at end)
+ let mut args = vec!["a".to_string(), "b".to_string(), "--file".to_string()];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, None);
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test flag without value (not at end)
+ let mut args = vec!["a".to_string(), "--file".to_string(), "b".to_string()];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, Some("b".to_string()));
+ assert_eq!(args, vec!["a"]);
+
+ // Test flag not found
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--other".to_string(),
+ "value".to_string(),
+ ];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, None);
+ assert_eq!(args, vec!["a", "b", "--other", "value"]);
+
+ // Test empty args
+ let mut args: Vec<String> = Vec::new();
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, None);
+ assert_eq!(args, Vec::<String>::new());
+
+ // Test multiple same flags (should only extract first)
+ let mut args = vec![
+ "--file".to_string(),
+ "first.txt".to_string(),
+ "--file".to_string(),
+ "second.txt".to_string(),
+ ];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, Some("first.txt".to_string()));
+ assert_eq!(args, vec!["--file", "second.txt"]);
+
+ // Test flag with empty string value
+ let mut args = vec![
+ "a".to_string(),
+ "--file".to_string(),
+ "".to_string(),
+ "b".to_string(),
+ ];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, Some("".to_string()));
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test flag with value starting with dash
+ let mut args = vec![
+ "a".to_string(),
+ "--file".to_string(),
+ "-value".to_string(),
+ "b".to_string(),
+ ];
+ let result = special_argument!(args, "--file");
+ assert_eq!(result, Some("-value".to_string()));
+ assert_eq!(args, vec!["a", "b"]);
+ }
+
+ #[test]
+ fn test_special_arguments() {
+ // Test extracting multiple values after flag
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--list".to_string(),
+ "a".to_string(),
+ "b".to_string(),
+ "c".to_string(),
+ "d".to_string(),
+ "--next".to_string(),
+ "1".to_string(),
+ ];
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, vec!["a", "b", "c", "d"]);
+ assert_eq!(args, vec!["a", "b", "--next", "1"]);
+
+ // Test extracting single value
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--next".to_string(),
+ "1".to_string(),
+ ];
+ let result = special_arguments!(args, "--next");
+ assert_eq!(result, vec!["1"]);
+ assert_eq!(args, vec!["a", "b"]);
+
+ // Test extracting from beginning
+ let mut args = vec![
+ "--list".to_string(),
+ "a".to_string(),
+ "b".to_string(),
+ "--next".to_string(),
+ "1".to_string(),
+ ];
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, vec!["a", "b"]);
+ assert_eq!(args, vec!["--next", "1"]);
+
+ // Test extracting when no values after flag
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--list".to_string(),
+ "--next".to_string(),
+ "1".to_string(),
+ ];
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, Vec::<String>::new());
+ assert_eq!(args, vec!["a", "b", "--next", "1"]);
+
+ // Test extracting when flag not found
+ let mut args = vec![
+ "a".to_string(),
+ "b".to_string(),
+ "--list".to_string(),
+ "c".to_string(),
+ "d".to_string(),
+ ];
+ let result = special_arguments!(args, "--none");
+ assert_eq!(result, Vec::<String>::new());
+ assert_eq!(args, vec!["a", "b", "--list", "c", "d"]);
+
+ // Test extracting empty args
+ let mut args: Vec<String> = Vec::new();
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, Vec::<String>::new());
+ assert_eq!(args, Vec::<String>::new());
+
+ // Test extracting with only flag at end
+ let mut args = vec!["--list".to_string()];
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, Vec::<String>::new());
+ assert_eq!(args, Vec::<String>::new());
+
+ // Test extracting multiple values until end of args
+ let mut args = vec![
+ "--list".to_string(),
+ "a".to_string(),
+ "b".to_string(),
+ "c".to_string(),
+ ];
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, vec!["a", "b", "c"]);
+ assert_eq!(args, Vec::<String>::new());
+
+ // Test extracting with mixed non-dash values
+ let mut args = vec![
+ "--list".to_string(),
+ "value1".to_string(),
+ "value2".to_string(),
+ "-next".to_string(),
+ "value3".to_string(),
+ ];
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, vec!["value1", "value2"]);
+ assert_eq!(args, vec!["-next", "value3"]);
+
+ // Test extracting with single dash values
+ let mut args = vec![
+ "--list".to_string(),
+ "-a".to_string(),
+ "-b".to_string(),
+ "--next".to_string(),
+ "1".to_string(),
+ ];
+ let result = special_arguments!(args, "--list");
+ assert_eq!(result, Vec::<String>::new());
+ assert_eq!(args, vec!["-a", "-b", "--next", "1"]);
+ }
+}
+
impl<C, G> Program<C, G>
where
C: ProgramCollect,