use std::path::Path;
use std::time::Duration;
use notify::RecursiveMode;
use notify_debouncer_full::DebounceEventResult;
use tokio::sync::mpsc::UnboundedSender;
use super::WatchEvent;
use super::backend::{KizuDebouncer, new_kizu_debouncer};
const EVENTS_DEBOUNCE: Duration = Duration::from_millis(100);
pub(in crate::watcher) fn spawn_events_dir_debouncer(
root: &Path,
tx: UnboundedSender<WatchEvent>,
) -> Option<KizuDebouncer> {
let events_dir = crate::paths::events_dir(root)?;
let _ = crate::paths::ensure_private_dir(&events_dir);
if !events_dir.is_dir() {
return None;
}
let events_dir_owned = events_dir.clone();
let mut debouncer = new_kizu_debouncer(
EVENTS_DEBOUNCE,
false, move |result: DebounceEventResult| {
let events = match result {
Ok(events) => events,
Err(_) => return, };
for event in events {
for path in &event.event.paths {
if path
.file_name()
.is_some_and(|n| n.to_string_lossy().starts_with('.'))
{
continue;
}
if path.starts_with(&events_dir_owned) {
let _ = tx.send(WatchEvent::EventLog(path.clone()));
}
}
}
},
)
.ok()?;
debouncer
.watch(&events_dir, RecursiveMode::NonRecursive)
.ok()?;
Some(debouncer)
}