use std::collections::HashSet;
use std::path::Path;
use std::sync::mpsc::{self, Receiver};
use std::time::Duration;
use notify_debouncer_mini::{new_debouncer, DebouncedEventKind};
pub struct WatchEvent {
pub changed_files: HashSet<String>,
}
#[allow(dead_code)]
pub struct WatchHandle(notify_debouncer_mini::Debouncer<notify::RecommendedWatcher>);
pub fn setup_watcher() -> Option<(WatchHandle, Receiver<WatchEvent>)> {
let (tx, rx) = mpsc::channel();
let cwd = std::env::current_dir().ok();
let mut debouncer = new_debouncer(
Duration::from_millis(500),
move |res: Result<Vec<notify_debouncer_mini::DebouncedEvent>, notify::Error>| {
if let Ok(events) = res {
let mut changed_files = HashSet::new();
for event in events {
if event.kind == DebouncedEventKind::Any {
let path_str = if let Some(ref cwd) = cwd {
event
.path
.strip_prefix(cwd)
.unwrap_or(&event.path)
.to_string_lossy()
.to_string()
} else {
event.path.to_string_lossy().to_string()
};
let normalized = path_str.strip_prefix("./").unwrap_or(&path_str);
changed_files.insert(normalized.to_string());
}
}
if !changed_files.is_empty() {
let _ = tx.send(WatchEvent { changed_files });
}
}
},
)
.ok()?;
debouncer
.watcher()
.watch(Path::new("."), notify::RecursiveMode::Recursive)
.ok()?;
Some((WatchHandle(debouncer), rx))
}