watchexec/src/watcher.rs

62 lines
1.7 KiB
Rust
Raw Normal View History

2019-01-26 03:15:27 +01:00
use notify::{raw_watcher, PollWatcher, RecommendedWatcher, RecursiveMode};
2021-04-10 19:13:44 +02:00
use std::convert::TryFrom;
2017-02-04 22:18:02 +01:00
use std::path::PathBuf;
use std::sync::mpsc::Sender;
2021-04-10 19:33:30 +02:00
use std::time::Duration;
/// Thin wrapper over the notify crate
///
/// `PollWatcher` and `RecommendedWatcher` are distinct types, but watchexec
/// really just wants to handle them without regard to the exact type
/// (e.g. polymorphically). This has the nice side effect of separating out
/// all coupling to the notify crate into this module.
pub struct Watcher {
watcher_impl: WatcherImpl,
}
pub use notify::Error;
2018-09-08 10:08:36 +02:00
pub use notify::RawEvent as Event;
enum WatcherImpl {
Recommended(RecommendedWatcher),
Poll(PollWatcher),
}
impl Watcher {
2018-09-08 10:08:36 +02:00
pub fn new(
tx: Sender<Event>,
paths: &[PathBuf],
poll: bool,
2021-04-10 19:13:44 +02:00
interval: Duration,
2019-10-27 12:06:09 +01:00
) -> Result<Self, Error> {
2017-02-04 22:18:02 +01:00
use notify::Watcher;
let imp = if poll {
2021-04-10 19:33:30 +02:00
let mut watcher = PollWatcher::with_delay_ms(
tx,
u32::try_from(interval.as_millis()).unwrap_or(u32::MAX),
)?;
2017-02-04 22:26:59 +01:00
for path in paths {
watcher.watch(path, RecursiveMode::Recursive)?;
2017-02-04 22:18:02 +01:00
debug!("Watching {:?}", path);
}
WatcherImpl::Poll(watcher)
} else {
let mut watcher = raw_watcher(tx)?;
2017-02-04 22:26:59 +01:00
for path in paths {
watcher.watch(path, RecursiveMode::Recursive)?;
2017-02-04 22:18:02 +01:00
debug!("Watching {:?}", path);
}
WatcherImpl::Recommended(watcher)
};
2019-10-27 12:06:09 +01:00
Ok(Self { watcher_impl: imp })
}
pub fn is_polling(&self) -> bool {
2021-04-10 19:44:24 +02:00
matches!(self.watcher_impl, WatcherImpl::Poll(_))
}
}