chore: Rename compression directory to compression_engine
This commit is contained in:
committed by
Andrew Phillips (aider)
parent
9c8bc542c5
commit
e3159473d0
114
src/compression_engine/program.rs
Normal file
114
src/compression_engine/program.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use log::*;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use crate::compression::CompressionEngine;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct CompressionEngineProgram {
|
||||
pub program: String,
|
||||
pub compress: Vec<String>,
|
||||
pub decompress: Vec<String>,
|
||||
pub supported: bool,
|
||||
}
|
||||
|
||||
impl CompressionEngineProgram {
|
||||
pub fn new(
|
||||
program: &str,
|
||||
compress: Vec<&str>,
|
||||
decompress: Vec<&str>,
|
||||
) -> CompressionEngineProgram {
|
||||
let program_path = get_program_path(program);
|
||||
let supported = program_path.is_ok();
|
||||
|
||||
CompressionEngineProgram {
|
||||
program: program_path.unwrap_or(program.to_string()),
|
||||
compress: compress.iter().map(|s| s.to_string()).collect(),
|
||||
decompress: decompress.iter().map(|s| s.to_string()).collect(),
|
||||
supported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CompressionEngine for CompressionEngineProgram {
|
||||
fn is_supported(&self) -> bool {
|
||||
self.supported
|
||||
}
|
||||
|
||||
fn open(&self, file_path: PathBuf) -> Result<Box<dyn Read>> {
|
||||
debug!("COMPRESSION: Opening {:?} using {:?}", file_path, *self);
|
||||
|
||||
let program = self.program.clone();
|
||||
let args = self.decompress.clone();
|
||||
|
||||
debug!(
|
||||
"COMPRESSION: Executing command: {:?} {:?} reading from {:?}",
|
||||
program, args, file_path
|
||||
);
|
||||
|
||||
let file = File::open(file_path).context("Unable to open file for reading")?;
|
||||
|
||||
let process = Command::new(program.clone())
|
||||
.args(args.clone())
|
||||
.stdin(file)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.context(anyhow!(
|
||||
"Unable to spawn child process: {:?} {:?}",
|
||||
program,
|
||||
args
|
||||
))?;
|
||||
Ok(Box::new(process.stdout.unwrap()))
|
||||
}
|
||||
|
||||
fn create(&self, file_path: PathBuf) -> Result<Box<dyn Write>> {
|
||||
debug!("COMPRESSION: Writting to {:?} using {:?}", file_path, *self);
|
||||
|
||||
let program = self.program.clone();
|
||||
let args = self.compress.clone();
|
||||
|
||||
debug!(
|
||||
"COMPRESSION: Executing command: {:?} {:?} writing to {:?}",
|
||||
program, args, file_path
|
||||
);
|
||||
|
||||
let file = File::create(file_path).context("Unable to open file for writing")?;
|
||||
|
||||
let process = Command::new(program.clone())
|
||||
.args(args.clone())
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(file)
|
||||
.spawn()
|
||||
.context(anyhow!(
|
||||
"Problem spawning child process: {:?} {:?}",
|
||||
program,
|
||||
args
|
||||
))?;
|
||||
|
||||
Ok(Box::new(process.stdin.unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_program_path(program: &str) -> Result<String> {
|
||||
debug!("COMPRESSION: Looking for executable: {}", program);
|
||||
if let Ok(path) = env::var("PATH") {
|
||||
for p in path.split(':') {
|
||||
let p_str = format!("{}/{}", p, program);
|
||||
let stat = fs::metadata(p_str.clone());
|
||||
if let Ok(stat) = stat {
|
||||
let md = stat;
|
||||
let permissions = md.permissions();
|
||||
if md.is_file() && permissions.mode() & 0o111 != 0 {
|
||||
return Ok(p_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(anyhow!("Unable to find binary {} in PATH", program))
|
||||
}
|
||||
Reference in New Issue
Block a user