Run rustfmt

This commit is contained in:
Vinícius Rodrigues Miguel 2021-09-16 21:35:18 -03:00
parent fabe7cba31
commit eabaac0145
11 changed files with 109 additions and 203 deletions

View File

@ -10,11 +10,7 @@ use walkdir::WalkDir;
use crate::{oof, utils}; use crate::{oof, utils};
pub fn unpack_archive( pub fn unpack_archive(reader: Box<dyn Read>, output_folder: &Path, flags: &oof::Flags) -> crate::Result<Vec<PathBuf>> {
reader: Box<dyn Read>,
output_folder: &Path,
flags: &oof::Flags,
) -> crate::Result<Vec<PathBuf>> {
let mut archive = tar::Archive::new(reader); let mut archive = tar::Archive::new(reader);
let mut files_unpacked = vec![]; let mut files_unpacked = vec![];

View File

@ -12,11 +12,7 @@ use crate::{
utils::{self, colors}, utils::{self, colors},
}; };
pub fn unpack_archive<R>( pub fn unpack_archive<R>(mut archive: ZipArchive<R>, into: &Path, flags: &oof::Flags) -> crate::Result<Vec<PathBuf>>
mut archive: ZipArchive<R>,
into: &Path,
flags: &oof::Flags,
) -> crate::Result<Vec<PathBuf>>
where where
R: Read + Seek, R: Read + Seek,
{ {
@ -39,7 +35,7 @@ where
_is_dir @ true => { _is_dir @ true => {
println!("File {} extracted to \"{}\"", idx, file_path.display()); println!("File {} extracted to \"{}\"", idx, file_path.display());
fs::create_dir_all(&file_path)?; fs::create_dir_all(&file_path)?;
}, }
_is_file @ false => { _is_file @ false => {
if let Some(path) = file_path.parent() { if let Some(path) = file_path.parent() {
if !path.exists() { if !path.exists() {
@ -56,7 +52,7 @@ where
let mut output_file = fs::File::create(&file_path)?; let mut output_file = fs::File::create(&file_path)?;
io::copy(&mut file, &mut output_file)?; io::copy(&mut file, &mut output_file)?;
}, }
} }
#[cfg(unix)] #[cfg(unix)]
@ -85,10 +81,7 @@ where
.collect(); .collect();
if !invalid_unicode_filenames.is_empty() { if !invalid_unicode_filenames.is_empty() {
panic!( panic!("invalid unicode filenames found, cannot be supported by Zip:\n {:#?}", invalid_unicode_filenames);
"invalid unicode filenames found, cannot be supported by Zip:\n {:#?}",
invalid_unicode_filenames
);
} }
for filename in input_filenames { for filename in input_filenames {
@ -123,13 +116,7 @@ where
fn check_for_comments(file: &ZipFile) { fn check_for_comments(file: &ZipFile) {
let comment = file.comment(); let comment = file.comment();
if !comment.is_empty() { if !comment.is_empty() {
println!( println!("{}[INFO]{} Comment in {}: {}", colors::yellow(), colors::reset(), file.name(), comment);
"{}[INFO]{} Comment in {}: {}",
colors::yellow(),
colors::reset(),
file.name(),
comment
);
} }
} }

View File

@ -38,8 +38,8 @@ pub fn parse_args() -> crate::Result<ParsedArgs> {
match &mut parsed_args.command { match &mut parsed_args.command {
Command::Compress { files, .. } | Command::Decompress { files, .. } => { Command::Compress { files, .. } | Command::Decompress { files, .. } => {
*files = canonicalize_files(files)?; *files = canonicalize_files(files)?;
}, }
_ => {}, _ => {}
} }
if parsed_args.flags.is_present("yes") && parsed_args.flags.is_present("no") { if parsed_args.flags.is_present("yes") && parsed_args.flags.is_present("no") {
@ -78,7 +78,7 @@ fn canonicalize(path: impl AsRef<Path>) -> crate::Result<PathBuf> {
} else { } else {
Err(io_err.into()) Err(io_err.into())
} }
}, }
} }
} }
@ -113,7 +113,7 @@ pub fn parse_args_from(mut args: Vec<OsString>) -> crate::Result<ParsedArgs> {
let command = Command::Compress { files, output_path }; let command = Command::Compress { files, output_path };
ParsedArgs { command, flags } ParsedArgs { command, flags }
}, }
// Defaults to decompression when there is no subcommand // Defaults to decompression when there is no subcommand
None => { None => {
flags_info.push(arg_flag!('o', "output")); flags_info.push(arg_flag!('o', "output"));
@ -136,7 +136,7 @@ pub fn parse_args_from(mut args: Vec<OsString>) -> crate::Result<ParsedArgs> {
let command = Command::Decompress { files, output_folder }; let command = Command::Decompress { files, output_folder };
ParsedArgs { command, flags } ParsedArgs { command, flags }
}, }
_ => unreachable!("You should match each subcommand passed."), _ => unreachable!("You should match each subcommand passed."),
}; };
@ -163,14 +163,14 @@ mod tests {
assert_eq!(test_cli("--help").unwrap().command, Command::ShowHelp); assert_eq!(test_cli("--help").unwrap().command, Command::ShowHelp);
assert_eq!(test_cli("--version").unwrap().command, Command::ShowVersion); assert_eq!(test_cli("--version").unwrap().command, Command::ShowVersion);
assert_eq!(test_cli("--version").unwrap().flags, oof::Flags::default()); assert_eq!(test_cli("--version").unwrap().flags, oof::Flags::default());
assert_eq!(test_cli("foo.zip bar.zip").unwrap().command, Command::Decompress { assert_eq!(
files: vec!["foo.zip".into(), "bar.zip".into()], test_cli("foo.zip bar.zip").unwrap().command,
output_folder: None 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 { assert_eq!(
files: vec!["foo".into(), "bar".into()], test_cli("compress foo bar baz.zip").unwrap().command,
output_path: "baz.zip".into() Command::Compress { files: vec!["foo".into(), "bar".into()], output_path: "baz.zip".into() }
}); );
assert_eq!(test_cli("compress").unwrap_err(), crate::Error::MissingArgumentsForCompression); assert_eq!(test_cli("compress").unwrap_err(), crate::Error::MissingArgumentsForCompression);
} }
@ -180,9 +180,12 @@ mod tests {
assert_eq!(test_cli("--help").unwrap().flags, oof::Flags::default()); assert_eq!(test_cli("--help").unwrap().flags, oof::Flags::default());
assert_eq!(test_cli("--version").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 { assert_eq!(
boolean_flags: vec!["yes"].into_iter().collect(), test_cli("foo --yes bar --output folder").unwrap().flags,
argument_flags: vec![("output", OsString::from("folder"))].into_iter().collect(), oof::Flags {
}); boolean_flags: vec!["yes"].into_iter().collect(),
argument_flags: vec![("output", OsString::from("folder"))].into_iter().collect(),
}
);
} }
} }

