43 stable releases (4 major)

4.0.12 May 22, 2019
4.0.10 Mar 6, 2019
4.0.6 Aug 29, 2018
4.0.3 Nov 26, 2017
0.0.1 Dec 20, 2014

#4 in Filesystem

Download history 9421/week @ 2019-02-06 8772/week @ 2019-02-13 8909/week @ 2019-02-20 10326/week @ 2019-02-27 9424/week @ 2019-03-06 9900/week @ 2019-03-13 9341/week @ 2019-03-20 9123/week @ 2019-03-27 9945/week @ 2019-04-03 9252/week @ 2019-04-10 8091/week @ 2019-04-17 8849/week @ 2019-04-24 8527/week @ 2019-05-01 10769/week @ 2019-05-08 10025/week @ 2019-05-15

40,062 downloads per month
Used in 113 crates (77 directly)

CC0 license

127KB
2.5K SLoC

Notify

» Crate » Docs » CI » Downloads » Conduct » Public Domain

Cross-platform filesystem notification library for Rust.

(Looking for desktop notifications instead? Have a look at notify-rust or alert-after!)

As used by: alacritty, cargo watch, cobalt, docket, handlebars-iron, mdBook, pax, rdiff, timetrack, watchexec, xi-editor, and others. (Want to be added to this list? Open a pull request!)

Installation

[dependencies]
notify = "4.0.12"

Usage

extern crate notify;

use notify::{RecommendedWatcher, Watcher, RecursiveMode};
use std::sync::mpsc::channel;
use std::time::Duration;

fn watch() -> notify::Result<()> {
    // Create a channel to receive the events.
    let (tx, rx) = channel();

    // Automatically select the best implementation for your platform.
    // You can also access each implementation directly e.g. INotifyWatcher.
    let mut watcher: RecommendedWatcher = try!(Watcher::new(tx, Duration::from_secs(2)));

    // Add a path to be watched. All files and directories at that path and
    // below will be monitored for changes.
    try!(watcher.watch("/home/test/notify", RecursiveMode::Recursive));

    // This is a simple loop, but you may want to use more complex logic here,
    // for example to handle I/O.
    loop {
        match rx.recv() {
            Ok(event) => println!("{:?}", event),
            Err(e) => println!("watch error: {:?}", e),
        }
    }
}

fn main() {
    if let Err(e) = watch() {
        println!("error: {:?}", e)
    }
}

Looking overly verbose? Too much boilerplate? Have a look at hotwatch, a friendly wrapper:

// Taken from the hotwatch readme
use hotwatch::{Hotwatch, Event};

let mut hotwatch = Hotwatch::new().expect("Hotwatch failed to initialize.");
hotwatch.watch("war.png", |event: Event| {
    if let Event::Write(path) = event {
        println!("War has changed.");
    }
}).expect("Failed to watch file!");

Platforms

  • Linux / Android: inotify
  • macOS: FSEvents
  • Windows: ReadDirectoryChangesW
  • All platforms: polling

FSEvents

Due to the inner security model of FSEvents (see FileSystemEventSecurity), some event cannot be observed easily when trying to follow files that do not belong to you. In this case, reverting to the pollwatcher can fix the issue, with a slight performance cost.

Todo

Version 4 is not frozen! I'm just not actively spending time on it.

I do accept pull requests for fixes and features, and would even consider breaking changes with enough justification. Do contribute, please!

(Originally I thought that Version 5 would take less time to get out, but it has now been clear for a while that the finish line is quite far away still. I'm still at it, but expect nothing soon.)

Origins

Inspired by Go's fsnotify and Node.js's Chokidar, born out of need for cargo watch, and general frustration at the non-existence of C/Rust cross-platform notify libraries.

Written by Félix Saparelli and awesome contributors, and released in the Public Domain using the Creative Commons Zero Declaration.

Note that licensing will change from version 5 to Artistic 2.0.

Dependencies

~1MB
~17K SLoC