use std::path::Path;
use std::time::Duration;
use notify_debouncer_full::notify::{RecommendedWatcher, RecursiveMode};
use notify_debouncer_full::{DebounceEventResult, Debouncer, RecommendedCache, new_debouncer};
use tokio::sync::mpsc::{self, UnboundedReceiver};
const DEBOUNCE: Duration = Duration::from_millis(300);
pub struct Watch {
pub rx: UnboundedReceiver<()>,
_debouncer: Debouncer<RecommendedWatcher, RecommendedCache>,
}
pub fn spawn(root: &Path) -> Option<Watch> {
let (tx, rx) = mpsc::unbounded_channel();
let handler = move |result: DebounceEventResult| {
if result.is_ok() {
let _ = tx.send(());
}
};
let mut debouncer = match new_debouncer(DEBOUNCE, None, handler) {
Ok(debouncer) => debouncer,
Err(err) => {
tracing::warn!(%err, "file watcher unavailable; live refresh disabled");
return None;
}
};
if let Err(err) = debouncer.watch(root, RecursiveMode::Recursive) {
tracing::warn!(%err, "failed to watch the root; live refresh disabled");
return None;
}
Some(Watch {
rx,
_debouncer: debouncer,
})
}