Skip to main content

killswitch/cli/dispatch/
mod.rs

1use crate::cli::{actions::Action, verbosity::Verbosity};
2use anyhow::Result;
3use clap::ArgMatches;
4
5/// Convert CLI arguments to an Action
6///
7/// # Errors
8/// Returns an error if no action is specified or if arguments are invalid
9pub fn handler(matches: &ArgMatches, verbose: Verbosity) -> Result<Action> {
10    let enable = matches.get_flag("enable");
11    let disable = matches.get_flag("disable");
12    let status = matches.get_flag("status");
13    let print = matches.get_flag("print");
14
15    if enable {
16        let ipv4 = matches.get_one::<String>("ipv4").map(String::from);
17        let leak = matches.get_flag("leak");
18        let local = matches.get_flag("local");
19
20        if print {
21            Ok(Action::Print {
22                ipv4,
23                leak,
24                local,
25                verbose,
26            })
27        } else {
28            Ok(Action::Enable {
29                ipv4,
30                leak,
31                local,
32                verbose,
33            })
34        }
35    } else if disable {
36        Ok(Action::Disable { verbose })
37    } else if status {
38        Ok(Action::Status { verbose })
39    } else if print {
40        let ipv4 = matches.get_one::<String>("ipv4").map(String::from);
41        let leak = matches.get_flag("leak");
42        let local = matches.get_flag("local");
43        Ok(Action::Print {
44            ipv4,
45            leak,
46            local,
47            verbose,
48        })
49    } else {
50        Ok(Action::ShowInterfaces { verbose })
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use crate::cli::commands;
58
59    #[allow(clippy::unwrap_used)]
60    #[test]
61    fn test_handler_enable() {
62        use crate::cli::verbosity::Verbosity;
63        let matches = commands::new().get_matches_from(vec!["killswitch", "--enable"]);
64        let action = handler(&matches, Verbosity::Normal).unwrap();
65        assert!(matches!(action, Action::Enable { .. }));
66    }
67
68    #[allow(clippy::unwrap_used)]
69    #[test]
70    fn test_handler_disable() {
71        use crate::cli::verbosity::Verbosity;
72        let matches = commands::new().get_matches_from(vec!["killswitch", "-d"]);
73        let action = handler(&matches, Verbosity::Normal).unwrap();
74        assert!(matches!(action, Action::Disable { .. }));
75    }
76
77    #[allow(clippy::unwrap_used)]
78    #[test]
79    fn test_handler_status() {
80        use crate::cli::verbosity::Verbosity;
81        let matches = commands::new().get_matches_from(vec!["killswitch", "--status"]);
82        let action = handler(&matches, Verbosity::Normal).unwrap();
83        assert!(matches!(action, Action::Status { .. }));
84    }
85
86    #[allow(clippy::unwrap_used)]
87    #[test]
88    fn test_handler_print() {
89        use crate::cli::verbosity::Verbosity;
90        let matches = commands::new().get_matches_from(vec!["killswitch", "--print"]);
91        let action = handler(&matches, Verbosity::Normal).unwrap();
92        assert!(matches!(action, Action::Print { .. }));
93    }
94
95    #[allow(clippy::unwrap_used, clippy::panic)]
96    #[test]
97    fn test_handler_enable_with_options() {
98        use crate::cli::verbosity::Verbosity;
99        let matches = commands::new().get_matches_from(vec![
100            "killswitch",
101            "-e",
102            "--local",
103            "--leak",
104            "--ipv4",
105            "10.0.0.1",
106        ]);
107        let action = handler(&matches, Verbosity::Normal).unwrap();
108        if let Action::Enable {
109            ipv4,
110            leak,
111            local,
112            verbose: _,
113        } = action
114        {
115            assert_eq!(ipv4, Some("10.0.0.1".to_string()));
116            assert!(leak);
117            assert!(local);
118        } else {
119            panic!("Expected Action::Enable");
120        }
121    }
122
123    #[allow(clippy::unwrap_used)]
124    #[test]
125    fn test_handler_no_action() {
126        use crate::cli::verbosity::Verbosity;
127        let matches = commands::new().get_matches_from(vec!["killswitch"]);
128        let result = handler(&matches, Verbosity::Normal);
129        assert!(result.is_ok());
130        assert!(matches!(result.unwrap(), Action::ShowInterfaces { .. }));
131    }
132}