mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-06 19:45:29 +00:00
Change evaluator.rs to commands.rs
This commit is contained in:
parent
3869c2502e
commit
973af5fe1c
281
src/commands.rs
Normal file
281
src/commands.rs
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
io::Write,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use colored::Colorize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
cli::Command,
|
||||||
|
compressors::{
|
||||||
|
BzipCompressor, Compressor, Entry, GzipCompressor, LzmaCompressor, TarCompressor,
|
||||||
|
ZipCompressor,
|
||||||
|
},
|
||||||
|
decompressors::{
|
||||||
|
BzipDecompressor, DecompressionResult, Decompressor, GzipDecompressor, LzmaDecompressor,
|
||||||
|
TarDecompressor, ZipDecompressor,
|
||||||
|
},
|
||||||
|
dialogs::Confirmation,
|
||||||
|
extension::{CompressionFormat, Extension},
|
||||||
|
file::File,
|
||||||
|
utils,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn run(command: Command, flags: &oof::Flags) -> crate::Result<()> {
|
||||||
|
match command {
|
||||||
|
Command::Compress {
|
||||||
|
files,
|
||||||
|
compressed_output_path,
|
||||||
|
} => compress_files(files, &compressed_output_path, flags)?,
|
||||||
|
Command::Decompress {
|
||||||
|
files,
|
||||||
|
output_folder,
|
||||||
|
} => {
|
||||||
|
// From Option<PathBuf> to Option<&Path>
|
||||||
|
let output_folder = output_folder.as_ref().map(|path| Path::new(path));
|
||||||
|
for file in files.iter() {
|
||||||
|
decompress_file(file, output_folder, flags)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command::ShowHelp => help_command(),
|
||||||
|
Command::ShowVersion => version_command(),
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn help_command() {
|
||||||
|
version_command();
|
||||||
|
println!("Vinícius R. M. & João M. Bezerra");
|
||||||
|
println!("ouch is a unified compression & decompression utility");
|
||||||
|
println!();
|
||||||
|
println!(" COMPRESSION USAGE:");
|
||||||
|
println!(" ouch compress <input...> output-file");
|
||||||
|
println!("DECOMPRESSION USAGE:");
|
||||||
|
println!(" ouch <input> [-o/--output output-folder]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn version_command() {
|
||||||
|
println!("ouch {}", crate::VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
type BoxedCompressor = Box<dyn Compressor>;
|
||||||
|
type BoxedDecompressor = Box<dyn Decompressor>;
|
||||||
|
|
||||||
|
fn get_compressor(file: &File) -> crate::Result<(Option<BoxedCompressor>, BoxedCompressor)> {
|
||||||
|
let extension = match &file.extension {
|
||||||
|
Some(extension) => extension.clone(),
|
||||||
|
None => {
|
||||||
|
// This is reached when the output file given does not have an extension or has an unsupported one
|
||||||
|
return Err(crate::Error::MissingExtensionError(file.path.to_path_buf()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported first compressors:
|
||||||
|
// .tar and .zip
|
||||||
|
let first_compressor: Option<Box<dyn Compressor>> = match extension.first_ext {
|
||||||
|
Some(ext) => match ext {
|
||||||
|
CompressionFormat::Tar => Some(Box::new(TarCompressor)),
|
||||||
|
CompressionFormat::Zip => Some(Box::new(ZipCompressor)),
|
||||||
|
CompressionFormat::Bzip => Some(Box::new(BzipCompressor)),
|
||||||
|
CompressionFormat::Gzip => Some(Box::new(GzipCompressor)),
|
||||||
|
CompressionFormat::Lzma => Some(Box::new(LzmaCompressor)),
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported second compressors:
|
||||||
|
// any
|
||||||
|
let second_compressor: Box<dyn Compressor> = match extension.second_ext {
|
||||||
|
CompressionFormat::Tar => Box::new(TarCompressor),
|
||||||
|
CompressionFormat::Zip => Box::new(ZipCompressor),
|
||||||
|
CompressionFormat::Bzip => Box::new(BzipCompressor),
|
||||||
|
CompressionFormat::Gzip => Box::new(GzipCompressor),
|
||||||
|
CompressionFormat::Lzma => Box::new(LzmaCompressor),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((first_compressor, second_compressor))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_decompressor(file: &File) -> crate::Result<(Option<BoxedDecompressor>, BoxedDecompressor)> {
|
||||||
|
let extension = match &file.extension {
|
||||||
|
Some(extension) => extension.clone(),
|
||||||
|
None => {
|
||||||
|
// This block *should* be unreachable
|
||||||
|
eprintln!(
|
||||||
|
"{} reached Evaluator::get_decompressor without known extension.",
|
||||||
|
"[internal error]".red()
|
||||||
|
);
|
||||||
|
return Err(crate::Error::InvalidInput);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let second_decompressor: Box<dyn Decompressor> = match extension.second_ext {
|
||||||
|
CompressionFormat::Tar => Box::new(TarDecompressor),
|
||||||
|
CompressionFormat::Zip => Box::new(ZipDecompressor),
|
||||||
|
CompressionFormat::Gzip => Box::new(GzipDecompressor),
|
||||||
|
CompressionFormat::Lzma => Box::new(LzmaDecompressor),
|
||||||
|
CompressionFormat::Bzip => Box::new(BzipDecompressor),
|
||||||
|
};
|
||||||
|
|
||||||
|
let first_decompressor: Option<Box<dyn Decompressor>> = match extension.first_ext {
|
||||||
|
Some(ext) => match ext {
|
||||||
|
CompressionFormat::Tar => Some(Box::new(TarDecompressor)),
|
||||||
|
CompressionFormat::Zip => Some(Box::new(ZipDecompressor)),
|
||||||
|
_other => None,
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((first_decompressor, second_decompressor))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decompress_file_in_memory(
|
||||||
|
bytes: Vec<u8>,
|
||||||
|
file_path: &Path,
|
||||||
|
decompressor: Option<Box<dyn Decompressor>>,
|
||||||
|
output_file: Option<File>,
|
||||||
|
extension: Option<Extension>,
|
||||||
|
flags: &oof::Flags,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
let output_file_path = utils::get_destination_path(&output_file);
|
||||||
|
|
||||||
|
let file_name = file_path
|
||||||
|
.file_stem()
|
||||||
|
.map(Path::new)
|
||||||
|
.unwrap_or(output_file_path);
|
||||||
|
|
||||||
|
if "." == file_name.as_os_str() {
|
||||||
|
// I believe this is only possible when the supplied input has a name
|
||||||
|
// of the sort `.tar` or `.zip' and no output has been supplied.
|
||||||
|
// file_name = OsStr::new("ouch-output");
|
||||||
|
todo!("Pending review, what is this supposed to do??");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a decompressor to use, we'll create a file in-memory and decompress it
|
||||||
|
let decompressor = match decompressor {
|
||||||
|
Some(decompressor) => decompressor,
|
||||||
|
None => {
|
||||||
|
// There is no more processing to be done on the input file (or there is but currently unsupported)
|
||||||
|
// Therefore, we'll save what we have in memory into a file.
|
||||||
|
println!("{}: saving to {:?}.", "info".yellow(), file_name);
|
||||||
|
|
||||||
|
if file_name.exists() {
|
||||||
|
let confirm = Confirmation::new("Do you want to overwrite 'FILE'?", Some("FILE"));
|
||||||
|
if !utils::permission_for_overwriting(&file_name, flags, &confirm)? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut f = fs::File::create(output_file_path.join(file_name))?;
|
||||||
|
f.write_all(&bytes)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let file = File {
|
||||||
|
path: file_name,
|
||||||
|
contents_in_memory: Some(bytes),
|
||||||
|
extension,
|
||||||
|
};
|
||||||
|
|
||||||
|
let decompression_result = decompressor.decompress(file, &output_file, flags)?;
|
||||||
|
if let DecompressionResult::FileInMemory(_) = decompression_result {
|
||||||
|
unreachable!("Shouldn't");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compress_files(
|
||||||
|
files: Vec<PathBuf>,
|
||||||
|
output_path: &Path,
|
||||||
|
flags: &oof::Flags,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
let mut output = File::from(output_path)?;
|
||||||
|
|
||||||
|
let confirm = Confirmation::new("Do you want to overwrite 'FILE'?", Some("FILE"));
|
||||||
|
let (first_compressor, second_compressor) = get_compressor(&output)?;
|
||||||
|
|
||||||
|
if output_path.exists() && !utils::permission_for_overwriting(&output_path, flags, &confirm)? {
|
||||||
|
// The user does not want to overwrite the file
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes = match first_compressor {
|
||||||
|
Some(first_compressor) => {
|
||||||
|
let mut entry = Entry::Files(files);
|
||||||
|
let bytes = first_compressor.compress(entry)?;
|
||||||
|
|
||||||
|
output.contents_in_memory = Some(bytes);
|
||||||
|
entry = Entry::InMemory(output);
|
||||||
|
second_compressor.compress(entry)?
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let entry = Entry::Files(files);
|
||||||
|
second_compressor.compress(entry)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}: writing to {:?}. ({})",
|
||||||
|
"info".yellow(),
|
||||||
|
output_path,
|
||||||
|
utils::Bytes::new(bytes.len() as u64)
|
||||||
|
);
|
||||||
|
fs::write(output_path, bytes)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decompress_file(
|
||||||
|
file_path: &Path,
|
||||||
|
output: Option<&Path>,
|
||||||
|
flags: &oof::Flags,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
// 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 {
|
||||||
|
Some(inner) => Some(File::from(inner)?),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
let (first_decompressor, second_decompressor) = get_decompressor(&file)?;
|
||||||
|
|
||||||
|
let extension = file.extension.clone();
|
||||||
|
|
||||||
|
let decompression_result = second_decompressor.decompress(file, &output, &flags)?;
|
||||||
|
|
||||||
|
match decompression_result {
|
||||||
|
DecompressionResult::FileInMemory(bytes) => {
|
||||||
|
// We'll now decompress a file currently in memory.
|
||||||
|
// This will currently happen in the case of .bz, .xz and .lzma
|
||||||
|
decompress_file_in_memory(
|
||||||
|
bytes,
|
||||||
|
file_path,
|
||||||
|
first_decompressor,
|
||||||
|
output,
|
||||||
|
extension,
|
||||||
|
flags,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
DecompressionResult::FilesUnpacked(_files) => {
|
||||||
|
// If the file's last extension was an archival method,
|
||||||
|
// such as .tar, .zip or (to-do) .rar, then we won't look for
|
||||||
|
// further processing.
|
||||||
|
// The reason for this is that cases such as "file.xz.tar" are too rare
|
||||||
|
// to worry about, at least at the moment.
|
||||||
|
|
||||||
|
// TODO: use the `files` variable for something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
292
src/evaluator.rs
292
src/evaluator.rs
@ -1,292 +0,0 @@
|
|||||||
use std::{
|
|
||||||
fs,
|
|
||||||
io::Write,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use colored::Colorize;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
cli::Command,
|
|
||||||
compressors::{
|
|
||||||
BzipCompressor, Compressor, Entry, GzipCompressor, LzmaCompressor, TarCompressor,
|
|
||||||
ZipCompressor,
|
|
||||||
},
|
|
||||||
decompressors::{
|
|
||||||
BzipDecompressor, DecompressionResult, Decompressor, GzipDecompressor, LzmaDecompressor,
|
|
||||||
TarDecompressor, ZipDecompressor,
|
|
||||||
},
|
|
||||||
dialogs::Confirmation,
|
|
||||||
extension::{CompressionFormat, Extension},
|
|
||||||
file::File,
|
|
||||||
utils,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Evaluator;
|
|
||||||
|
|
||||||
type BoxedCompressor = Box<dyn Compressor>;
|
|
||||||
type BoxedDecompressor = Box<dyn Decompressor>;
|
|
||||||
|
|
||||||
impl Evaluator {
|
|
||||||
pub fn get_compressor(
|
|
||||||
file: &File,
|
|
||||||
) -> crate::Result<(Option<BoxedCompressor>, BoxedCompressor)> {
|
|
||||||
let extension = match &file.extension {
|
|
||||||
Some(extension) => extension.clone(),
|
|
||||||
None => {
|
|
||||||
// This is reached when the output file given does not have an extension or has an unsupported one
|
|
||||||
return Err(crate::Error::MissingExtensionError(file.path.to_path_buf()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Supported first compressors:
|
|
||||||
// .tar and .zip
|
|
||||||
let first_compressor: Option<Box<dyn Compressor>> = match extension.first_ext {
|
|
||||||
Some(ext) => match ext {
|
|
||||||
CompressionFormat::Tar => Some(Box::new(TarCompressor)),
|
|
||||||
CompressionFormat::Zip => Some(Box::new(ZipCompressor)),
|
|
||||||
CompressionFormat::Bzip => Some(Box::new(BzipCompressor)),
|
|
||||||
CompressionFormat::Gzip => Some(Box::new(GzipCompressor)),
|
|
||||||
CompressionFormat::Lzma => Some(Box::new(LzmaCompressor)),
|
|
||||||
},
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Supported second compressors:
|
|
||||||
// any
|
|
||||||
let second_compressor: Box<dyn Compressor> = match extension.second_ext {
|
|
||||||
CompressionFormat::Tar => Box::new(TarCompressor),
|
|
||||||
CompressionFormat::Zip => Box::new(ZipCompressor),
|
|
||||||
CompressionFormat::Bzip => Box::new(BzipCompressor),
|
|
||||||
CompressionFormat::Gzip => Box::new(GzipCompressor),
|
|
||||||
CompressionFormat::Lzma => Box::new(LzmaCompressor),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((first_compressor, second_compressor))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_decompressor(
|
|
||||||
file: &File,
|
|
||||||
) -> crate::Result<(Option<BoxedDecompressor>, BoxedDecompressor)> {
|
|
||||||
let extension = match &file.extension {
|
|
||||||
Some(extension) => extension.clone(),
|
|
||||||
None => {
|
|
||||||
// This block *should* be unreachable
|
|
||||||
eprintln!(
|
|
||||||
"{} reached Evaluator::get_decompressor without known extension.",
|
|
||||||
"[internal error]".red()
|
|
||||||
);
|
|
||||||
return Err(crate::Error::InvalidInput);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let second_decompressor: Box<dyn Decompressor> = match extension.second_ext {
|
|
||||||
CompressionFormat::Tar => Box::new(TarDecompressor),
|
|
||||||
CompressionFormat::Zip => Box::new(ZipDecompressor),
|
|
||||||
CompressionFormat::Gzip => Box::new(GzipDecompressor),
|
|
||||||
CompressionFormat::Lzma => Box::new(LzmaDecompressor),
|
|
||||||
CompressionFormat::Bzip => Box::new(BzipDecompressor),
|
|
||||||
};
|
|
||||||
|
|
||||||
let first_decompressor: Option<Box<dyn Decompressor>> = match extension.first_ext {
|
|
||||||
Some(ext) => match ext {
|
|
||||||
CompressionFormat::Tar => Some(Box::new(TarDecompressor)),
|
|
||||||
CompressionFormat::Zip => Some(Box::new(ZipDecompressor)),
|
|
||||||
_other => None,
|
|
||||||
},
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((first_decompressor, second_decompressor))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decompress_file_in_memory(
|
|
||||||
bytes: Vec<u8>,
|
|
||||||
file_path: &Path,
|
|
||||||
decompressor: Option<Box<dyn Decompressor>>,
|
|
||||||
output_file: Option<File>,
|
|
||||||
extension: Option<Extension>,
|
|
||||||
flags: &oof::Flags,
|
|
||||||
) -> crate::Result<()> {
|
|
||||||
let output_file_path = utils::get_destination_path(&output_file);
|
|
||||||
|
|
||||||
let file_name = file_path
|
|
||||||
.file_stem()
|
|
||||||
.map(Path::new)
|
|
||||||
.unwrap_or(output_file_path);
|
|
||||||
|
|
||||||
if "." == file_name.as_os_str() {
|
|
||||||
// I believe this is only possible when the supplied input has a name
|
|
||||||
// of the sort `.tar` or `.zip' and no output has been supplied.
|
|
||||||
// file_name = OsStr::new("ouch-output");
|
|
||||||
todo!("Pending review, what is this supposed to do??");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is a decompressor to use, we'll create a file in-memory and decompress it
|
|
||||||
let decompressor = match decompressor {
|
|
||||||
Some(decompressor) => decompressor,
|
|
||||||
None => {
|
|
||||||
// There is no more processing to be done on the input file (or there is but currently unsupported)
|
|
||||||
// Therefore, we'll save what we have in memory into a file.
|
|
||||||
println!("{}: saving to {:?}.", "info".yellow(), file_name);
|
|
||||||
|
|
||||||
if file_name.exists() {
|
|
||||||
let confirm =
|
|
||||||
Confirmation::new("Do you want to overwrite 'FILE'?", Some("FILE"));
|
|
||||||
if !utils::permission_for_overwriting(&file_name, flags, &confirm)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut f = fs::File::create(output_file_path.join(file_name))?;
|
|
||||||
f.write_all(&bytes)?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let file = File {
|
|
||||||
path: file_name,
|
|
||||||
contents_in_memory: Some(bytes),
|
|
||||||
extension,
|
|
||||||
};
|
|
||||||
|
|
||||||
let decompression_result = decompressor.decompress(file, &output_file, flags)?;
|
|
||||||
if let DecompressionResult::FileInMemory(_) = decompression_result {
|
|
||||||
unreachable!("Shouldn't");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compress_files(
|
|
||||||
files: Vec<PathBuf>,
|
|
||||||
output_path: &Path,
|
|
||||||
flags: &oof::Flags,
|
|
||||||
) -> crate::Result<()> {
|
|
||||||
let mut output = File::from(output_path)?;
|
|
||||||
|
|
||||||
let confirm = Confirmation::new("Do you want to overwrite 'FILE'?", Some("FILE"));
|
|
||||||
let (first_compressor, second_compressor) = Self::get_compressor(&output)?;
|
|
||||||
|
|
||||||
if output_path.exists()
|
|
||||||
&& !utils::permission_for_overwriting(&output_path, flags, &confirm)?
|
|
||||||
{
|
|
||||||
// The user does not want to overwrite the file
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let bytes = match first_compressor {
|
|
||||||
Some(first_compressor) => {
|
|
||||||
let mut entry = Entry::Files(files);
|
|
||||||
let bytes = first_compressor.compress(entry)?;
|
|
||||||
|
|
||||||
output.contents_in_memory = Some(bytes);
|
|
||||||
entry = Entry::InMemory(output);
|
|
||||||
second_compressor.compress(entry)?
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let entry = Entry::Files(files);
|
|
||||||
second_compressor.compress(entry)?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}: writing to {:?}. ({})",
|
|
||||||
"info".yellow(),
|
|
||||||
output_path,
|
|
||||||
utils::Bytes::new(bytes.len() as u64)
|
|
||||||
);
|
|
||||||
fs::write(output_path, bytes)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decompress_file(
|
|
||||||
file_path: &Path,
|
|
||||||
output: Option<&Path>,
|
|
||||||
flags: &oof::Flags,
|
|
||||||
) -> crate::Result<()> {
|
|
||||||
// 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 {
|
|
||||||
Some(inner) => Some(File::from(inner)?),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
let (first_decompressor, second_decompressor) = Self::get_decompressor(&file)?;
|
|
||||||
|
|
||||||
let extension = file.extension.clone();
|
|
||||||
|
|
||||||
let decompression_result = second_decompressor.decompress(file, &output, &flags)?;
|
|
||||||
|
|
||||||
match decompression_result {
|
|
||||||
DecompressionResult::FileInMemory(bytes) => {
|
|
||||||
// We'll now decompress a file currently in memory.
|
|
||||||
// This will currently happen in the case of .bz, .xz and .lzma
|
|
||||||
Self::decompress_file_in_memory(
|
|
||||||
bytes,
|
|
||||||
file_path,
|
|
||||||
first_decompressor,
|
|
||||||
output,
|
|
||||||
extension,
|
|
||||||
flags,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
DecompressionResult::FilesUnpacked(_files) => {
|
|
||||||
// If the file's last extension was an archival method,
|
|
||||||
// such as .tar, .zip or (to-do) .rar, then we won't look for
|
|
||||||
// further processing.
|
|
||||||
// The reason for this is that cases such as "file.xz.tar" are too rare
|
|
||||||
// to worry about, at least at the moment.
|
|
||||||
|
|
||||||
// TODO: use the `files` variable for something
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn evaluate(command: Command, flags: &oof::Flags) -> crate::Result<()> {
|
|
||||||
match command {
|
|
||||||
Command::Compress {
|
|
||||||
files,
|
|
||||||
compressed_output_path,
|
|
||||||
} => Self::compress_files(files, &compressed_output_path, flags)?,
|
|
||||||
Command::Decompress {
|
|
||||||
files,
|
|
||||||
output_folder,
|
|
||||||
} => {
|
|
||||||
// From Option<PathBuf> to Option<&Path>
|
|
||||||
let output_folder = output_folder.as_ref().map(|path| Path::new(path));
|
|
||||||
for file in files.iter() {
|
|
||||||
Self::decompress_file(file, output_folder, flags)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::ShowHelp => help_message(),
|
|
||||||
Command::ShowVersion => version_message(),
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn version_message() {
|
|
||||||
println!("ouch {}", crate::VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn help_message() {
|
|
||||||
version_message();
|
|
||||||
println!("Vinícius R. M. & João M. Bezerra");
|
|
||||||
println!("ouch is a unified compression & decompression utility");
|
|
||||||
println!();
|
|
||||||
println!(" COMPRESSION USAGE:");
|
|
||||||
println!(" ouch compress <input...> output-file");
|
|
||||||
println!("DECOMPRESSION USAGE:");
|
|
||||||
println!(" ouch <input> [-o/--output output-folder]");
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
// Public modules
|
// Public modules
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
pub mod evaluator;
|
pub mod commands;
|
||||||
|
|
||||||
// Private modules
|
// Private modules
|
||||||
mod compressors;
|
mod compressors;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use ouch::{
|
use ouch::{
|
||||||
cli::{parse_args, ParsedArgs},
|
cli::{parse_args, ParsedArgs},
|
||||||
evaluator::Evaluator,
|
commands, Result,
|
||||||
Result,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -13,5 +12,5 @@ fn main() {
|
|||||||
|
|
||||||
fn run() -> crate::Result<()> {
|
fn run() -> crate::Result<()> {
|
||||||
let ParsedArgs { command, flags } = parse_args()?;
|
let ParsedArgs { command, flags } = parse_args()?;
|
||||||
Evaluator::evaluate(command, &flags)
|
commands::run(command, &flags)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user