evaluator: Verify if input files are decompressible

This commit is contained in:
Vinícius Miguel 2021-04-06 04:30:36 -03:00
parent 9b8dcb40fa
commit f9272b5ce5
16 changed files with 81 additions and 90 deletions

View File

@ -1,4 +1,9 @@
use std::{env, ffi::OsString, path::{Path, PathBuf}, vec::Vec}; use std::{
env,
ffi::OsString,
path::{Path, PathBuf},
vec::Vec,
};
use oof::{arg_flag, flag}; use oof::{arg_flag, flag};
@ -41,7 +46,7 @@ pub struct ParsedArgs {
fn canonicalize<'a, P>(path: P) -> crate::Result<PathBuf> fn canonicalize<'a, P>(path: P) -> crate::Result<PathBuf>
where where
P: AsRef<Path> + 'a P: AsRef<Path> + 'a,
{ {
match std::fs::canonicalize(&path.as_ref()) { match std::fs::canonicalize(&path.as_ref()) {
Ok(abs_path) => Ok(abs_path), Ok(abs_path) => Ok(abs_path),
@ -118,6 +123,7 @@ pub fn parse_args_from(mut args: Vec<OsString>) -> crate::Result<ParsedArgs> {
let files = files.map(Result::unwrap).collect(); let files = files.map(Result::unwrap).collect();
let output_folder = flags.take_arg("output").map(PathBuf::from); let output_folder = flags.take_arg("output").map(PathBuf::from);
// TODO: ensure all files are decompressible // TODO: ensure all files are decompressible
let command = Command::Decompress { let command = Command::Decompress {

View File

@ -4,8 +4,8 @@ use colored::Colorize;
use super::{Compressor, Entry}; use super::{Compressor, Entry};
use crate::{ use crate::{
extension::CompressionFormat,
bytes::Bytes, bytes::Bytes,
extension::CompressionFormat,
file::File, file::File,
utils::{check_for_multiple_files, ensure_exists}, utils::{check_for_multiple_files, ensure_exists},
}; };

View File

@ -4,9 +4,9 @@ use colored::Colorize;
use super::{Compressor, Entry}; use super::{Compressor, Entry};
use crate::{ use crate::{
bytes::Bytes,
extension::CompressionFormat, extension::CompressionFormat,
file::File, file::File,
bytes::Bytes,
utils::{check_for_multiple_files, ensure_exists}, utils::{check_for_multiple_files, ensure_exists},
}; };

View File

@ -4,9 +4,9 @@ use colored::Colorize;
use super::{Compressor, Entry}; use super::{Compressor, Entry};
use crate::{ use crate::{
bytes::Bytes,
extension::CompressionFormat, extension::CompressionFormat,
file::File, file::File,
bytes::Bytes,
utils::{check_for_multiple_files, ensure_exists}, utils::{check_for_multiple_files, ensure_exists},
}; };

View File

@ -8,7 +8,7 @@ use colored::Colorize;
use tar::{self, Archive}; use tar::{self, Archive};
use super::decompressor::{DecompressionResult, Decompressor}; use super::decompressor::{DecompressionResult, Decompressor};
use crate::{dialogs::Confirmation, file::File, bytes::Bytes, utils}; use crate::{bytes::Bytes, dialogs::Confirmation, file::File, utils};
#[derive(Debug)] #[derive(Debug)]
pub struct TarDecompressor {} pub struct TarDecompressor {}

View File

@ -6,8 +6,8 @@ use std::{
use colored::Colorize; use colored::Colorize;
use super::decompressor::{DecompressionResult, Decompressor}; use super::decompressor::{DecompressionResult, Decompressor};
use crate::utils;
use crate::bytes::Bytes; use crate::bytes::Bytes;
use crate::utils;
use crate::{extension::CompressionFormat, file::File}; use crate::{extension::CompressionFormat, file::File};
struct DecompressorToMemory {} struct DecompressorToMemory {}

View File

@ -8,7 +8,7 @@ use colored::Colorize;
use zip::{self, read::ZipFile, ZipArchive}; use zip::{self, read::ZipFile, ZipArchive};
use super::decompressor::{DecompressionResult, Decompressor}; use super::decompressor::{DecompressionResult, Decompressor};
use crate::{dialogs::Confirmation, file::File, bytes::Bytes, utils}; use crate::{bytes::Bytes, dialogs::Confirmation, file::File, utils};
#[cfg(unix)] #[cfg(unix)]
fn __unix_set_permissions(file_path: &Path, file: &ZipFile) { fn __unix_set_permissions(file_path: &Path, file: &ZipFile) {

View File

@ -5,7 +5,7 @@ use colored::Colorize;
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq)]
pub enum Error { pub enum Error {
UnknownExtensionError(String), UnknownExtensionError(String),
MissingExtensionError(String), MissingExtensionError(PathBuf),
// TODO: get rid of this error variant // TODO: get rid of this error variant
InvalidUnicode, InvalidUnicode,
InvalidInput, InvalidInput,
@ -35,7 +35,7 @@ impl fmt::Display for Error {
Error::MissingExtensionError(filename) => { Error::MissingExtensionError(filename) => {
write!(f, "{} ", "[ERROR]".red())?; write!(f, "{} ", "[ERROR]".red())?;
// TODO: show MIME type of the unsupported file // TODO: show MIME type of the unsupported file
write!(f, "cannot compress to \'{}\', likely because it has an unsupported (or missing) extension.", filename) write!(f, "cannot compress to {:?}, likely because it has an unsupported (or missing) extension.", filename)
} }
Error::WalkdirError => { Error::WalkdirError => {
// Already printed in the From block // Already printed in the From block

View File

@ -8,9 +8,9 @@ use colored::Colorize;
use crate::{ use crate::{
bytes::Bytes, bytes::Bytes,
cli::{VERSION, Command}, cli::{Command, VERSION},
compressors::{ compressors::{
Entry, Compressor, BzipCompressor, GzipCompressor, LzmaCompressor, TarCompressor, BzipCompressor, Compressor, Entry, GzipCompressor, LzmaCompressor, TarCompressor,
ZipCompressor, ZipCompressor,
}, },
decompressors::{ decompressors::{
@ -21,7 +21,6 @@ use crate::{
extension::{CompressionFormat, Extension}, extension::{CompressionFormat, Extension},
file::File, file::File,
utils, utils,
debug
}; };
pub struct Evaluator {} pub struct Evaluator {}
@ -33,7 +32,6 @@ impl Evaluator {
pub fn get_compressor( pub fn get_compressor(
file: &File, file: &File,
) -> crate::Result<(Option<BoxedCompressor>, BoxedCompressor)> { ) -> crate::Result<(Option<BoxedCompressor>, BoxedCompressor)> {
let extension = match &file.extension { let extension = match &file.extension {
Some(extension) => extension.clone(), Some(extension) => extension.clone(),
None => { None => {
@ -214,7 +212,15 @@ impl Evaluator {
output: Option<&Path>, output: Option<&Path>,
flags: &oof::Flags, flags: &oof::Flags,
) -> crate::Result<()> { ) -> crate::Result<()> {
let file = debug!(File::from(file_path)?); // The file to be decompressed
let file = File::from(file_path)?;
// The file must have a supported decompressible format
if file.extension == None {
return Err(crate::Error::MissingExtensionError(PathBuf::from(
file_path,
)));
}
let output = match output { let output = match output {
Some(inner) => Some(File::from(inner)?), Some(inner) => Some(File::from(inner)?),
None => None, None => None,

View File

@ -57,7 +57,11 @@ impl Extension {
(os_str, snd) if os_str.is_empty() => (None, snd), (os_str, snd) if os_str.is_empty() => (None, snd),
(fst, snd) => (Some(fst), snd), (fst, snd) => (Some(fst), snd),
}, },
None => return Err(crate::Error::MissingExtensionError(to_utf(file_name))), None => {
return Err(crate::Error::MissingExtensionError(PathBuf::from(
file_name,
)))
}
}; };
let (first_ext, second_ext) = match (first_ext, second_ext) { let (first_ext, second_ext) = match (first_ext, second_ext) {
@ -119,7 +123,7 @@ impl TryFrom<&PathBuf> for CompressionFormat {
let ext = match ext.extension() { let ext = match ext.extension() {
Some(ext) => ext, Some(ext) => ext,
None => { None => {
return Err(crate::Error::MissingExtensionError(String::new())); return Err(crate::Error::MissingExtensionError(PathBuf::new()));
} }
}; };
extension_from_os_str(ext) extension_from_os_str(ext)
@ -133,7 +137,7 @@ impl TryFrom<&str> for CompressionFormat {
let file_name = Path::new(file_name); let file_name = Path::new(file_name);
let ext = match file_name.extension() { let ext = match file_name.extension() {
Some(ext) => ext, Some(ext) => ext,
None => return Err(crate::Error::MissingExtensionError(String::new())), None => return Err(crate::Error::MissingExtensionError(PathBuf::new())),
}; };
extension_from_os_str(ext) extension_from_os_str(ext)

View File

@ -24,7 +24,7 @@ impl<'a> File<'a> {
Ok(File { Ok(File {
path, path,
contents_in_memory: None, contents_in_memory: None,
extension extension,
}) })
} }
} }

View File

@ -27,7 +27,7 @@ where
#[cfg(test)] #[cfg(test)]
mod argparsing { mod argparsing {
use super::{make_dummy_files}; use super::make_dummy_files;
use crate::cli; use crate::cli;
use crate::cli::Command; use crate::cli::Command;
use std::{ffi::OsString, fs, path::PathBuf}; use std::{ffi::OsString, fs, path::PathBuf};
@ -65,10 +65,13 @@ mod argparsing {
#[test] #[test]
fn test_arg_parsing_compress_subcommand() -> crate::Result<()> { fn test_arg_parsing_compress_subcommand() -> crate::Result<()> {
let files = vec!["a", "b", "c"]; let files = vec!["a", "b", "c"];
make_dummy_files(&*files)?; make_dummy_files(&*files)?;
let files= files.iter().map(fs::canonicalize).map(Result::unwrap).collect(); let files = files
.iter()
.map(fs::canonicalize)
.map(Result::unwrap)
.collect();
let expected = Command::Compress { let expected = Command::Compress {
files, files,
@ -108,69 +111,36 @@ mod byte_pretty_printing {
use crate::bytes::Bytes; use crate::bytes::Bytes;
#[test] #[test]
fn bytes() { fn bytes() {
assert_eq!( assert_eq!(&format!("{}", Bytes::new(234)), "234.00 B");
&format!("{}", Bytes::new(234)),
"234.00 B"
);
assert_eq!( assert_eq!(&format!("{}", Bytes::new(999)), "999.00 B");
&format!("{}", Bytes::new(999)),
"999.00 B"
);
} }
#[test] #[test]
fn kilobytes() { fn kilobytes() {
assert_eq!( assert_eq!(&format!("{}", Bytes::new(2234)), "2.23 kB");
&format!("{}", Bytes::new(2234)),
"2.23 kB"
);
assert_eq!( assert_eq!(&format!("{}", Bytes::new(62500)), "62.50 kB");
&format!("{}", Bytes::new(62500)),
"62.50 kB"
);
assert_eq!( assert_eq!(&format!("{}", Bytes::new(329990)), "329.99 kB");
&format!("{}", Bytes::new(329990)),
"329.99 kB"
);
} }
#[test] #[test]
fn megabytes() { fn megabytes() {
assert_eq!( assert_eq!(&format!("{}", Bytes::new(2750000)), "2.75 MB");
&format!("{}", Bytes::new(2750000)),
"2.75 MB"
);
assert_eq!( assert_eq!(&format!("{}", Bytes::new(55000000)), "55.00 MB");
&format!("{}", Bytes::new(55000000)),
"55.00 MB"
);
assert_eq!( assert_eq!(&format!("{}", Bytes::new(987654321)), "987.65 MB");
&format!("{}", Bytes::new(987654321)),
"987.65 MB"
);
} }
#[test] #[test]
fn gigabytes() { fn gigabytes() {
assert_eq!( assert_eq!(&format!("{}", Bytes::new(5280000000)), "5.28 GB");
&format!("{}", Bytes::new(5280000000)),
"5.28 GB"
);
assert_eq!( assert_eq!(&format!("{}", Bytes::new(95200000000)), "95.20 GB");
&format!("{}", Bytes::new(95200000000)),
"95.20 GB"
);
assert_eq!( assert_eq!(&format!("{}", Bytes::new(302000000000)), "302.00 GB");
&format!("{}", Bytes::new(302000000000)),
"302.00 GB"
);
} }
} }

View File

@ -12,16 +12,19 @@ use crate::{dialogs::Confirmation, extension::CompressionFormat, file::File};
#[macro_export] #[macro_export]
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
macro_rules! debug { macro_rules! debug {
($x:expr) => { dbg!($x) } ($x:expr) => {
dbg!($x)
};
} }
#[macro_export] #[macro_export]
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
macro_rules! debug { macro_rules! debug {
($x:expr) => { std::convert::identity($x) } ($x:expr) => {
std::convert::identity($x)
};
} }
pub(crate) fn ensure_exists<'a, P>(path: P) -> crate::Result<()> pub(crate) fn ensure_exists<'a, P>(path: P) -> crate::Result<()>
where where
P: AsRef<Path> + 'a, P: AsRef<Path> + 'a,
@ -82,7 +85,9 @@ pub(crate) fn change_dir_and_return_parent(filename: &Path) -> crate::Result<Pat
return Err(crate::Error::CompressingRootFolder); return Err(crate::Error::CompressingRootFolder);
}; };
env::set_current_dir(parent).ok().ok_or(crate::Error::CompressingRootFolder)?; env::set_current_dir(parent)
.ok()
.ok_or(crate::Error::CompressingRootFolder)?;
Ok(previous_location) Ok(previous_location)
} }