1use crate::error::{CommonError, Result};
4
5pub fn parse_option(option: &str) -> Result<Vec<String>> {
18 shell_words::split(option)
19 .map_err(|e| CommonError::ShellParse(format!("Failed to parse option '{option}': {e}")))
20}
21
22pub fn parse_options(options: &[String]) -> Result<Vec<String>> {
24 let mut result = Vec::new();
25 for option in options {
26 result.extend(parse_option(option)?);
27 }
28 Ok(result)
29}
30
31pub fn has_flag(args: &[String], flag: &str) -> bool {
33 args.iter().any(|arg| arg == flag)
34}
35
36pub fn get_flag_value(args: &[String], flag: &str) -> Option<String> {
39 let mut iter = args.iter();
40 while let Some(arg) = iter.next() {
41 if arg == flag {
42 return iter.next().cloned();
43 }
44 }
45 None
46}
47
48pub fn remove_flag(args: &mut Vec<String>, flag: &str) -> Option<String> {
50 if let Some(pos) = args.iter().position(|arg| arg == flag) {
51 args.remove(pos);
52 if pos < args.len() {
53 Some(args.remove(pos))
54 } else {
55 None
56 }
57 } else {
58 None
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_parse_option() {
68 assert_eq!(
69 parse_option("--features foo").unwrap(),
70 vec!["--features", "foo"]
71 );
72
73 assert_eq!(
74 parse_option("--message \"hello world\"").unwrap(),
75 vec!["--message", "hello world"]
76 );
77 }
78
79 #[test]
80 fn test_has_flag() {
81 let args = vec!["--release".to_string(), "--verbose".to_string()];
82 assert!(has_flag(&args, "--release"));
83 assert!(!has_flag(&args, "--debug"));
84 }
85
86 #[test]
87 fn test_get_flag_value() {
88 let args = vec![
89 "--features".to_string(),
90 "foo".to_string(),
91 "--target".to_string(),
92 "wasm32".to_string(),
93 ];
94 assert_eq!(get_flag_value(&args, "--features"), Some("foo".to_string()));
95 assert_eq!(
96 get_flag_value(&args, "--target"),
97 Some("wasm32".to_string())
98 );
99 assert_eq!(get_flag_value(&args, "--missing"), None);
100 }
101}