77 lines · 2.1 KB · Rust
RawDownload
use crate::Watcher;use anyhow::{Context as _, Result};use collections::{BTreeMap, Bound};use fsevent::EventStream;use parking_lot::Mutex;use std::{    path::{Path, PathBuf},    sync::Weak,    thread,    time::Duration,}; pub struct MacWatcher {    events_tx: smol::channel::Sender<Vec<fsevent::Event>>,    handles: Weak<Mutex<BTreeMap<PathBuf, fsevent::Handle>>>,    latency: Duration,} impl MacWatcher {    pub fn new(        events_tx: smol::channel::Sender<Vec<fsevent::Event>>,        handles: Weak<Mutex<BTreeMap<PathBuf, fsevent::Handle>>>,        latency: Duration,    ) -> Self {        Self {            events_tx,            handles,            latency,        }    }} impl Watcher for MacWatcher {    fn add(&self, path: &Path) -> Result<()> {        log::trace!("mac watcher add: {:?}", path);        let handles = self            .handles            .upgrade()            .context("unable to watch path, receiver dropped")?;        let mut handles = handles.lock();         // Return early if an ancestor of this path was already being watched.        if let Some((watched_path, _)) = handles            .range::<Path, _>((Bound::Unbounded, Bound::Included(path)))            .next_back()            && path.starts_with(watched_path)        {            log::trace!(                "mac watched path starts with existing watched path: {watched_path:?}, {path:?}"            );            return Ok(());        }         let (stream, handle) = EventStream::new(&[path], self.latency);        let tx = self.events_tx.clone();        thread::Builder::new()            .name("MacWatcher".to_owned())            .spawn(move || {                stream.run(move |events| smol::block_on(tx.send(events)).is_ok());            })            .unwrap();        handles.insert(path.into(), handle);         Ok(())    }     fn remove(&self, path: &Path) -> anyhow::Result<()> {        let handles = self            .handles            .upgrade()            .context("unable to remove path, receiver dropped")?;         let mut handles = handles.lock();        handles.remove(path);        Ok(())    }}