diff --git a/src/cli.rs b/src/cli.rs index 4eb31f6..0b38cab 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -37,8 +37,8 @@ pub fn parse_args() -> crate::Result { match &mut parsed_args.command { Command::Compress { files, .. } | Command::Decompress { files, .. } => { *files = canonicalize_files(&files)?; - }, - _ => {}, + } + _ => {} } Ok(parsed_args) } @@ -72,7 +72,7 @@ fn canonicalize(path: impl AsRef) -> crate::Result { } else { Err(io_err.into()) } - }, + } } } @@ -107,7 +107,7 @@ pub fn parse_args_from(mut args: Vec) -> crate::Result { let command = Command::Compress { files, compressed_output_path }; ParsedArgs { command, flags } - }, + } // Defaults to decompression when there is no subcommand None => { flags_info.push(arg_flag!('o', "output")); @@ -121,18 +121,71 @@ pub fn parse_args_from(mut args: Vec) -> crate::Result { } // Parse flags - let (files, mut flags) = oof::filter_flags(args, &flags_info)?; + let (files, flags) = oof::filter_flags(args, &flags_info)?; let files = files.into_iter().map(PathBuf::from).collect(); - let output_folder = flags.take_arg("output").map(PathBuf::from); + let output_folder = flags.arg("output").map(PathBuf::from); // TODO: ensure all files are decompressible let command = Command::Decompress { files, output_folder }; ParsedArgs { command, flags } - }, + } _ => unreachable!("You should match each subcommand passed."), }; Ok(parsed_args) } + +#[cfg(test)] +mod tests { + + use super::*; + + fn gen_args(text: &str) -> Vec { + let args = text.split_whitespace(); + args.map(OsString::from).collect() + } + + fn test_cli(args: &str) -> crate::Result { + let args = gen_args(args); + parse_args_from(args) + } + + #[test] + fn test_cli_commands() { + assert_eq!(test_cli("--help").unwrap().command, Command::ShowHelp); + assert_eq!(test_cli("--version").unwrap().command, Command::ShowVersion); + assert_eq!(test_cli("--version").unwrap().flags, oof::Flags::default()); + assert_eq!( + test_cli("foo.zip bar.zip").unwrap().command, + Command::Decompress { + files: vec!["foo.zip".into(), "bar.zip".into()], + output_folder: None + } + ); + assert_eq!( + test_cli("compress foo bar baz.zip").unwrap().command, + Command::Compress { + files: vec!["foo".into(), "bar".into()], + compressed_output_path: "baz.zip".into() + } + ); + assert_eq!(test_cli("compress").unwrap_err(), crate::Error::MissingArgumentsForCompression); + } + + #[test] + fn test_cli_flags() { + // --help and --version flags are considered commands that are ran over anything else + assert_eq!(test_cli("--help").unwrap().flags, oof::Flags::default()); + assert_eq!(test_cli("--version").unwrap().flags, oof::Flags::default()); + + assert_eq!( + test_cli("foo --yes bar --output folder").unwrap().flags, + oof::Flags { + boolean_flags: vec!["yes"].into_iter().collect(), + argument_flags: vec![("output", OsString::from("folder"))].into_iter().collect(), + } + ); + } +} diff --git a/src/oof/flags.rs b/src/oof/flags.rs index b70af33..7ff1a78 100644 --- a/src/oof/flags.rs +++ b/src/oof/flags.rs @@ -55,9 +55,7 @@ impl Flags { pub fn new() -> Self { Self::default() } -} -impl Flags { pub fn is_present(&self, flag_name: &str) -> bool { self.boolean_flags.contains(flag_name) || self.argument_flags.contains_key(flag_name) }