First commit

This commit is contained in:
Vinícius Rodrigues Miguel 2021-03-19 04:40:19 -03:00
commit 08489b028c
10 changed files with 914 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

416
Cargo.lock generated Normal file
View File

@ -0,0 +1,416 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "addr2line"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "bgzip"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adff113e9fe73a6d0c4efd0f143857bd6bdad40743542f3f57464398c532234f"
dependencies = [
"failure",
"flate2",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bzip2"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf8012c8a15d5df745fcf258d93e6149dcf102882c8d8702d9cff778eab43a8"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.10+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17fa3d1ac1ca21c5c4e36a97f3c3eb25084576f6fc47bf0139c1123434216c6c"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "cc"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "colored"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if",
]
[[package]]
name = "enum_primitive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
dependencies = [
"num-traits 0.1.43",
]
[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "flate2"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
dependencies = [
"cfg-if",
"crc32fast",
"libc",
"miniz_oxide",
]
[[package]]
name = "gimli"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
[[package]]
name = "lzma-sys"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb4b7c3eddad11d3af9e86c487607d2d2442d185d848575365c4856ba96d619"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "niffler"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ea40fb13399dd0e9780ea3d82cb6cf27f489f63d820aa7dc9ec967750dc6d58"
dependencies = [
"bgzip",
"bzip2",
"cfg-if",
"enum_primitive",
"flate2",
"thiserror",
"xz2",
]
[[package]]
name = "num-traits"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
dependencies = [
"num-traits 0.2.14",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "object"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
[[package]]
name = "ouch"
version = "0.1.0"
dependencies = [
"clap",
"colored",
"niffler",
]
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustc-demangle"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "synstructure"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xz2"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c"
dependencies = [
"lzma-sys",
]

12
Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "ouch"
version = "0.1.0"
authors = ["Vinícius Rodrigues Miguel <lemao.vrm07@hotmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
colored = "2.0.0"
niffler = "2.3.1"
clap = "2.33.3"

67
README.md Normal file
View File

@ -0,0 +1,67 @@
# ouch
`ouch` is the Obvious Unified Compression (and decompression) Helper.
## How does it work?
`ouch` infers commands from the extensions of its command-line options.
```
ouch 0.1.0
ouch is a unified compression & decompression utility
USAGE:
ouch [OPTIONS] --input <input>...
FLAGS:
-h, --help Displays this message and exits
-V, --version Prints version information
OPTIONS:
-i, --input <input>... Input files (TODO description)
-o, --output <output> Output file (TODO description)
```
### Examples
#### Decompressing a bunch of files
```bash
$ ouch -i file{1..5}.zip
info: attempting to decompress input files into single_folder
info: done!
```
When no output file is supplied, `ouch` infers that it must decompress all of its input files. This will error if any of the input files are not decompressable.
#### Decompressing a bunch of files into a folder
```bash
$ ouch -i file{1..5}.tar.gz -o some-folder
info: attempting to decompress input files into single_folder
info: done!
```
When the output file is not a compressed file, `ouch` will check if all input files are decompressable and infer that it must decompress them into the output file.
#### Compressing files
```bash
$ ouch -i file{1..20} -o archive.tar
info: trying to compress input files into 'archive.tar'
info: done!
```
### Error scenarios
#### No clear decompression algorithm
```bash
$ ouch -i some-file -o some-folder
error: file 'some-file' is not decompressable.
```
`ouch` might (TODO!) be able to sniff a file's compression format if it isn't supplied in the future, but that is not currently implemented.

218
src/cli.rs Normal file
View File

@ -0,0 +1,218 @@
use std::{convert::TryFrom, ffi::OsStr, path::PathBuf, vec::Vec};
use clap::{Arg};
use colored::Colorize;
use crate::error;
use crate::extensions::CompressionExtension;
use crate::file::File;
#[derive(Debug)]
pub enum CommandType {
Compression(
// Files to be compressed
Vec<PathBuf>,
),
Decompression(
// Files to be decompressed and their extensions
Vec<(PathBuf, CompressionExtension)>,
),
}
#[derive(Debug)]
pub struct Command {
pub command_type: CommandType,
pub output: Option<File>,
}
pub fn get_matches() -> clap::ArgMatches<'static> {
clap::App::new("ouch")
.version("0.1.0")
.about("ouch is a unified compression & decompression utility")
.help_message("Displays this message and exits")
.settings(&[
clap::AppSettings::ColoredHelp,
clap::AppSettings::ArgRequiredElseHelp,
])
.arg(
Arg::with_name("input")
.required(true)
.multiple(true)
.long("input")
.short("i")
.help("Input files (TODO description)")
.takes_value(true),
)
.arg(
Arg::with_name("output")
// --output/-o not required when output can be inferred from the input files
.required(false)
.multiple(false)
.long("output")
.short("o")
.help("Output file (TODO description)")
.takes_value(true),
)
.get_matches()
}
// holy spaghetti code
impl TryFrom<clap::ArgMatches<'static>> for Command {
type Error = error::Error;
fn try_from(matches: clap::ArgMatches<'static>) -> error::OuchResult<Command> {
// Possibilities:
// * Case 1: output not supplied, therefore try to infer output by checking if all input files are decompressable
// * Case 2: output supplied
let output_was_supplied = matches.is_present("output");
if output_was_supplied {
let output_file = matches
.value_of("output")
.unwrap(); // Safe unwrap since we've established that output was supplied
let input_files = matches
.values_of("input")
.unwrap(); // Safe to unwrap since input is an obligatory argument
// .map(PathBuf::from)
// .collect();
let output_file_extension = CompressionExtension::try_from(output_file);
let output_is_compressable = output_file_extension.is_ok();
if output_is_compressable {
println!("{}: trying to compress input files into '{}'", "info".yellow(), output_file);
let input_files = input_files.map(PathBuf::from).collect();
return Ok(
Command {
command_type: CommandType::Compression(input_files),
output: Some(File::WithExtension(
(output_file.into(), output_file_extension.unwrap())
))
}
);
}
else {
// Checking if input files are decompressable
let input_files = input_files
.map(|filename| (filename, CompressionExtension::try_from(filename)));
for file in input_files.clone() {
if let (file, Err(_)) = file {
eprintln!("{}: file '{}' is not decompressable.", "error".red(), file);
return Err(error::Error::InputsMustHaveBeenDecompressable(file.into()));
}
}
let input_files =
input_files
.map(|(filename, extension)|
(PathBuf::from(filename), extension.unwrap())
)
.collect();
println!("{}: attempting to decompress input files into {}", "info".yellow(), output_file);
return Ok(
Command {
command_type: CommandType::Decompression(input_files),
output: Some(File::WithoutExtension(output_file.into()))
}
);
}
} else {
// BIG TODO
Err(error::Error::MissingExtensionError("placeholder result".into()))
}
}
}
// impl TryFrom<clap::ArgMatches<'static>> for ArgValues {
// type Error = error::OuchError;
// fn try_from(matches: clap::ArgMatches<'static>) -> error::OuchResult<ArgValues> {
// // Case 1: -o was set
// // Case 1.1: -o was set and has a (supported) compression file extension
// // |--> Compress all input files into the supplied output file (no extension checks on inputs)
// // Case 1.2: -o was set and is not a supported expression
// // Case 2: -o was not set
// // Case 2.1: -o was not set and all input files are (supported) compression file extensions
// // |--> Decompress input files into inferred filenames or directories
// // Case 2.2: -o was not set and not all input files are (supported) compression file extensions
// // |--> Issue an error
// let inputs = matches
// .values_of("input")
// .unwrap() // Safe to unwrap since this is a required argument
// .map(|input: &str| {
// (
// PathBuf::from(input),
// CompressionExtension::try_from(input).ok(),
// )
// });
// let output_was_supplied = matches.is_present("output");
// let inputs_are_compressed_files = inputs.clone().all(|(_, ext)| ext.is_some());
// match (output_was_supplied, inputs_are_compressed_files) {
// (true, true) => {
// // -o was set and inputs are all valid compressed files
// let output = matches.value_of("output").unwrap();
// let output = PathBuf::from(output);
// match CompressionExtension::try_from(&output) {
// Ok(ext) => {
// // If the output file is a valid compressed file, then we compress the input files into it
// Ok(Self {
// command_type: CommandType::Compress(
// inputs.map(|(path, _)| path).collect(),
// ),
// output: Some((output, ext)),
// })
// }
// Err(_) => {
// // If the output file is not a compressed file, then we decompress the input files into it
// Ok(Self {
// command_type: CommandType::Decompress(
// inputs.map(|(path, ext)| (path, ext.unwrap())).collect(),
// ),
// output: Some((output, CompressionExtension::NotCompressed)),
// })
// }
// }
// }
// (true, false) => {
// // -o was set and inputs are not (all) valid compressed files
// let output_str = matches.value_of("output").unwrap();
// let output = PathBuf::from(output_str);
// let output_ext = match CompressionExtension::try_from(&output) {
// Ok(ext) => ext,
// Err(_) => {
// return Err(error::OuchError::MissingExtensionError(output_str.into()));
// }
// };
// Ok(Self {
// command_type: CommandType::Compress(inputs.map(|(path, _)| path).collect()),
// output: Some((output, output_ext)),
// })
// }
// (false, true) => {
// // Case 2.1: -o was not set and all input files are (supported) compression file extensions
// Ok(Self {
// command_type: CommandType::Decompress(
// inputs.map(|(path, ext)| (path, ext.unwrap())).collect(),
// ),
// output: None,
// })
// }
// (false, false) => {
// // Case 2.2: -o was not set and not all input files are not (supported) compression file extensions
// Err(error::OuchError::InvalidInput)
// }
// }
// }
// }

38
src/error.rs Normal file
View File

@ -0,0 +1,38 @@
use std::{fmt, path::PathBuf};
use colored::Colorize;
#[derive(Debug)]
pub enum Error {
UnknownExtensionError(String),
MissingExtensionError(String),
InvalidUnicode,
InvalidInput,
InputsMustHaveBeenDecompressable(String)
}
// This should be placed somewhere else
pub type OuchResult<T> = Result<T, Error>;
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Error::*;
match self {
InvalidInput => write!(
f,
"When `-o/--output` is omitted, all input files should be compressed files."
),
Error::MissingExtensionError(filename) => {
write!(f, "cannot compress to \'{}\', likely because it has an unsupported (or missing) extension.", filename)
}
Error::InputsMustHaveBeenDecompressable(file) => {
write!(f, "file '{}' is not decompressable", file.red())
}
_ => {
// TODO
write!(f, "")
}
}
}
}

