75 lines
1.9 KiB
Rust
75 lines
1.9 KiB
Rust
use anyhow::Result;
|
|
use log::*;
|
|
use std::fs::File;
|
|
use std::io;
|
|
use std::io::{Read, Write};
|
|
use std::path::PathBuf;
|
|
|
|
use flate2::Compression;
|
|
use flate2::read::GzDecoder;
|
|
use flate2::write::GzEncoder;
|
|
|
|
use crate::compression_engine::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<Box<dyn Read>> {
|
|
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<Box<dyn Write>> {
|
|
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<W: Write> {
|
|
encoder: Option<GzEncoder<W>>,
|
|
}
|
|
|
|
impl<W: Write> AutoFinishGzEncoder<W> {
|
|
fn new(gz_encoder: GzEncoder<W>) -> AutoFinishGzEncoder<W> {
|
|
AutoFinishGzEncoder {
|
|
encoder: Some(gz_encoder),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<W: Write> Drop for AutoFinishGzEncoder<W> {
|
|
fn drop(&mut self) {
|
|
if let Some(encoder) = self.encoder.take() {
|
|
debug!("COMPRESSION: Finishing");
|
|
let _ = encoder.finish();
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<W: Write> Write for AutoFinishGzEncoder<W> {
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
self.encoder.as_mut().unwrap().write(buf)
|
|
}
|
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
self.encoder.as_mut().unwrap().flush()
|
|
}
|
|
}
|