View File

@ -40,8 +40,7 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> {
// It says: // It says:
// Change from file.bz.xz // Change from file.bz.xz
// To file.tar.bz.xz // To file.tar.bz.xz
let extensions_text: String = let extensions_text: String = formats.iter().map(|format| format.to_string()).collect();
formats.iter().map(|format| format.to_string()).collect();
let output_path = to_utf(output_path); let output_path = to_utf(output_path);
@ -53,38 +52,21 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> {
let mut suggested_output_path = output_path.clone(); let mut suggested_output_path = output_path.clone();
suggested_output_path.replace_range(empty_range, ".tar"); suggested_output_path.replace_range(empty_range, ".tar");
FinalError::with_title(format!( FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path)))
"Cannot compress to '{}'.", .detail("You are trying to compress multiple files.")
to_utf(&output_path) .detail(format!("The compression format '{}' cannot receive multiple files.", &formats[0]))
)) .detail("The only supported formats that bundle files into an archive are .tar and .zip.")
.detail("You are trying to compress multiple files.") .hint(format!("Try inserting '.tar' or '.zip' before '{}'.", &formats[0]))
.detail(format!( .hint(format!("From: {}", output_path))
"The compression format '{}' cannot receive multiple files.", .hint(format!(" To : {}", suggested_output_path))
&formats[0] .display_and_crash();
))
.detail("The only supported formats that bundle files into an archive are .tar and .zip.")
.hint(format!(
"Try inserting '.tar' or '.zip' before '{}'.",
&formats[0]
))
.hint(format!("From: {}", output_path))
.hint(format!(" To : {}", suggested_output_path))
.display_and_crash();
} }
if let Some(format) = if let Some(format) = formats.iter().skip(1).position(|format| matches!(format, Tar | Zip)) {
formats.iter().skip(1).position(|format| matches!(format, Tar | Zip))
{
FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path))) FinalError::with_title(format!("Cannot compress to '{}'.", to_utf(&output_path)))
.detail(format!("Found the format '{}' in an incorrect position.", format)) .detail(format!("Found the format '{}' in an incorrect position.", format))
.detail(format!( .detail(format!("{} can only be used at the start of the file extension.", format))
"{} can only be used at the start of the file extension.", .hint(format!("If you wish to compress multiple files, start the extension with {}.", format))
format
))
.hint(format!(
"If you wish to compress multiple files, start the extension with {}.",
format
))
.hint(format!("Otherwise, remove {} from '{}'.", format, to_utf(&output_path))) .hint(format!("Otherwise, remove {} from '{}'.", format, to_utf(&output_path)))
.display_and_crash(); .display_and_crash();
} }
@ -108,16 +90,8 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> {
if let Err(err) = fs::remove_file(&output_path) { if let Err(err) = fs::remove_file(&output_path) {
eprintln!("{red}FATAL ERROR:\n", red = colors::red()); eprintln!("{red}FATAL ERROR:\n", red = colors::red());
eprintln!(" Please manually delete '{}'.", to_utf(&output_path)); eprintln!(" Please manually delete '{}'.", to_utf(&output_path));
eprintln!( eprintln!(" Compression failed and we could not delete '{}'.", to_utf(&output_path),);
" Compression failed and we could not delete '{}'.", eprintln!(" Error:{reset} {}{red}.{reset}\n", err, reset = colors::reset(), red = colors::red());
to_utf(&output_path),
);
eprintln!(
" Error:{reset} {}{red}.{reset}\n",
err,
reset = colors::reset(),
red = colors::red()
);
} }
} else { } else {
println!( println!(
@ -129,14 +103,13 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> {
} }
compress_result?; compress_result?;
}, }
Command::Decompress { files, output_folder } => { Command::Decompress { files, output_folder } => {
let mut output_paths = vec![]; let mut output_paths = vec![];
let mut formats = vec![]; let mut formats = vec![];
for path in files.iter() { for path in files.iter() {
let (file_output_path, file_formats) = let (file_output_path, file_formats) = extension::separate_known_extensions_from_name(path);
extension::separate_known_extensions_from_name(path);
output_paths.push(file_output_path); output_paths.push(file_output_path);
formats.push(file_formats); formats.push(file_formats);
} }
@ -165,7 +138,7 @@ pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> {
for ((input_path, formats), file_name) in files.iter().zip(formats).zip(output_paths) { for ((input_path, formats), file_name) in files.iter().zip(formats).zip(output_paths) {
decompress_file(input_path, formats, output_folder, file_name, flags)?; decompress_file(input_path, formats, output_folder, file_name, flags)?;
} }
}, }
Command::ShowHelp => crate::help_command(), Command::ShowHelp => crate::help_command(),
Command::ShowVersion => crate::version_command(), Command::ShowVersion => crate::version_command(),
} }
@ -212,17 +185,13 @@ fn compress_files(
writer = chain_writer_encoder(&formats[0], writer); writer = chain_writer_encoder(&formats[0], writer);
let mut reader = fs::File::open(&files[0]).unwrap(); let mut reader = fs::File::open(&files[0]).unwrap();
io::copy(&mut reader, &mut writer)?; io::copy(&mut reader, &mut writer)?;
}, }
Tar => { Tar => {
let mut writer = archive::tar::build_archive_from_paths(&files, writer)?; let mut writer = archive::tar::build_archive_from_paths(&files, writer)?;
writer.flush()?; writer.flush()?;
}, }
Zip => { Zip => {
eprintln!( eprintln!("{yellow}Warning:{reset}", yellow = colors::yellow(), reset = colors::reset());
"{yellow}Warning:{reset}",
yellow = colors::yellow(),
reset = colors::reset()
);
eprintln!("\tCompressing .zip entirely in memory."); eprintln!("\tCompressing .zip entirely in memory.");
eprintln!("\tIf the file is too big, your pc might freeze!"); eprintln!("\tIf the file is too big, your pc might freeze!");
eprintln!( eprintln!(
@ -235,7 +204,7 @@ fn compress_files(
archive::zip::build_archive_from_paths(&files, &mut vec_buffer)?; archive::zip::build_archive_from_paths(&files, &mut vec_buffer)?;
let vec_buffer = vec_buffer.into_inner(); let vec_buffer = vec_buffer.into_inner();
io::copy(&mut vec_buffer.as_slice(), &mut writer)?; io::copy(&mut vec_buffer.as_slice(), &mut writer)?;
}, }
} }
} }
@ -257,11 +226,8 @@ fn decompress_file(
let reader = fs::File::open(&input_file_path)?; let reader = fs::File::open(&input_file_path)?;
// Output path is used by single file formats // Output path is used by single file formats
let output_path = if let Some(output_folder) = output_folder { let output_path =
output_folder.join(file_name) if let Some(output_folder) = output_folder { output_folder.join(file_name) } else { file_name.to_path_buf() };
} else {
file_name.to_path_buf()
};
// Output folder is used by archive file formats (zip and tar) // Output folder is used by archive file formats (zip and tar)
let output_folder = output_folder.unwrap_or_else(|| Path::new(".")); let output_folder = output_folder.unwrap_or_else(|| Path::new("."));
@ -309,18 +275,20 @@ fn decompress_file(
io::copy(&mut reader, &mut writer)?; io::copy(&mut reader, &mut writer)?;
println!("[INFO]: Successfully uncompressed file at '{}'.", to_utf(output_path)); println!("[INFO]: Successfully uncompressed file at '{}'.", to_utf(output_path));
}, }
Tar => { Tar => {
utils::create_dir_if_non_existent(output_folder)?; utils::create_dir_if_non_existent(output_folder)?;
let _ = crate::archive::tar::unpack_archive(reader, output_folder, flags)?; let _ = crate::archive::tar::unpack_archive(reader, output_folder, flags)?;
println!("[INFO]: Successfully uncompressed bundle at '{}'.", to_utf(output_folder)); println!("[INFO]: Successfully uncompressed bundle at '{}'.", to_utf(output_folder));
}, }
Zip => { Zip => {
utils::create_dir_if_non_existent(output_folder)?; utils::create_dir_if_non_existent(output_folder)?;
eprintln!("Compressing first into .zip."); eprintln!("Compressing first into .zip.");
eprintln!("Warning: .zip archives with extra extensions have a downside."); eprintln!("Warning: .zip archives with extra extensions have a downside.");
eprintln!("The only way is loading everything into the RAM while compressing, and then write everything down."); eprintln!(
"The only way is loading everything into the RAM while compressing, and then write everything down."
);
eprintln!("this means that by compressing .zip with extra compression formats, you can run out of RAM if the file is too large!"); eprintln!("this means that by compressing .zip with extra compression formats, you can run out of RAM if the file is too large!");
let mut vec = vec![]; let mut vec = vec![];
@ -330,7 +298,7 @@ fn decompress_file(
let _ = crate::archive::zip::unpack_archive(zip_archive, output_folder, flags)?; let _ = crate::archive::zip::unpack_archive(zip_archive, output_folder, flags)?;
println!("[INFO]: Successfully uncompressed bundle at '{}'.", to_utf(output_folder)); println!("[INFO]: Successfully uncompressed bundle at '{}'.", to_utf(output_folder));
}, }
} }
Ok(()) Ok(())