74
src/extensions.rs Normal file
View File

@ -0,0 +1,74 @@
use std::{
convert::TryFrom,
path::{Path, PathBuf},
};
use crate::error;
#[derive(Debug)]
/// Accepted extensions for input and output
pub enum CompressionExtension {
// .gz
Gzip,
// .bz
Bzip,
// .lzma
Lzma,
// .tar (technically not a compression extension, but will do for now)
Tar,
// .zip
Zip,
// Not a supported compressed file extension (any other file)
// TODO: it makes no sense for this variant to exist here
// NotCompressed
}
impl TryFrom<&PathBuf> for CompressionExtension {
type Error = error::Error;
fn try_from(ext: &PathBuf) -> Result<Self, Self::Error> {
use CompressionExtension::*;
let ext = match ext.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())),
}
}
}
impl TryFrom<&str> for CompressionExtension {
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())),
}
}
}

43
src/file.rs Normal file
View File

@ -0,0 +1,43 @@
use std::{convert::TryFrom, path::PathBuf, str::FromStr};
use crate::error::Error as OuchError;
use crate::error;
use crate::extensions::CompressionExtension;
// pub type File = (PathBuf, CompressionExtension);
// #[derive(Debug)]
// pub struct FileWithExtension {
// pub extension: CompressionExtension,
// pub filename: PathBuf,
// }
#[derive(Debug)]
pub enum File {
WithExtension((PathBuf, CompressionExtension)),
WithoutExtension(PathBuf)
}
// impl TryFrom<String> for FileWithExtension {
// type Error = OuchError;
// fn try_from(filename: String) -> error::OuchResult<Self> {
// // Safe to unwrap (infallible operation)
// let filename = PathBuf::from_str(&filename).unwrap();
// let os_str = match filename.extension() {
// Some(os_str) => os_str,
// None => return Err(OuchError::MissingExtensionError(filename.to_string_lossy().to_string())),
// };
// let extension = match CompressionExtension::try_from(os_str.into()) {
// Ok(ext) => ext,
// Err(err) => return Err(err),
// };
// Ok(Self {
// filename,
// extension,
// })
// }
// }

45
src/main.rs Normal file
View File

@ -0,0 +1,45 @@
use std::{convert::TryFrom, fs::File};
use cli::get_matches;
mod cli;
mod file;
mod extensions;
mod error;
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 (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 = get_matches();
match cli::Command::try_from(matches) {
Ok(vals) => { dbg!(vals); },
Err(err) => {
print!("{}\n", err);
}
}
}

0
src/test.rs Normal file
View File