Skip to content

Commit

Permalink
Use FnMut for watch closure (#4)
Browse files Browse the repository at this point in the history
* Use FnMut for watch closure

* Release 0.4.4
  • Loading branch information
edward-shen authored Nov 20, 2020
1 parent a484a6b commit 9e6d36b
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Unreleased

# Version 0.4.4 (2020-11-19)

- `watch` now accepts `FnMut` instead of `Fn`

# Version 0.4.3 (2019-12-03)

- Added `blocking` API.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hotwatch"
version = "0.4.3"
version = "0.4.4"
authors = ["Francesca Lovebloom <[email protected]>"]
edition = "2018"
description = "A Rust library for conveniently watching and handling file changes."
Expand Down
2 changes: 1 addition & 1 deletion src/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl Hotwatch {
match self.rx.recv() {
Ok(event) => {
util::log_event(&event);
if let Some(handler) = util::handler_for_event(&event, &self.handlers) {
if let Some(handler) = util::handler_for_event(&event, &mut self.handlers) {
if let Flow::Exit = handler(event) {
break;
}
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl From<notify::Error> for Error {
}
}

type HandlerMap = HashMap<PathBuf, Box<dyn Fn(Event) + Send>>;
type HandlerMap = HashMap<PathBuf, Box<dyn FnMut(Event) + Send>>;

/// A non-blocking hotwatch instance.
///
Expand Down Expand Up @@ -147,7 +147,7 @@ impl Hotwatch {
pub fn watch<P, F>(&mut self, path: P, handler: F) -> Result<(), Error>
where
P: AsRef<Path>,
F: 'static + Fn(Event) + Send,
F: 'static + FnMut(Event) + Send,
{
let absolute_path = path.as_ref().canonicalize()?;
self.watcher
Expand Down Expand Up @@ -176,8 +176,8 @@ impl Hotwatch {
match rx.recv() {
Ok(event) => {
util::log_event(&event);
let handlers = handlers.lock().expect("handler mutex poisoned!");
if let Some(handler) = util::handler_for_event(&event, &handlers) {
let mut handlers = handlers.lock().expect("handler mutex poisoned!");
if let Some(handler) = util::handler_for_event(&event, &mut handlers) {
handler(event);
}
}
Expand Down
21 changes: 14 additions & 7 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ pub fn log_dead() {
log::debug!("sender disconnected! the watcher is dead 💀");
}

pub fn handler_for_event<'a, H>(e: &Event, handlers: &'a HashMap<PathBuf, H>) -> Option<&'a H> {
pub fn handler_for_event<'a, H>(
e: &Event,
handlers: &'a mut HashMap<PathBuf, H>,
) -> Option<&'a mut H> {
fn path_from_event(e: &Event) -> Option<PathBuf> {
match e {
Event::NoticeWrite(p)
Expand All @@ -23,16 +26,20 @@ pub fn handler_for_event<'a, H>(e: &Event, handlers: &'a HashMap<PathBuf, H>) ->
}
}

fn find_handler<'a, H>(mut path: PathBuf, handlers: &'a HashMap<PathBuf, H>) -> Option<&'a H> {
let mut handler = None;
fn find_handler<'a, H>(
mut path: PathBuf,
handlers: &'a mut HashMap<PathBuf, H>,
) -> Option<&'a mut H> {
let mut poppable = true;
while handler.is_none() && poppable {
while poppable {
log::debug!("matching against {:?}", path);
handler = handlers.get(&path);
if handlers.contains_key(&path) {
return handlers.get_mut(&path);
}
poppable = path.pop();
}
handler
None
}

path_from_event(e).and_then(|path| find_handler(path, handlers))
path_from_event(e).and_then(move |path| find_handler(path, handlers))
}

0 comments on commit 9e6d36b

Please sign in to comment.