Fixes Gzip and Lzma compression
[ouch.git] / src / compressors / bzip.rs
blobd34866d1501e0f387290aad2fb6468e05092060b
1 use std::{fs, io::Write, path::PathBuf};
3 use colored::Colorize;
5 use crate::{error::{Error, OuchResult}, extension::CompressionFormat, file::File};
6 use crate::utils::ensure_exists;
8 use super::{Compressor, Entry};
10 pub struct BzipCompressor {}
12 impl BzipCompressor {
13     fn compress_files(files: Vec<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
14         if files.len() != 1 {
15             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);
16             return Err(Error::InvalidInput);
17         }
18         let path = &files[0];
19         ensure_exists(path)?;
20         let contents = {
21             let bytes = fs::read(path)?;
22             Self::compress_bytes(&*bytes)?
23         };
25         println!("{}: compressed {:?} into memory ({} bytes)", "info".yellow(), &path, contents.len());
26         
27         Ok(contents)
28     }
30     fn compress_file_in_memory(file: File) -> OuchResult<Vec<u8>> {
31         // Ensure that our file has in-memory content
32         let bytes = match file.contents_in_memory {
33             Some(bytes) => bytes,
34             None => {
35                 // TODO: error message,
36                 return Err(Error::InvalidInput);
37             }
38         };
40         Ok(Self::compress_bytes(&*bytes)?)
41     }
43     fn compress_bytes(bytes: &[u8]) -> OuchResult<Vec<u8>> {
44         let buffer = vec![];
45         let mut encoder = bzip2::write::BzEncoder::new(buffer, bzip2::Compression::new(6));
46         encoder.write_all(bytes)?;
47         Ok(encoder.finish()?)
48     }
52 // TODO: customizable compression level
53 impl Compressor for BzipCompressor {
54     fn compress(&self, from: Entry) -> OuchResult<Vec<u8>> {
55         match from {
56             Entry::Files(files) => Ok(
57                 Self::compress_files(files, CompressionFormat::Bzip)?
58             ),
59             Entry::InMemory(file) => Ok(
60                 Self::compress_file_in_memory(file)?
61             ),
62         }
63     }