use anyhow::Result; use std::fs::File; use std::io; use std::io::{Read,Write}; use std::path::PathBuf; use log::*; use flate2::Compression; use flate2::read::GzDecoder; use flate2::write::GzEncoder; use crate::compression::CompressionEngine; #[derive(Debug, Eq, PartialEq, Clone, Default)] pub struct CompressionEngineGZip {} impl CompressionEngineGZip { pub fn new() -> CompressionEngineGZip { CompressionEngineGZip {} } } impl CompressionEngine for CompressionEngineGZip { fn is_supported(&self) -> bool { true } fn open(&self, file_path: PathBuf) -> Result> { debug!("COMPRESSION: Opening {:?} using {:?}", file_path, *self); let file = File::open(file_path)?; Ok(Box::new(GzDecoder::new(file))) } fn create(&self, file_path: PathBuf) -> Result> { debug!("COMPRESSION: Writting to {:?} using {:?}", file_path, *self); let file = File::create(file_path)?; let gzip_write = GzEncoder::new(file, Compression::default()); Ok(Box::new(AutoFinishGzEncoder::new(gzip_write))) } } pub struct AutoFinishGzEncoder { encoder: Option>, } impl AutoFinishGzEncoder { fn new(gz_encoder: GzEncoder) -> AutoFinishGzEncoder { AutoFinishGzEncoder { encoder: Some(gz_encoder), } } } impl Drop for AutoFinishGzEncoder { fn drop(&mut self) { if let Some(encoder) = self.encoder.take() { debug!("COMPRESSION: Finishing"); let _ = encoder.finish(); } } } impl Write for AutoFinishGzEncoder { fn write(&mut self, buf: &[u8]) -> io::Result { self.encoder.as_mut().unwrap().write(buf) } fn flush(&mut self) -> io::Result<()> { self.encoder.as_mut().unwrap().flush() } }