shadow_crypt_shell/decryption/
cli.rs1use crate::errors::{WorkflowError, WorkflowResult};
2use clap::Parser;
3
4#[derive(Debug, Clone, Parser)]
6#[command(name = "unshadow", about = "Decrypt shadow files", version)]
7pub struct DecryptionCliArgs {
8 #[arg(value_name = "FILE")]
10 pub input_files: Vec<String>,
11}
12
13pub fn get_cli_args(args: Vec<String>) -> WorkflowResult<DecryptionCliArgs> {
15 let cli_args = DecryptionCliArgs::try_parse_from(args).map_err(|e| {
16 if e.kind() == clap::error::ErrorKind::DisplayHelp
18 || e.kind() == clap::error::ErrorKind::DisplayVersion
19 {
20 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 }
77}