mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-05 02:55:31 +00:00
Fixes Gzip and Lzma compression
This commit is contained in:
parent
f3dd4d9804
commit
0b346eee3d
72
src/compressors/gzip.rs
Normal file
72
src/compressors/gzip.rs
Normal file
@ -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<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
|
||||
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<Vec<u8>> {
|
||||
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<u8>) -> OuchResult<Vec<u8>> {
|
||||
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<Vec<u8>> {
|
||||
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)?
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
69
src/compressors/lzma.rs
Normal file
69
src/compressors/lzma.rs
Normal file
@ -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<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
|
||||
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<Vec<u8>> {
|
||||
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<u8>) -> OuchResult<Vec<u8>> {
|
||||
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<Vec<u8>> {
|
||||
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)?
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
pub use self::gzip::GzipCompressor;
|
||||
pub use self::lzma::LzmaCompressor;
|
@ -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<Vec<u8>> {
|
||||
|
||||
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());
|
||||
|
@ -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<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
|
||||
|
||||
|
||||
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<Vec<u8>> {
|
||||
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<u8>, bytes_to_compress: Vec<u8>, format: CompressionFormat) -> OuchResult<usize> {
|
||||
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<dyn io::Write + Send + 'a>,
|
||||
) -> Box<dyn io::Write + Send + 'a> {
|
||||
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<Vec<u8>> {
|
||||
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<Vec<u8>> {
|
||||
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)?
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user