Skip to main content

standout_dispatch/
dispatch.rs

1use 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}