From 0b346eee3d7dac6afd23c18cecb9e45323fac7b1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vin=C3=ADcius=20Rodrigues=20Miguel?= Date: Wed, 24 Mar 2021 17:40:38 -0300 Subject: [PATCH] Fixes Gzip and Lzma compression --- src/compressors/gzip.rs | 72 ++++++++++++++++++++++++++++ src/compressors/lzma.rs | 69 +++++++++++++++++++++++++++ src/compressors/mod.rs | 7 +-- src/compressors/tar.rs | 4 +- src/compressors/tomemory.rs | 114 -------------------------------------------- 5 files changed, 147 insertions(+), 119 deletions(-) create mode 100644 src/compressors/gzip.rs create mode 100644 src/compressors/lzma.rs delete mode 100644 src/compressors/tomemory.rs diff --git a/src/compressors/gzip.rs b/src/compressors/gzip.rs new file mode 100644 index 0000000..135d8cf --- /dev/null +++ b/src/compressors/gzip.rs @@ -0,0 +1,72 @@ +use std::{fs, io::Write, path::PathBuf}; + +use colored::Colorize; + +use crate::{error::{Error, OuchResult}, extension::CompressionFormat, file::File}; +use crate::utils::ensure_exists; + +use super::{Compressor, Entry}; + +pub struct GzipCompressor {} + +impl GzipCompressor { + pub fn compress_files(files: Vec, format: CompressionFormat) -> OuchResult> { + if files.len() != 1 { + eprintln!("{}: cannot compress multiple files directly to {:#?}.\n Try using an intermediate archival method such as Tar.\n Example: filename.tar{}", "error".red(), format, format); + return Err(Error::InvalidInput); + } + + let path = &files[0]; + ensure_exists(path)?; + + let bytes = { + let bytes = fs::read(path)?; + Self::compress_bytes(bytes)? + }; + + println!( + "{}: compressed {:?} into memory ({} bytes)", + "info".yellow(), + &path, + bytes.len() + ); + + Ok(bytes) + } + + pub fn compress_file_in_memory(file: File) -> OuchResult> { + let file_contents = match file.contents_in_memory { + Some(bytes) => bytes, + None => { + unreachable!(); + } + }; + + Ok(Self::compress_bytes(file_contents)?) + } + + pub fn compress_bytes(bytes_to_compress: Vec) -> OuchResult> { + let buffer = vec![]; + let mut encoder = flate2::write::GzEncoder::new( + buffer, + flate2::Compression::default(), + ); + encoder.write_all(&*bytes_to_compress)?; + + Ok(encoder.finish()?) + } +} + +impl Compressor for GzipCompressor { + fn compress(&self, from: Entry) -> OuchResult> { + let format = CompressionFormat::Gzip; + match from { + Entry::Files(files) => Ok( + Self::compress_files(files, format)? + ), + Entry::InMemory(file) => Ok( + Self::compress_file_in_memory(file)? + ), + } + } +} diff --git a/src/compressors/lzma.rs b/src/compressors/lzma.rs new file mode 100644 index 0000000..8d37224 --- /dev/null +++ b/src/compressors/lzma.rs @@ -0,0 +1,69 @@ +use std::{fs, io::Write, path::PathBuf}; + +use colored::Colorize; + +use crate::{error::{Error, OuchResult}, extension::CompressionFormat, file::File}; +use crate::utils::ensure_exists; + +use super::{Compressor, Entry}; + +pub struct LzmaCompressor {} + +impl LzmaCompressor { + pub fn compress_files(files: Vec, format: CompressionFormat) -> OuchResult> { + if files.len() != 1 { + eprintln!("{}: cannot compress multiple files directly to {:#?}.\n Try using an intermediate archival method such as Tar.\n Example: filename.tar{}", "error".red(), format, format); + return Err(Error::InvalidInput); + } + + let path = &files[0]; + ensure_exists(path)?; + + let bytes = { + let bytes = fs::read(path)?; + Self::compress_bytes(bytes)? + }; + + println!( + "{}: compressed {:?} into memory ({} bytes)", + "info".yellow(), + &path, + bytes.len() + ); + + Ok(bytes) + } + + pub fn compress_file_in_memory(file: File) -> OuchResult> { + let file_contents = match file.contents_in_memory { + Some(bytes) => bytes, + None => { + unreachable!(); + } + }; + + Ok(Self::compress_bytes(file_contents)?) + } + + pub fn compress_bytes(bytes_to_compress: Vec) -> OuchResult> { + let buffer = vec![]; + let mut encoder = xz2::write::XzEncoder::new(buffer, 6); + encoder.write_all(&*bytes_to_compress)?; + + Ok(encoder.finish()?) + } +} + +impl Compressor for LzmaCompressor { + fn compress(&self, from: Entry) -> OuchResult> { + let format = CompressionFormat::Lzma; + match from { + Entry::Files(files) => Ok( + Self::compress_files(files, format)? + ), + Entry::InMemory(file) => Ok( + Self::compress_file_in_memory(file)? + ), + } + } +} \ No newline at end of file diff --git a/src/compressors/mod.rs b/src/compressors/mod.rs index ad0ec85..d8b075a 100644 --- a/src/compressors/mod.rs +++ b/src/compressors/mod.rs @@ -1,7 +1,8 @@ mod tar; mod zip; mod bzip; -mod tomemory; +mod gzip; +mod lzma; mod compressor; pub use compressor::Compressor; @@ -9,5 +10,5 @@ pub use self::compressor::Entry; pub use self::tar::TarCompressor; pub use self::zip::ZipCompressor; pub use self::bzip::BzipCompressor; -pub use self::tomemory::GzipCompressor; -pub use self::tomemory::LzmaCompressor; \ No newline at end of file +pub use self::gzip::GzipCompressor; +pub use self::lzma::LzmaCompressor; \ No newline at end of file diff --git a/src/compressors/tar.rs b/src/compressors/tar.rs index fa57175..8900c16 100644 --- a/src/compressors/tar.rs +++ b/src/compressors/tar.rs @@ -1,7 +1,7 @@ use std::{fs, path::PathBuf}; use colored::Colorize; -use tar::{Builder, EntryType, Header}; +use tar::Builder; use walkdir::WalkDir; use crate::{compressors::Compressor, error::{Error, OuchResult}, file::File}; @@ -15,7 +15,7 @@ impl TarCompressor { // TODO: this function does not seem to be working correctly ;/ fn make_archive_from_memory(input: File) -> OuchResult> { - let contents = match input.contents_in_memory { + let _contents = match input.contents_in_memory { Some(bytes) => bytes, None => { eprintln!("{}: reached TarCompressor::make_archive_from_memory without known content.", "internal error".red()); diff --git a/src/compressors/tomemory.rs b/src/compressors/tomemory.rs deleted file mode 100644 index 152d7ee..0000000 --- a/src/compressors/tomemory.rs +++ /dev/null @@ -1,114 +0,0 @@ -use std::{fs, io::{self, Read}, path::PathBuf}; - -use colored::Colorize; - -use crate::{error::{Error, OuchResult}, extension::CompressionFormat, file::File}; -use crate::utils::ensure_exists; - -use super::{Compressor, Entry}; - -pub struct GzipCompressor {} -pub struct LzmaCompressor {} - -struct CompressorToMemory {} - -impl CompressorToMemory { - pub fn compress_files(files: Vec, format: CompressionFormat) -> OuchResult> { - - - if files.len() != 1 { - eprintln!("{}: cannot compress multiple files directly to {:#?}.\n Try using an intermediate archival method such as Tar.\n Example: filename.tar{}", "error".red(), format, format); - return Err(Error::InvalidInput); - } - - let mut contents = Vec::new(); - let path = &files[0]; - ensure_exists(path)?; - - let bytes_written = { - let bytes = fs::read(path)?; - - // let mut buffer = vec![]; - // let mut encoder = get_encoder(&format, Box::new(&mut buffer)); - // encoder.write_all(&*bytes)?; - // bytes.as_slice().read_to_end(&mut contents)? - Self::compress_bytes(&mut contents, bytes, format)? - }; - - println!( - "{}: compressed {:?} into memory ({} bytes)", - "info".yellow(), - &path, - bytes_written - ); - - Ok(contents) - } - - pub fn compress_file_in_memory(file: File, format:CompressionFormat ) -> OuchResult> { - let mut compressed_contents = Vec::new(); - let file_contents = match file.contents_in_memory { - Some(bytes) => bytes, - None => { - unreachable!(); - } - }; - - let _bytes_written = Self::compress_bytes(&mut compressed_contents, file_contents, format); - - Ok(compressed_contents) - } - - pub fn compress_bytes(mut contents: &mut Vec, bytes_to_compress: Vec, format: CompressionFormat) -> OuchResult { - let mut buffer = vec![]; - let mut encoder = get_encoder(&format, Box::new(&mut buffer)); - encoder.write_all(&*bytes_to_compress)?; - - Ok(bytes_to_compress.as_slice().read_to_end(&mut contents)?) - } - - -} - -fn get_encoder<'a>( - format: &CompressionFormat, - buffer: Box, -) -> Box { - match format { - CompressionFormat::Gzip => Box::new(flate2::write::GzEncoder::new( - buffer, - flate2::Compression::default(), - )), - CompressionFormat::Lzma => Box::new(xz2::write::XzEncoder::new(buffer, 6)), - _other => unreachable!(), - } -} - -impl Compressor for GzipCompressor { - fn compress(&self, from: Entry) -> OuchResult> { - let format = CompressionFormat::Gzip; - match from { - Entry::Files(files) => Ok( - CompressorToMemory::compress_files(files, format)? - ), - Entry::InMemory(file) => Ok( - CompressorToMemory::compress_file_in_memory(file, format)? - ), - } - } -} - - -impl Compressor for LzmaCompressor { - fn compress(&self, from: Entry) -> OuchResult> { - let format = CompressionFormat::Lzma; - match from { - Entry::Files(files) => Ok( - CompressorToMemory::compress_files(files, format)? - ), - Entry::InMemory(file) => Ok( - CompressorToMemory::compress_file_in_memory(file, format)? - ), - } - } -} \ No newline at end of file -- 2.11.4.GIT