use std::{collections::HashSet, ffi::OsStr, path::Path};
use crossbeam_channel::Sender;
use notify::Watcher as _;
use crate::{Error, HostCommand};
pub struct Watcher {
_watcher: Box<dyn notify::Watcher>,
}
impl Watcher {
pub fn watch_model(
watch_path: impl AsRef<Path>,
host_tx: Sender<HostCommand>,
) -> Result<Self, Error> {
let watch_path = watch_path.as_ref();
let mut watcher = notify::recommended_watcher(
move |event: notify::Result<notify::Event>| {
let event = event.expect("Error handling watch event");
if let notify::EventKind::Modify(
notify::event::ModifyKind::Any
| notify::event::ModifyKind::Data(
notify::event::DataChange::Any
| notify::event::DataChange::Content,
),
) = event.kind
{
let file_ext = event
.paths
.get(0)
.expect("File path missing in watch event")
.extension();
let black_list = HashSet::from([
OsStr::new("swp"),
OsStr::new("tmp"),
OsStr::new("swx"),
]);
if let Some(ext) = file_ext {
if black_list.contains(ext) {
return;
}
}
host_tx
.send(HostCommand::TriggerEvaluation)
.expect("Channel is disconnected");
}
},
)?;
watcher.watch(watch_path, notify::RecursiveMode::Recursive)?;
Ok(Self {
_watcher: Box::new(watcher),
})
}
}