standout_dispatch/
dispatch.rs1use clap::ArgMatches;
2pub fn extract_command_path(matches: &ArgMatches) -> Vec<String> {
3 let mut path = Vec::new();
4 let mut current = matches;
5 while let Some((name, sub)) = current.subcommand() {
6 path.push(name.to_string());
7 current = sub;
8 }
9 path
10}
11pub fn get_deepest_matches(matches: &ArgMatches) -> &ArgMatches {
12 let mut current = matches;
13 while let Some((_, sub)) = current.subcommand() {
14 current = sub;
15 }
16 current
17}
18pub fn has_subcommand(matches: &ArgMatches) -> bool {
19 matches.subcommand().is_some()
20}
21pub fn insert_default_command<I, S>(args: I, command: &str) -> Vec<String>
22where
23 I: IntoIterator<Item = S>,
24 S: Into<String>,
25{
26 let mut result: Vec<String> = args.into_iter().map(Into::into).collect();
27 if !result.is_empty() {
28 result.insert(1, command.to_string());
29 } else {
30 result.push(command.to_string());
31 }
32 result
33}
34pub fn path_to_string(path: &[String]) -> String {
35 path.join(".")
36}
37pub fn string_to_path(s: &str) -> Vec<String> {
38 if s.is_empty() {
39 Vec::new()
40 } else {
41 s.split('.').map(String::from).collect()
42 }
43}
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use clap::Command;
48 #[test]
49 fn test_extract_command_path() {
50 let cmd =
51 Command::new("app").subcommand(Command::new("config").subcommand(Command::new("get")));
52 let matches = cmd.try_get_matches_from(["app", "config", "get"]).unwrap();
53 let path = extract_command_path(&matches);
54 assert_eq!(path, vec!["config", "get"]);
55 }
56 #[test]
57 fn test_extract_command_path_single() {
58 let cmd = Command::new("app").subcommand(Command::new("list"));
59 let matches = cmd.try_get_matches_from(["app", "list"]).unwrap();
60 let path = extract_command_path(&matches);
61 assert_eq!(path, vec!["list"]);
62 }
63 #[test]
64 fn test_extract_command_path_empty() {
65 let cmd = Command::new("app");
66 let matches = cmd.try_get_matches_from(["app"]).unwrap();
67 let path = extract_command_path(&matches);
68 assert!(path.is_empty());
69 }
70 #[test]
71 fn test_has_subcommand_true() {
72 let cmd = Command::new("app").subcommand(Command::new("list"));
73 let matches = cmd.try_get_matches_from(["app", "list"]).unwrap();
74 assert!(has_subcommand(&matches));
75 }
76 #[test]
77 fn test_has_subcommand_false() {
78 let cmd = Command::new("app").subcommand(Command::new("list"));
79 let matches = cmd.try_get_matches_from(["app"]).unwrap();
80 assert!(!has_subcommand(&matches));
81 }
82 #[test]
83 fn test_no_name_is_privileged() {
84 let cmd = Command::new("app")
85 .disable_help_subcommand(true)
86 .subcommand(Command::new("help"));
87 let matches = cmd.try_get_matches_from(["app", "help"]).unwrap();
88 assert!(has_subcommand(&matches));
89 assert_eq!(extract_command_path(&matches), vec!["help"]);
90 }
91 #[test]
92 fn test_insert_default_command() {
93 let args = vec!["myapp", "-v"];
94 let result = insert_default_command(args, "list");
95 assert_eq!(result, vec!["myapp", "list", "-v"]);
96 }
97 #[test]
98 fn test_insert_default_command_no_args() {
99 let args = vec!["myapp"];
100 let result = insert_default_command(args, "list");
101 assert_eq!(result, vec!["myapp", "list"]);
102 }
103 #[test]
104 fn test_insert_default_command_empty() {
105 let args: Vec<String> = vec![];
106 let result = insert_default_command(args, "list");
107 assert_eq!(result, vec!["list"]);
108 }
109 #[test]
110 fn test_path_to_string() {
111 assert_eq!(
112 path_to_string(&["db".into(), "migrate".into()]),
113 "db.migrate"
114 );
115 assert_eq!(path_to_string(&["list".into()]), "list");
116 assert_eq!(path_to_string(&[]), "");
117 }
118 #[test]
119 fn test_string_to_path() {
120 assert_eq!(string_to_path("db.migrate"), vec!["db", "migrate"]);
121 assert_eq!(string_to_path("list"), vec!["list"]);
122 assert_eq!(string_to_path(""), Vec::<String>::new());
123 }
124}