mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-05 02:55:31 +00:00
Add struct Extension
This commit is contained in:
parent
73398c2d50
commit
7fd6020d99
18
src/cli.rs
18
src/cli.rs
@ -4,24 +4,24 @@ use clap::{Arg, Values};
|
||||
use colored::Colorize;
|
||||
|
||||
use crate::error;
|
||||
use crate::extensions::CompressionExtension;
|
||||
use crate::extensions::CompressionFormat;
|
||||
use crate::file::File;
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub enum CommandType {
|
||||
pub enum CommandKind {
|
||||
Compression(
|
||||
// Files to be compressed
|
||||
Vec<PathBuf>,
|
||||
),
|
||||
Decompression(
|
||||
// Files to be decompressed and their extensions
|
||||
Vec<(PathBuf, CompressionExtension)>,
|
||||
Vec<(PathBuf, CompressionFormat)>,
|
||||
),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct Command {
|
||||
pub command_type: CommandType,
|
||||
pub kind: CommandKind,
|
||||
pub output: Option<File>,
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
||||
fn try_from(matches: clap::ArgMatches<'static>) -> error::OuchResult<Command> {
|
||||
let process_decompressible_input = |input_files: Values| {
|
||||
let input_files =
|
||||
input_files.map(|filename| (filename, CompressionExtension::try_from(filename)));
|
||||
input_files.map(|filename| (filename, CompressionFormat::try_from(filename)));
|
||||
|
||||
for file in input_files.clone() {
|
||||
if let (file, Err(_)) = file {
|
||||
@ -91,7 +91,7 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
||||
if output_was_supplied {
|
||||
let output_file = matches.value_of("output").unwrap(); // Safe unwrap since we've established that output was supplied
|
||||
|
||||
let output_file_extension = CompressionExtension::try_from(output_file);
|
||||
let output_file_extension = CompressionFormat::try_from(output_file);
|
||||
let output_is_compressible = output_file_extension.is_ok();
|
||||
if output_is_compressible {
|
||||
println!(
|
||||
@ -103,7 +103,7 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
||||
let input_files = input_files.map(PathBuf::from).collect();
|
||||
|
||||
return Ok(Command {
|
||||
command_type: CommandType::Compression(input_files),
|
||||
kind: CommandKind::Compression(input_files),
|
||||
output: Some(File::WithExtension((
|
||||
output_file.into(),
|
||||
output_file_extension.unwrap(),
|
||||
@ -120,7 +120,7 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
||||
output_file
|
||||
);
|
||||
return Ok(Command {
|
||||
command_type: CommandType::Decompression(input_files),
|
||||
kind: CommandKind::Decompression(input_files),
|
||||
output: Some(File::WithoutExtension(output_file.into())),
|
||||
});
|
||||
}
|
||||
@ -130,7 +130,7 @@ impl TryFrom<clap::ArgMatches<'static>> for Command {
|
||||
// Case 2: error
|
||||
let input_files = process_decompressible_input(input_files)?;
|
||||
return Ok(Command {
|
||||
command_type: CommandType::Decompression(input_files),
|
||||
kind: CommandKind::Decompression(input_files),
|
||||
output: None,
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
use std::{convert::TryFrom, path::{PathBuf}};
|
||||
|
||||
use colored::Colorize;
|
||||
|
||||
use crate::{cli::{Command, CommandKind}, error, extensions::CompressionFormat, file::File};
|
||||
|
||||
pub struct Evaluator {
|
||||
command: Command,
|
||||
// verbosity: Verbosity
|
||||
}
|
||||
|
||||
impl Evaluator {
|
||||
pub fn new(command: Command) -> Self {
|
||||
Self {
|
||||
command
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_compression(files_to_compress: &[PathBuf], output_file: &Option<File>) {
|
||||
|
||||
}
|
||||
|
||||
fn decompress_file(mut filename: &PathBuf, mut extension: CompressionFormat, output_file: &Option<File>) -> error::OuchResult<()> {
|
||||
loop {
|
||||
println!("{}: attempting to decompress '{:?}'", "ouch".bright_blue(), filename);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_decompression(files_to_decompress: &[(PathBuf, CompressionFormat)], output_file: &Option<File>) {
|
||||
for (filename, extension) in files_to_decompress {
|
||||
// println!("file: {:?}, extension: {:?}", filename, extension);
|
||||
|
||||
// TODO: actually decompress anything ;-;
|
||||
|
||||
// Once decompressed, check if the file can be decompressed further
|
||||
// e.g.: "foobar.tar.gz" -> "foobar.tar"
|
||||
|
||||
|
||||
|
||||
let filename: &PathBuf = &filename.as_path().file_stem().unwrap().into();
|
||||
match CompressionFormat::try_from(filename) {
|
||||
Ok(extension) => {
|
||||
println!("{}: attempting to decompress {:?}, ext: {:?}", "info".yellow(), filename, extension);
|
||||
},
|
||||
Err(err) => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn evaluate(&mut self) {
|
||||
match &self.command.kind {
|
||||
CommandKind::Compression(files_to_compress) => {
|
||||
Evaluator::handle_compression(files_to_compress, &self.command.output);
|
||||
}
|
||||
CommandKind::Decompression(files_to_decompress) => {
|
||||
Evaluator::handle_decompression(files_to_decompress, &self.command.output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,84 @@
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use std::{convert::TryFrom, ffi::OsStr, path::{Path, PathBuf}};
|
||||
|
||||
use crate::error;
|
||||
use CompressionFormat::*;
|
||||
|
||||
/// Represents the extension of a file, but only really caring about
|
||||
/// compression formats (and .tar).
|
||||
/// Ex.: Extension::new("file.tar.gz") == Extension { first_ext: Some(Tar), second_ext: Gzip }
|
||||
struct Extension {
|
||||
first_ext: Option<CompressionFormat>,
|
||||
second_ext: CompressionFormat
|
||||
}
|
||||
|
||||
impl Extension {
|
||||
pub fn new(filename: &str) -> error::OuchResult<Self> {
|
||||
let ext_from_str = |ext| {
|
||||
match ext {
|
||||
"zip" => Ok(Zip),
|
||||
"tar" => Ok(Tar),
|
||||
"gz" => Ok(Gzip),
|
||||
"bz" => Ok(Bzip),
|
||||
"lzma" => Ok(Lzma),
|
||||
other => Err(error::Error::UnknownExtensionError(other.into())),
|
||||
}
|
||||
};
|
||||
|
||||
let (first_ext, second_ext) = match get_extension_from_filename(filename) {
|
||||
Some(extension_tuple) => {
|
||||
match extension_tuple {
|
||||
("", snd) => (None, snd),
|
||||
(fst, snd)=> (Some(fst), snd)
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(error::Error::MissingExtensionError(filename.into()))
|
||||
}
|
||||
};
|
||||
|
||||
let (first_ext, second_ext) = match (first_ext, second_ext) {
|
||||
(None, snd) => {
|
||||
let ext = ext_from_str(snd)?;
|
||||
(None, ext)
|
||||
}
|
||||
(Some(fst), snd) => {
|
||||
let snd = ext_from_str(snd)?;
|
||||
let fst = ext_from_str(fst).ok();
|
||||
(fst, snd)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(
|
||||
Self {
|
||||
first_ext,
|
||||
second_ext
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_extension_from_filename(filename: &str) -> Option<(&str, &str)> {
|
||||
let path = Path::new(filename);
|
||||
|
||||
let ext = path
|
||||
.extension()
|
||||
.and_then(OsStr::to_str)?;
|
||||
|
||||
let previous_extension = path
|
||||
.file_stem()
|
||||
.and_then(OsStr::to_str)
|
||||
.and_then(get_extension_from_filename);
|
||||
|
||||
if let Some((_, prev)) = previous_extension {
|
||||
Some((prev, ext))
|
||||
} else {
|
||||
Some(("", ext))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
/// Accepted extensions for input and output
|
||||
pub enum CompressionExtension {
|
||||
pub enum CompressionFormat {
|
||||
// .gz
|
||||
Gzip,
|
||||
// .bz
|
||||
@ -22,11 +94,27 @@ pub enum CompressionExtension {
|
||||
// NotCompressed
|
||||
}
|
||||
|
||||
impl TryFrom<&PathBuf> for CompressionExtension {
|
||||
fn extension_from_os_str(ext: &OsStr) -> Result<CompressionFormat, error::Error> {
|
||||
|
||||
let ext = match ext.to_str() {
|
||||
Some(str) => str,
|
||||
None => return Err(error::Error::InvalidUnicode),
|
||||
};
|
||||
|
||||
match ext {
|
||||
"zip" => Ok(Zip),
|
||||
"tar" => Ok(Tar),
|
||||
"gz" => Ok(Gzip),
|
||||
"bz" => Ok(Bzip),
|
||||
"lzma" => Ok(Lzma),
|
||||
other => Err(error::Error::UnknownExtensionError(other.into())),
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&PathBuf> for CompressionFormat {
|
||||
type Error = error::Error;
|
||||
|
||||
fn try_from(ext: &PathBuf) -> Result<Self, Self::Error> {
|
||||
use CompressionExtension::*;
|
||||
|
||||
let ext = match ext.extension() {
|
||||
Some(ext) => ext,
|
||||
@ -35,43 +123,20 @@ impl TryFrom<&PathBuf> for CompressionExtension {
|
||||
}
|
||||
};
|
||||
|
||||
let ext = match ext.to_str() {
|
||||
Some(str) => str,
|
||||
None => return Err(error::Error::InvalidUnicode),
|
||||
};
|
||||
|
||||
match ext {
|
||||
"zip" => Ok(Zip),
|
||||
"tar" => Ok(Tar),
|
||||
"gz" => Ok(Gzip),
|
||||
"bz" => Ok(Bzip),
|
||||
"lzma" => Ok(Lzma),
|
||||
other => Err(error::Error::UnknownExtensionError(other.into())),
|
||||
}
|
||||
extension_from_os_str(ext)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for CompressionExtension {
|
||||
impl TryFrom<&str> for CompressionFormat {
|
||||
type Error = error::Error;
|
||||
|
||||
fn try_from(filename: &str) -> Result<Self, Self::Error> {
|
||||
use CompressionExtension::*;
|
||||
|
||||
let filename = Path::new(filename);
|
||||
let ext = match filename.extension() {
|
||||
Some(ext) => ext,
|
||||
None => return Err(error::Error::MissingExtensionError(String::new())),
|
||||
};
|
||||
|
||||
let ext = match ext.to_str() {
|
||||
Some(str) => str,
|
||||
None => return Err(error::Error::InvalidUnicode),
|
||||
};
|
||||
|
||||
match ext {
|
||||
"zip" => Ok(Zip),
|
||||
"tar" => Ok(Tar),
|
||||
other => Err(error::Error::UnknownExtensionError(other.into())),
|
||||
}
|
||||
extension_from_os_str(ext)
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::extensions::CompressionExtension;
|
||||
use crate::extensions::CompressionFormat;
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub enum File {
|
||||
WithExtension((PathBuf, CompressionExtension)),
|
||||
WithExtension((PathBuf, CompressionFormat)),
|
||||
WithoutExtension(PathBuf),
|
||||
}
|
47
src/main.rs
47
src/main.rs
@ -1,4 +1,6 @@
|
||||
use std::convert::TryFrom;
|
||||
use std::{convert::TryFrom, ffi::OsStr, path::Path};
|
||||
|
||||
use colored::Colorize;
|
||||
|
||||
mod cli;
|
||||
mod error;
|
||||
@ -8,38 +10,17 @@ mod test;
|
||||
mod evaluator;
|
||||
|
||||
fn main() {
|
||||
// Just testing
|
||||
|
||||
// let args: Vec<String> = std::env::args().collect();
|
||||
|
||||
// let file = std::fs::read(args[1].clone()).unwrap();
|
||||
|
||||
// match niffler::sniff(Box::new(&file[..])) {
|
||||
// Ok((reader, compression)) => {},
|
||||
// Err(err) => {}
|
||||
// let matches = cli::get_matches();
|
||||
// match cli::Command::try_from(matches) {
|
||||
// Ok(command) => {
|
||||
// let mut eval = evaluator::Evaluator::new(command);
|
||||
// eval.evaluate();
|
||||
// }
|
||||
// Err(err) => {
|
||||
// print!("{}: {}\n", "error".red(), err);
|
||||
// }
|
||||
// }
|
||||
|
||||
// let (mut reader, compression) = niffler::sniff(Box::new(&file[..])).unwrap();
|
||||
|
||||
// match compression {
|
||||
// niffler::Format::Gzip => {}
|
||||
// niffler::Format::Bzip => {}
|
||||
// niffler::Format::Lzma => {}
|
||||
// niffler::Format::No => {}
|
||||
// }
|
||||
|
||||
// let mut contents = String::new();
|
||||
// println!("Contents: {}", reader.read_to_string(&mut contents).unwrap());
|
||||
|
||||
// dbg!(compression);
|
||||
|
||||
let matches = cli::get_matches();
|
||||
match cli::Command::try_from(matches) {
|
||||
Ok(vals) => {
|
||||
dbg!(vals);
|
||||
}
|
||||
Err(err) => {
|
||||
print!("{}\n", err);
|
||||
}
|
||||
}
|
||||
dbg!(extensions::get_extension_from_filename("file"));
|
||||
// dbg!(get_extension_from_filename("file.zip"));
|
||||
}
|
||||
|
32
src/test.rs
32
src/test.rs
@ -3,9 +3,9 @@ mod cli {
|
||||
|
||||
use crate::cli::clap_app;
|
||||
use crate::cli::Command;
|
||||
use crate::cli::CommandType::*;
|
||||
use crate::cli::CommandKind::*;
|
||||
use crate::error::OuchResult;
|
||||
use crate::extensions::CompressionExtension::*;
|
||||
use crate::extensions::CompressionFormat::*;
|
||||
use crate::file::File;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
@ -17,7 +17,7 @@ mod cli {
|
||||
assert_eq!(
|
||||
command_from_matches,
|
||||
Command {
|
||||
command_type: Decompression(vec![("file.zip".into(), Zip,),],),
|
||||
kind: Decompression(vec![("file.zip".into(), Zip,),],),
|
||||
output: Some(File::WithoutExtension("folder".into())),
|
||||
}
|
||||
);
|
||||
@ -33,7 +33,7 @@ mod cli {
|
||||
assert_eq!(
|
||||
command_from_matches,
|
||||
Command {
|
||||
command_type: Decompression(vec![
|
||||
kind: Decompression(vec![
|
||||
("file.zip".into(), Zip,),
|
||||
("file.tar".into(), Tar,),
|
||||
],),
|
||||
@ -60,7 +60,7 @@ mod cli {
|
||||
assert_eq!(
|
||||
command_from_matches,
|
||||
Command {
|
||||
command_type: Compression(vec![
|
||||
kind: Compression(vec![
|
||||
"file".into(),
|
||||
"file2.jpeg".into(),
|
||||
"file3.ok".into()
|
||||
@ -101,15 +101,15 @@ mod cli_errors {
|
||||
#[cfg(test)]
|
||||
mod extension_extraction {
|
||||
use crate::error::OuchResult;
|
||||
use crate::extensions::CompressionExtension;
|
||||
use crate::extensions::CompressionFormat;
|
||||
use std::{convert::TryFrom, path::PathBuf, str::FromStr};
|
||||
|
||||
#[test]
|
||||
fn zip() -> OuchResult<()> {
|
||||
let path = PathBuf::from_str("filename.tar.zip").unwrap();
|
||||
assert_eq!(
|
||||
CompressionExtension::try_from(&path)?,
|
||||
CompressionExtension::Zip
|
||||
CompressionFormat::try_from(&path)?,
|
||||
CompressionFormat::Zip
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@ -119,8 +119,8 @@ mod extension_extraction {
|
||||
fn tar() -> OuchResult<()> {
|
||||
let path = PathBuf::from_str("pictures.tar").unwrap();
|
||||
assert_eq!(
|
||||
CompressionExtension::try_from(&path)?,
|
||||
CompressionExtension::Tar
|
||||
CompressionFormat::try_from(&path)?,
|
||||
CompressionFormat::Tar
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@ -130,8 +130,8 @@ mod extension_extraction {
|
||||
fn gz() -> OuchResult<()> {
|
||||
let path = PathBuf::from_str("passwords.tar.gz").unwrap();
|
||||
assert_eq!(
|
||||
CompressionExtension::try_from(&path)?,
|
||||
CompressionExtension::Gzip
|
||||
CompressionFormat::try_from(&path)?,
|
||||
CompressionFormat::Gzip
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@ -141,8 +141,8 @@ mod extension_extraction {
|
||||
fn lzma() -> OuchResult<()> {
|
||||
let path = PathBuf::from_str("mygame.tar.lzma").unwrap();
|
||||
assert_eq!(
|
||||
CompressionExtension::try_from(&path)?,
|
||||
CompressionExtension::Lzma
|
||||
CompressionFormat::try_from(&path)?,
|
||||
CompressionFormat::Lzma
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@ -152,8 +152,8 @@ mod extension_extraction {
|
||||
fn bz() -> OuchResult<()> {
|
||||
let path = PathBuf::from_str("songs.tar.bz").unwrap();
|
||||
assert_eq!(
|
||||
CompressionExtension::try_from(&path)?,
|
||||
CompressionExtension::Bzip
|
||||
CompressionFormat::try_from(&path)?,
|
||||
CompressionFormat::Bzip
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
Loading…
x
Reference in New Issue
Block a user