use std::error::Error;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use bstr::{ByteSlice, ByteVec};
use inotify::{Inotify, WatchDescriptor, WatchMask};
pub(crate) struct Processor {
pub path: PathBuf,
pub command: String,
pub args: Vec<String>,
pub debounce: u64,
pub keep_file: bool,
}
impl Processor {
pub(crate) fn register(&self, inotify: &mut Inotify) -> Option<WatchDescriptor> {
println!(
"Registering {} => {} {}",
self.path.display(),
self.command,
self.args.join(" ")
);
inotify
.watches()
.add(
&self.path,
WatchMask::CLOSE_WRITE
| WatchMask::MOVED_TO
| WatchMask::MOVED_FROM
| WatchMask::CREATE
| WatchMask::DELETE,
)
.map_err(|e| eprintln!("Error: {}", e))
.ok()
}
pub(crate) fn process(&self, filename: &Path) -> Result<(), Box<dyn Error>> {
let bfilename = <[u8]>::from_path(filename).unwrap();
let args = self.args.iter().map(|arg| {
arg.as_bytes()
.replace("%f", bfilename)
.into_os_string()
.unwrap()
});
Command::new(&self.command).args(args).status()?.exit_ok()?;
if !self.keep_file {
println!("Removing {}", filename.display());
fs::remove_file(filename)?;
}
Ok(())
}
}