shadow_crypt_shell/decryption/
cli.rs

1use crate::errors::{WorkflowError, WorkflowResult};
2use clap::Parser;
3
4/// Decryption CLI arguments structure
5#[derive(Debug, Clone, Parser)]
6#[command(name = "unshadow", about = "Decrypt shadow files", version)]
7pub struct DecryptionCliArgs {
8    /// Input files to decrypt
9    #[arg(value_name = "FILE")]
10    pub input_files: Vec<String>,
11}
12
13/// Parse decryption command line arguments
14pub fn get_cli_args(args: Vec<String>) -> WorkflowResult<DecryptionCliArgs> {
15    let cli_args = DecryptionCliArgs::try_parse_from(args).map_err(|e| {
16        // If it's help or version, it's not a user input error
17        if e.kind() == clap::error::ErrorKind::DisplayHelp
18            || e.kind() == clap::error::ErrorKind::DisplayVersion
19        {
20            // Print the message and exit successfully
21            eprintln!("{}", e);
22            std::process::exit(0);
23        }
24        WorkflowError::UserInput(e.to_string())
25    })?;
26
27    if cli_args.input_files.is_empty() {
28        return Err(WorkflowError::UserInput(
29            "No input files provided".to_string(),
30        ));
31    }
32
33    Ok(cli_args)
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn test_parse_cli_args_with_files() {
42        let args = vec![
43            "unshadow".to_string(),
44            "file1.txt".to_string(),
45            "file2.txt".to_string(),
46        ];
47        let cli_args = get_cli_args(args).unwrap();
48        assert_eq!(
49            cli_args.input_files,
50            vec!["file1.txt".to_string(), "file2.txt".to_string()]
51        );
52    }
53
54    #[test]
55    fn test_parse_cli_args_with_single_file() {
56        let args = vec!["unshadow".to_string(), "file1.txt".to_string()];
57        let cli_args = get_cli_args(args).unwrap();
58        assert_eq!(cli_args.input_files, vec!["file1.txt".to_string()]);
59    }
60
61    #[test]
62    fn test_parse_cli_args_no_files() {
63        let args = vec!["unshadow".to_string()];
64        let result = get_cli_args(args);
65        assert!(result.is_err());
66        if let Err(WorkflowError::UserInput(msg)) = result {
67            assert_eq!(msg, "No input files provided");
68        } else {
69            panic!("Expected UserInput error");
70        }
71    }
72
73    #[test]
74    fn test_parse_cli_args_help() {
75        // Note: --help now causes the function to exit successfully, so this test is removed
76    }
77}