net_agent/
args.rs

1use clap::Parser;
2
3#[derive(Parser, Debug, Clone)]
4#[command(version, about, long_about = None)]
5pub struct Cli {
6    #[arg(short = 'D', long, conflicts_with_all = ["config_file"])]
7    pub device_name: Option<String>,
8    #[arg(short = 'N', long, conflicts_with_all = ["config_file"])]
9    pub number_packages: Option<u64>,
10    #[arg(short = 'B', long, conflicts_with_all = ["config_file"])]
11    pub buffer_size: Option<i32>,
12    #[arg(short = 'C', long, conflicts_with_all = ["device_name", "number_packages", "buffer_size"])]
13    pub config_file: Option<String>,
14    #[arg(short = 'O', long, default_value = "output", conflicts_with_all = ["config_file"])]
15    pub output_directory: Option<String>,
16}
17
18impl Cli {
19    pub fn is_config_missing(&self) -> bool {
20        self.config_file.is_none() &&
21        (
22            self.buffer_size.is_none() ||
23            self.device_name.is_none() ||
24            self.number_packages.is_none()
25        )
26    }
27
28    pub fn missing_fields_message(&self) -> String {
29        let mut missing_fields = Vec::new();
30
31        if self.buffer_size.is_none() {
32            missing_fields.push("buffer_size");
33        }
34        if self.device_name.is_none() {
35            missing_fields.push("device_name");
36        }
37        if self.number_packages.is_none() {
38            missing_fields.push("number_packages");
39        }
40
41        format!("Missing fields: {}. Provide a path to a valid config file or command line arguments for net-agent.\nYou can use config_file to set all these arguments.\nSee --help",
42                missing_fields.join(", "))
43    }
44}
45
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_cli_default_values() {
53        let cli = Cli::parse_from(&["test"]);
54
55        assert_eq!(cli.device_name, None);
56        assert_eq!(cli.number_packages, None);
57        assert_eq!(cli.buffer_size, None);
58        assert_eq!(cli.config_file, None);
59        assert_eq!(cli.output_directory, Some("output".to_string()));
60    }
61
62    #[test]
63    fn test_cli_custom_values_long() {
64        let cli = Cli::parse_from(&["test", "--device-name", "eth0", "--number-packages", "100", "--buffer-size", "1024", "--output-directory", "my-output"]);
65
66        assert_eq!(cli.device_name, Some("eth0".to_string()));
67        assert_eq!(cli.number_packages, Some(100));
68        assert_eq!(cli.buffer_size, Some(1024));
69        assert_eq!(cli.config_file, None);
70        assert_eq!(cli.output_directory, Some("my-output".to_string()));
71    }
72
73    #[test]
74    fn test_cli_custom_values_short() {
75        let cli = Cli::parse_from(&["test", "-D", "eth0", "-N", "100", "-B", "1024", "-O", "my-output"]);
76
77        assert_eq!(cli.device_name, Some("eth0".to_string()));
78        assert_eq!(cli.number_packages, Some(100));
79        assert_eq!(cli.buffer_size, Some(1024));
80        assert_eq!(cli.config_file, None);
81        assert_eq!(cli.output_directory, Some("my-output".to_string()));
82    }
83
84    #[test]
85    fn test_panic_lower_case_short() {
86        assert!(Cli::try_parse_from(&["test", "-d", "eth0", "-N", "100", "-B", "1024"]).is_err());
87    }
88
89    #[test]
90    fn test_cli_with_config_and_all_the_other_args() { 
91        assert!(Cli::try_parse_from(&["test", "-D", "eth0", "-N", "100", "-B", "1024", "--config-file", "config.toml"]).is_err());
92    }
93
94    #[test]
95    fn test_cli_with_long_config() {
96        let cli = Cli::try_parse_from(&["test", "--config-file", "config.toml"]);
97        assert!(cli.is_ok());
98        let cli = cli.unwrap();
99        assert_eq!(cli.device_name, None);
100        assert_eq!(cli.number_packages, None);
101        assert_eq!(cli.buffer_size, None);
102        assert_eq!(cli.config_file, Some("config.toml".to_string()));
103        // Actually all the other args must be set from the config file
104        assert_eq!(cli.output_directory, Some("output".to_string()));
105    }
106
107    #[test]
108    fn test_cli_with_short_config() {
109        let cli = Cli::try_parse_from(&["test", "-C", "config.toml"]);
110        assert!(cli.is_ok());
111        let cli = cli.unwrap();
112        assert_eq!(cli.device_name, None);
113        assert_eq!(cli.number_packages, None);
114        assert_eq!(cli.buffer_size, None);
115        assert_eq!(cli.config_file, Some("config.toml".to_string()));
116        assert_eq!(cli.output_directory, Some("output".to_string()));
117    }
118}