View File

@ -23,14 +23,7 @@ impl<'a> Confirmation<'a> {
}; };
loop { loop {
print!( print!("{} [{}Y{}/{}n{}] ", message, colors::green(), colors::reset(), colors::red(), colors::reset());
"{} [{}Y{}/{}n{}] ",
message,
colors::green(),
colors::reset(),
colors::red(),
colors::reset()
);
io::stdout().flush()?; io::stdout().flush()?;
let mut answer = String::new(); let mut answer = String::new();
@ -44,7 +37,7 @@ impl<'a> Confirmation<'a> {
match trimmed_answer.to_ascii_lowercase().as_ref() { match trimmed_answer.to_ascii_lowercase().as_ref() {
"y" | "yes" => return Ok(true), "y" | "yes" => return Ok(true),
"n" | "no" => return Ok(false), "n" | "no" => return Ok(false),
_ => {}, _ => {}
} }
} }
} }

View File

@ -86,10 +86,10 @@ impl fmt::Display for Error {
.hint("Use a supported format extension, like '.zip' or '.tar.gz'") .hint("Use a supported format extension, like '.zip' or '.tar.gz'")
.hint("Check https://github.com/vrmiguel/ouch for a full list of supported formats") .hint("Check https://github.com/vrmiguel/ouch for a full list of supported formats")
.display(); .display();
}, }
Error::WalkdirError { reason } => { Error::WalkdirError { reason } => {
FinalError::with_title(reason).display(); FinalError::with_title(reason).display();
}, }
Error::FileNotFound(file) => { Error::FileNotFound(file) => {
if file == Path::new("") { if file == Path::new("") {
FinalError::with_title("file not found!") FinalError::with_title("file not found!")
@ -97,13 +97,13 @@ impl fmt::Display for Error {
FinalError::with_title(format!("file {:?} not found!", file)) FinalError::with_title(format!("file {:?} not found!", file))
} }
.display(); .display();
}, }
Error::CompressingRootFolder => { Error::CompressingRootFolder => {
FinalError::with_title("It seems you're trying to compress the root folder.") FinalError::with_title("It seems you're trying to compress the root folder.")
.detail("This is unadvisable since ouch does compressions in-memory.") .detail("This is unadvisable since ouch does compressions in-memory.")
.hint("Use a more appropriate tool for this, such as rsync.") .hint("Use a more appropriate tool for this, such as rsync.")
.display(); .display();
}, }
Error::MissingArgumentsForCompression => { Error::MissingArgumentsForCompression => {
FinalError::with_title("Could not compress") FinalError::with_title("Could not compress")
.detail("The compress command requires at least 2 arguments") .detail("The compress command requires at least 2 arguments")
@ -113,7 +113,7 @@ impl fmt::Display for Error {
.hint("") .hint("")
.hint("Example: `ouch compress image.png img.zip`") .hint("Example: `ouch compress image.png img.zip`")
.display(); .display();
}, }
Error::InternalError => { Error::InternalError => {
FinalError::with_title("InternalError :(") FinalError::with_title("InternalError :(")
.detail("This should not have happened") .detail("This should not have happened")
@ -121,21 +121,21 @@ impl fmt::Display for Error {
.detail("Please help us improve by reporting the issue at:") .detail("Please help us improve by reporting the issue at:")
.detail(format!(" {}https://github.com/vrmiguel/ouch/issues ", cyan())) .detail(format!(" {}https://github.com/vrmiguel/ouch/issues ", cyan()))
.display(); .display();
}, }
Error::OofError(err) => { Error::OofError(err) => {
FinalError::with_title(err).display(); FinalError::with_title(err).display();
}, }
Error::IoError { reason } => { Error::IoError { reason } => {
FinalError::with_title(reason).display(); FinalError::with_title(reason).display();
}, }
Error::CompressionTypo => { Error::CompressionTypo => {
FinalError::with_title("Possible typo detected") FinalError::with_title("Possible typo detected")
.hint(format!("Did you mean '{}ouch compress{}'?", magenta(), reset())) .hint(format!("Did you mean '{}ouch compress{}'?", magenta(), reset()))
.display(); .display();
}, }
_err => { _err => {
todo!(); todo!();
}, }
} }
Ok(()) Ok(())
} }

