use std::path::Path;
use std::time::Duration;
use notify_debouncer_mini::notify::RecommendedWatcher;
use notify_debouncer_mini::{DebounceEventResult, Debouncer, new_debouncer, notify::RecursiveMode};
use tokio::sync::mpsc;
const IGNORED_PATHS: &[&str] = &[".git", "target", ".DS_Store", "node_modules"];
pub fn start(
source: &Path,
rebuild_tx: mpsc::Sender<()>,
) -> std::io::Result<Debouncer<RecommendedWatcher>> {
let mut debouncer = new_debouncer(
Duration::from_millis(200),
move |result: DebounceEventResult| {
match result {
Ok(events) => {
let relevant_events: Vec<_> = events
.iter()
.filter(|event| {
let path_str = event.path.to_string_lossy();
!IGNORED_PATHS
.iter()
.any(|ignored| path_str.contains(ignored))
})
.collect();
if !relevant_events.is_empty() {
tracing::debug!(
"File changes detected: {:?}",
relevant_events
.iter()
.map(|e| e.path.display().to_string())
.collect::<Vec<_>>()
);
let _ = rebuild_tx.try_send(());
}
}
Err(error) => {
tracing::warn!("Watch error: {:?}", error);
}
}
},
)
.map_err(|e| std::io::Error::other(format!("watcher error: {}", e)))?;
debouncer
.watcher()
.watch(source, RecursiveMode::Recursive)
.map_err(|e| std::io::Error::other(format!("watch error: {}", e)))?;
Ok(debouncer)
}