diff --git a/src/compressors/bzip.rs b/src/compressors/bzip.rs index f66ef8d..d34866d 100644 --- a/src/compressors/bzip.rs +++ b/src/compressors/bzip.rs @@ -1,4 +1,4 @@ -use std::{fs, io::{self, Read, Write}, path::PathBuf}; +use std::{fs, io::Write, path::PathBuf}; use colored::Colorize; @@ -9,38 +9,6 @@ use super::{Compressor, Entry}; pub struct BzipCompressor {} -struct CompressorToMemory {} - -// impl CompressorToMemory { -// pub fn compress_files(files: Vec, format: CompressionFormat) -> OuchResult> { -// let mut buffer = vec![]; - -// 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_read = { -// let bytes = fs::read(path)?; -// let mut encoder = get_encoder(&format, Box::new(&mut buffer)); -// encoder.write_all(&*bytes)?; -// bytes.as_slice().read_to_end(&mut contents)? -// }; - -// println!("{}: compressed {:?} into memory ({} bytes)", "info".yellow(), &path, bytes_read); - -// Ok(contents) -// } - -// pub fn compress_bytes(file: File) { - -// } -// } - impl BzipCompressor { fn compress_files(files: Vec, format: CompressionFormat) -> OuchResult> { if files.len() != 1 { @@ -82,13 +50,6 @@ impl BzipCompressor { } // TODO: customizable compression level -fn get_encoder<'a>(format: &CompressionFormat, buffer: Box) -> Box { - match format { - CompressionFormat::Bzip => Box::new(bzip2::write::BzEncoder::new(buffer, bzip2::Compression::new(4))), - _other => unreachable!() - } -} - impl Compressor for BzipCompressor { fn compress(&self, from: Entry) -> OuchResult> { match from { diff --git a/src/compressors/mod.rs b/src/compressors/mod.rs index fd1e83c..93336d4 100644 --- a/src/compressors/mod.rs +++ b/src/compressors/mod.rs @@ -1,6 +1,7 @@ mod tar; mod zip; mod bzip; +mod tomemory; mod compressor; pub use compressor::Compressor; @@ -8,3 +9,4 @@ 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; \ No newline at end of file diff --git a/src/compressors/tar.rs b/src/compressors/tar.rs index 84d53e1..fa57175 100644 --- a/src/compressors/tar.rs +++ b/src/compressors/tar.rs @@ -23,25 +23,8 @@ impl TarCompressor { } }; - // let ok = EntryType:: + println!("todo"); - - // let mut b = Builder::new(Vec::new()); - // let mut header = Header::new_gnu(); - // let name = b"././@LongLink"; - // header.as_gnu_mut().unwrap().name[..name.len()].clone_from_slice(&name[..]); - // header.set_mode(0o644); - // header.set_uid(0); - // header.set_gid(0); - // header.set_mtime(0); - // // + 1 to be compliant with GNU tar - // header.set_size(size + 1); - // header.set_entry_type(EntryType::new(entry_type)); - // header.set_cksum(); - - - - // Ok(b.into_inner()?) Ok(vec![]) } diff --git a/src/compressors/tomemory.rs b/src/compressors/tomemory.rs new file mode 100644 index 0000000..66db3ea --- /dev/null +++ b/src/compressors/tomemory.rs @@ -0,0 +1,97 @@ +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 {} + +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(), + )), + _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)? + ), + } + } +} \ No newline at end of file diff --git a/src/evaluator.rs b/src/evaluator.rs index 963448b..b245d82 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -7,6 +7,7 @@ use crate::compressors::{ Compressor, TarCompressor, ZipCompressor, + GzipCompressor, BzipCompressor, }; @@ -71,6 +72,7 @@ impl Evaluator { CompressionFormat::Tar => Box::new(TarCompressor {}), CompressionFormat::Zip => Box::new(ZipCompressor {}), CompressionFormat::Bzip => Box::new(BzipCompressor {}), + CompressionFormat::Gzip => Box::new(GzipCompressor {}), _other => todo!() };