chore: Rename compression directory to compression_engine

This commit is contained in:
Andrew Phillips
2025-05-12 17:08:00 -03:00
committed by Andrew Phillips (aider)
parent 9c8bc542c5
commit e3159473d0
5 changed files with 0 additions and 0 deletions

154
src/compression_engine.rs Executable file
View File

@@ -0,0 +1,154 @@
use anyhow::{anyhow, Context, Result};
use std::io;
use std::io::{Read, Write};
use std::path::PathBuf;
use std::process::{Command, Stdio};
use strum::IntoEnumIterator;
use log::*;
use lazy_static::lazy_static;
extern crate enum_map;
use enum_map::enum_map;
use enum_map::{Enum, EnumMap};
pub mod gzip;
pub mod lz4;
pub mod none;
pub mod program;
use gzip::CompressionEngineGZip;
use lz4::CompressionEngineLZ4;
use none::CompressionEngineNone;
use program::CompressionEngineProgram;
#[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString, Enum)]
#[strum(ascii_case_insensitive)]
pub enum CompressionType {
LZ4,
GZip,
BZip2,
XZ,
ZStd,
None,
}
pub trait CompressionEngine {
fn open(&self, file_path: PathBuf) -> Result<Box<dyn Read>>;
fn create(&self, file_path: PathBuf) -> Result<Box<dyn Write>>;
fn is_supported(&self) -> bool {
true
}
fn copy(&self, file_path: PathBuf, writer: &mut dyn Write) -> Result<()> {
let mut reader = self.open(file_path)?;
io::copy(&mut reader, writer)?;
writer.flush()?;
Ok(())
}
fn cat(&self, file_path: PathBuf) -> Result<()> {
let mut stdout = io::stdout().lock();
self.copy(file_path, &mut stdout)
}
fn magic(&self, file_path: PathBuf) -> Result<String> {
let mut buffer = [0; libc::BUFSIZ as usize];
let mut reader = self.open(file_path)?;
let buffer_size = reader.read(&mut buffer[..])?;
//let cookie = magic::Cookie::open(magic::cookie::Flags::ERROR)?;
// load the system's default database
//let database = Default::default();
//let cookie = cookie.load(&database).map_err(|error| { anyhow!(error.to_string())})?;
//let magic = cookie.buffer(&buffer[0..n])?;
let program = "file";
let args = ["-bE", "-"];
let process = Command::new(program)
.args(args.clone())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.context(anyhow!(
"Unable to spawn child process: {:?} {:?}",
program,
args
))?;
let mut stdin = process.stdin.unwrap();
stdin.write_all(&buffer[0..buffer_size])?;
drop(stdin);
let mut magic = String::new();
process.stdout.unwrap().read_to_string(&mut magic)?;
Ok(magic)
}
fn size(&self, file_path: PathBuf) -> Result<usize> {
let mut reader = self.open(file_path)?;
let mut buffer = [0; libc::BUFSIZ as usize];
let mut size: usize = 0;
loop {
let n = reader.read(&mut buffer[..libc::BUFSIZ as usize])?;
if n == 0 {
debug!("COMPREESSION: EOF");
break;
}
size = size + n;
}
Ok(size)
}
}
lazy_static! {
pub static ref COMPRESSION_PROGRAMS: EnumMap<CompressionType, Option<CompressionEngineProgram>> = enum_map! {
CompressionType::LZ4 => None,
CompressionType::GZip => None,
CompressionType::BZip2 => {
let program = CompressionEngineProgram::new("bzip2", vec!["-qcf"], vec!["-dcf"]);
if program.supported { Some(program) } else { None }
},
CompressionType::XZ => {
let program = CompressionEngineProgram::new("xz", vec!["-qcf"], vec!["-dcf"]);
if program.supported { Some(program) } else { None }
},
CompressionType::ZStd => {
let program = CompressionEngineProgram::new("zstd", vec!["-qcf"], vec!["-dcf"]);
if program.supported { Some(program) } else { None }
},
CompressionType::None => None
};
}
pub fn get_engine(compression_type: CompressionType) -> Result<Box<dyn CompressionEngine>> {
match compression_type {
CompressionType::LZ4 => Ok(Box::new(CompressionEngineLZ4::new())),
CompressionType::GZip => Ok(Box::new(CompressionEngineGZip::new())),
CompressionType::None => Ok(Box::new(CompressionEngineNone::new())),
compression_type => Ok(Box::new(
COMPRESSION_PROGRAMS[compression_type.clone()]
.clone()
.unwrap(),
)),
}
}
pub fn default_type() -> CompressionType {
let mut default = CompressionType::None;
for compression_type in CompressionType::iter() {
let compression_engine = get_engine(compression_type.clone()).expect("Missing engine");
if compression_engine.is_supported() {
default = compression_type;
break;
}
}
default
}