View File

@ -14,13 +14,17 @@ pub enum CompressionFormat {
impl fmt::Display for CompressionFormat { impl fmt::Display for CompressionFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", match self { write!(
Gzip => ".gz", f,
Bzip => ".bz", "{}",
Lzma => ".lz", match self {
Tar => ".tar", Gzip => ".gz",
Zip => ".zip", Bzip => ".bz",
}) Lzma => ".lz",
Tar => ".tar",
Zip => ".zip",
}
)
} }
} }

View File

@ -29,18 +29,18 @@ impl fmt::Display for OofError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// TODO: implement proper debug messages // TODO: implement proper debug messages
match self { match self {
OofError::FlagValueConflict { OofError::FlagValueConflict { flag, previous_value, new_value } => write!(
flag,
previous_value,
new_value,
} => write!(
f, f,
"CLI flag value conflicted for flag '--{}', previous: {:?}, new: {:?}.", "CLI flag value conflicted for flag '--{}', previous: {:?}, new: {:?}.",
flag.long, previous_value, new_value flag.long, previous_value, new_value
), ),
OofError::InvalidUnicode(flag) => write!(f, "{:?} is not valid Unicode.", flag), OofError::InvalidUnicode(flag) => write!(f, "{:?} is not valid Unicode.", flag),
OofError::UnknownShortFlag(ch) => write!(f, "Unknown argument '-{}'", ch), OofError::UnknownShortFlag(ch) => write!(f, "Unknown argument '-{}'", ch),
OofError::MisplacedShortArgFlagError(ch) => write!(f, "Invalid placement of `-{}`.\nOnly the last letter in a sequence of short flags can take values.", ch), OofError::MisplacedShortArgFlagError(ch) => write!(
f,
"Invalid placement of `-{}`.\nOnly the last letter in a sequence of short flags can take values.",
ch
),
OofError::MissingValueToFlag(flag) => write!(f, "Flag {} takes value but none was supplied.", flag), OofError::MissingValueToFlag(flag) => write!(f, "Flag {} takes value but none was supplied.", flag),
OofError::DuplicatedFlag(flag) => write!(f, "Duplicated usage of {}.", flag), OofError::DuplicatedFlag(flag) => write!(f, "Duplicated usage of {}.", flag),
OofError::UnknownLongFlag(flag) => write!(f, "Unknown argument '--{}'", flag), OofError::UnknownLongFlag(flag) => write!(f, "Unknown argument '--{}'", flag),

View File

@ -63,30 +63,19 @@ where
/// - User passes same flag twice (short or long, boolean or arg). /// - User passes same flag twice (short or long, boolean or arg).
/// ///
/// ... /// ...
pub fn filter_flags( pub fn filter_flags(args: Vec<OsString>, flags_info: &[Flag]) -> Result<(Vec<OsString>, Flags), OofError> {
args: Vec<OsString>,
flags_info: &[Flag],
) -> Result<(Vec<OsString>, Flags), OofError> {
let mut short_flags_info = BTreeMap::<char, &Flag>::new(); let mut short_flags_info = BTreeMap::<char, &Flag>::new();
let mut long_flags_info = BTreeMap::<&'static str, &Flag>::new(); let mut long_flags_info = BTreeMap::<&'static str, &Flag>::new();
for flag in flags_info.iter() { for flag in flags_info.iter() {
// Panics if duplicated/conflicts // Panics if duplicated/conflicts
assert!( assert!(!long_flags_info.contains_key(flag.long), "DEV ERROR: duplicated long flag '{}'.", flag.long);
!long_flags_info.contains_key(flag.long),
"DEV ERROR: duplicated long flag '{}'.",
flag.long
);
long_flags_info.insert(flag.long, flag); long_flags_info.insert(flag.long, flag);
if let Some(short) = flag.short { if let Some(short) = flag.short {
// Panics if duplicated/conflicts // Panics if duplicated/conflicts
assert!( assert!(!short_flags_info.contains_key(&short), "DEV ERROR: duplicated short flag '-{}'.", short);
!short_flags_info.contains_key(&short),
"DEV ERROR: duplicated short flag '-{}'.",
short
);
short_flags_info.insert(short, flag); short_flags_info.insert(short, flag);
} }
} }
@ -130,8 +119,7 @@ pub fn filter_flags(
// Safety: this loop only runs when len >= 1, so this subtraction is safe // Safety: this loop only runs when len >= 1, so this subtraction is safe
let is_last_letter = i == letters.len() - 1; let is_last_letter = i == letters.len() - 1;
let flag_info = let flag_info = *short_flags_info.get(&letter).ok_or(OofError::UnknownShortFlag(letter))?;
*short_flags_info.get(&letter).ok_or(OofError::UnknownShortFlag(letter))?;
if !is_last_letter && flag_info.takes_value { if !is_last_letter && flag_info.takes_value {
return Err(OofError::MisplacedShortArgFlagError(letter)); return Err(OofError::MisplacedShortArgFlagError(letter));
@ -149,9 +137,7 @@ pub fn filter_flags(
} }
// pop the next one // pop the next one
let flag_argument = iter let flag_argument = iter.next().ok_or_else(|| OofError::MissingValueToFlag(flag_info.clone()))?;
.next()
.ok_or_else(|| OofError::MissingValueToFlag(flag_info.clone()))?;
// Otherwise, insert it. // Otherwise, insert it.
result_flags.argument_flags.insert(flag_name, flag_argument); result_flags.argument_flags.insert(flag_name, flag_argument);
@ -169,9 +155,7 @@ pub fn filter_flags(
if let FlagType::Long = flag_type { if let FlagType::Long = flag_type {
let flag = trim_double_hyphen(flag); let flag = trim_double_hyphen(flag);
let flag_info = *long_flags_info let flag_info = *long_flags_info.get(flag).ok_or_else(|| OofError::UnknownLongFlag(String::from(flag)))?;
.get(flag)
.ok_or_else(|| OofError::UnknownLongFlag(String::from(flag)))?;
let flag_name = flag_info.long; let flag_name = flag_info.long;
@ -181,8 +165,7 @@ pub fn filter_flags(
return Err(OofError::DuplicatedFlag(flag_info.clone())); return Err(OofError::DuplicatedFlag(flag_info.clone()));
} }
let flag_argument = let flag_argument = iter.next().ok_or_else(|| OofError::MissingValueToFlag(flag_info.clone()))?;
iter.next().ok_or_else(|| OofError::MissingValueToFlag(flag_info.clone()))?;
result_flags.argument_flags.insert(flag_name, flag_argument); result_flags.argument_flags.insert(flag_name, flag_argument);
} else { } else {
// If it was already inserted // If it was already inserted
@ -223,11 +206,8 @@ mod tests {
} }
fn setup_args_scenario(arg_str: &str) -> Result<(Vec<OsString>, Flags), OofError> { fn setup_args_scenario(arg_str: &str) -> Result<(Vec<OsString>, Flags), OofError> {
let flags_info = [ let flags_info =
ArgFlag::long("output_file").short('o'), [ArgFlag::long("output_file").short('o'), Flag::long("verbose").short('v'), Flag::long("help").short('h')];
Flag::long("verbose").short('v'),
Flag::long("help").short('h'),
];
let args = gen_args(arg_str); let args = gen_args(arg_str);
filter_flags(args, &flags_info) filter_flags(args, &flags_info)
@ -265,9 +245,7 @@ mod tests {
let misplaced_flag = ArgFlag::long("output_file").short('o'); let misplaced_flag = ArgFlag::long("output_file").short('o');
let result = setup_args_scenario("ouch -ov a.zip b.tar.gz c.tar").unwrap_err(); let result = setup_args_scenario("ouch -ov a.zip b.tar.gz c.tar").unwrap_err();
assert!( assert!(matches!(result, OofError::MisplacedShortArgFlagError(flag) if flag == misplaced_flag.short.unwrap()));
matches!(result, OofError::MisplacedShortArgFlagError(flag) if flag == misplaced_flag.short.unwrap())
);
} }
// #[test] // #[test]
@ -284,11 +262,8 @@ mod tests {
// asdasdsa // asdasdsa
#[test] #[test]
fn test_filter_flags() { fn test_filter_flags() {
let flags_info = [ let flags_info =
ArgFlag::long("output_file").short('o'), [ArgFlag::long("output_file").short('o'), Flag::long("verbose").short('v'), Flag::long("help").short('h')];
Flag::long("verbose").short('v'),
Flag::long("help").short('h'),
];
let args = gen_args("ouch a.zip -v b.tar.gz --output_file new_folder c.tar"); let args = gen_args("ouch a.zip -v b.tar.gz --output_file new_folder c.tar");
let (args, mut flags) = filter_flags(args, &flags_info).unwrap(); let (args, mut flags) = filter_flags(args, &flags_info).unwrap();
@ -354,8 +329,7 @@ mod tests {
// TODO: remove should_panic and use proper error handling inside of filter_args // TODO: remove should_panic and use proper error handling inside of filter_args
#[should_panic] #[should_panic]
fn test_flag_info_with_short_flag_conflict() { fn test_flag_info_with_short_flag_conflict() {
let flags_info = let flags_info = [ArgFlag::long("output_file").short('o'), Flag::long("verbose").short('o')];
[ArgFlag::long("output_file").short('o'), Flag::long("verbose").short('o')];
// Should panic here // Should panic here
filter_flags(vec![], &flags_info).unwrap_err(); filter_flags(vec![], &flags_info).unwrap_err();

View File

@ -9,19 +9,9 @@ use crate::{dialogs::Confirmation, oof};
pub fn create_dir_if_non_existent(path: &Path) -> crate::Result<()> { pub fn create_dir_if_non_existent(path: &Path) -> crate::Result<()> {
if !path.exists() { if !path.exists() {
println!( println!("{}[INFO]{} attempting to create folder {:?}.", colors::yellow(), colors::reset(), &path);
"{}[INFO]{} attempting to create folder {:?}.",
colors::yellow(),
colors::reset(),
&path
);
fs::create_dir_all(path)?; fs::create_dir_all(path)?;
println!( println!("{}[INFO]{} directory {:#?} created.", colors::yellow(), colors::reset(), fs::canonicalize(&path)?);
"{}[INFO]{} directory {:#?} created.",
colors::yellow(),
colors::reset(),
fs::canonicalize(&path)?
);
} }
Ok(()) Ok(())
} }
@ -45,13 +35,11 @@ pub fn cd_into_same_dir_as(filename: &Path) -> crate::Result<PathBuf> {
pub fn user_wants_to_overwrite(path: &Path, flags: &oof::Flags) -> crate::Result<bool> { pub fn user_wants_to_overwrite(path: &Path, flags: &oof::Flags) -> crate::Result<bool> {
match (flags.is_present("yes"), flags.is_present("no")) { match (flags.is_present("yes"), flags.is_present("no")) {
(true, true) => { (true, true) => {
unreachable!( unreachable!("This should've been cutted out in the ~/src/cli.rs filter flags function.")
"This should've been cutted out in the ~/src/cli.rs filter flags function." }
)
},
(true, _) => return Ok(true), (true, _) => return Ok(true),
(_, true) => return Ok(false), (_, true) => return Ok(false),
_ => {}, _ => {}
} }
let file_path_str = to_utf(path); let file_path_str = to_utf(path);

View File

@ -27,7 +27,9 @@ fn test_each_format() {
test_compressing_and_decompressing_archive("zip.lzma"); test_compressing_and_decompressing_archive("zip.lzma");
// Why not // Why not
test_compressing_and_decompressing_archive("tar.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.lz.lz.lz.lz.lz.lz.lz.lz.lz.lz.bz.bz.bz.bz.bz.bz.bz"); test_compressing_and_decompressing_archive(
"tar.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.gz.lz.lz.lz.lz.lz.lz.lz.lz.lz.lz.bz.bz.bz.bz.bz.bz.bz",
);
} }
type FileContent = Vec<u8>; type FileContent = Vec<u8>;
@ -38,10 +40,8 @@ fn test_compressing_and_decompressing_archive(format: &str) {
let system_tmp = env::temp_dir(); let system_tmp = env::temp_dir();
// Create a temporary testing folder that will be deleted on scope drop // Create a temporary testing folder that will be deleted on scope drop
let testing_dir = tempfile::Builder::new() let testing_dir =
.prefix("ouch-testing") tempfile::Builder::new().prefix("ouch-testing").tempdir_in(system_tmp).expect("Could not create testing_dir");
.tempdir_in(system_tmp)
.expect("Could not create testing_dir");
let testing_dir_path = testing_dir.path(); let testing_dir_path = testing_dir.path();
// Quantity of compressed files vary from 1 to 10 // Quantity of compressed files vary from 1 to 10
@ -98,10 +98,7 @@ fn compress_files(at: &Path, paths_to_compress: &[PathBuf], format: &str) -> Pat
let archive_path = String::from("archive.") + format; let archive_path = String::from("archive.") + format;
let archive_path = at.join(archive_path); let archive_path = at.join(archive_path);
let command = Command::Compress { let command = Command::Compress { files: paths_to_compress.to_vec(), output_path: archive_path.to_path_buf() };
files: paths_to_compress.to_vec(),
output_path: archive_path.to_path_buf(),
};
run(command, &oof::Flags::default()).expect("Failed to compress test dummy files"); run(command, &oof::Flags::default()).expect("Failed to compress test dummy files");
archive_path archive_path
@ -125,11 +122,7 @@ fn extract_files(archive_path: &Path) -> Vec<PathBuf> {
}; };
run(command, &oof::Flags::default()).expect("Failed to extract"); run(command, &oof::Flags::default()).expect("Failed to extract");
fs::read_dir(extraction_output_folder) fs::read_dir(extraction_output_folder).unwrap().map(Result::unwrap).map(|entry| entry.path()).collect()
.unwrap()
.map(Result::unwrap)
.map(|entry| entry.path())
.collect()
} }
fn assert_correct_paths(original: &[PathBuf], extracted: &[PathBuf], format: &str) { fn assert_correct_paths(original: &[PathBuf], extracted: &[PathBuf], format: &str) {