notify-rs/notify

repository·main·Indexed 25 days ago

https://github.com/notify-rs/notify

A cross-platform filesystem notification library for Rust used by projects like Alacritty, Deno, and rust-analyzer. It provides a unified interface for monitoring filesystem events across Linux (inotify), macOS (FSEvents, kqueue), Windows (ReadDirectoryChangesW), and other BSD platforms. The ecosystem includes notify-debouncer-full and notify-debouncer-mini for event noise reduction, and the file-id crate for retrieving unique file identifiers.

Tokens
9K
Snippets
21
Records
64
Agent score
80%

What's inside notify

  1. Overview of Notify

    main

    Notify is a cross-platform filesystem notification library for Rust. It provides a unified interface for monitoring filesystem events across different operating systems.

    Supported Platforms and Mechanisms:

    • Linux / Android: inotify
    • macOS: FSEvents or kqueue (depending on features)
    • Windows: ReadDirectoryChangesW
    • iOS / FreeBSD / NetBSD / OpenBSD / DragonflyBSD: kqueue
    • All platforms: polling (fallback mechanism)

    Note: If you are looking for desktop notifications (system alerts) rather than filesystem event monitoring, use notify-rust or alert-after instead.

  2. Use Notify Debouncer Full for optimized file event handling

    main

    Notify Debouncer Full is a debouncer for the notify crate designed for ease of use. It reduces event noise by performing the following logic:

    • Rename Matching: Emits a single Rename event only if the From and To events can be matched. It merges multiple Rename events and updates paths for pending events that occurred before the rename.
    • File ID Tracking: Optionally uses file system IDs (supported on FSevents and Windows) to stitch rename events together.
    • Duplicate Suppression:
      • Emits only one Remove event when deleting a directory (on inotify).
      • Prevents duplicate Create events.
      • Prevents Modify events from being emitted immediately after a Create event.
  3. Minimum Supported Rust Version (MSRV) Requirements

    main

    The current Minimum Supported Rust Version (MSRV) for notify is 1.88.

    Project policy guarantees support for the current stable Rust release and the previous two stable releases (N, N-1, N-2).

  4. Migrate from v4 to v5: Watcher Configuration and Creation

    main
    In v5, all watchers expose the Watcher trait. Creating a watcher now requires providing both an EventHandler (for callbacks or foreign channels) and a Config object. The Config object is used for initialization parameters that must be specified before the watcher runs, such as compare_contents in PollWatcher.
  5. Understand path replacement behavior in Watcher::watch

    main

    In notify v9, calling Watcher::watch on a path that is already being watched will replace the existing watch with the new configuration (recursive mode and reported path) upon success. It does not create a second independent watch. To remove the watch, a single Watcher::unwatch call is used.

    watcher.watch(path, notify::RecursiveMode::Recursive)?;
    watcher.watch(path, notify::RecursiveMode::NonRecursive)?;
    
    // `path` is now watched non-recursively.
    watcher.unwatch(path)?;
  6. Migrate from Watcher::paths_mut to Watcher::update_paths

    main

    In notify v9, the PathsMut type and Watcher::paths_mut() method were removed. They are replaced by Watcher::update_paths(Vec<PathOp>).

    To update multiple paths, create a vector of PathOp operations (such as PathOp::watch_recursive) and pass them to update_paths. This method applies operations in order and stops on the first error. If it fails, it returns an UpdatePathsError which contains the source error, the origin of the failure, and the remaining operations that were not attempted, allowing for retry logic.

    use notify::{PathOp, Result, Watcher};
    
    fn add_many_paths<W: Watcher>(watcher: &mut W, paths: &[std::path::PathBuf]) -> Result<()> {
        let ops = paths
            .iter()
            .cloned()
            .map(PathOp::watch_recursive)
            .collect::<Vec<_>>();
    
        watcher.update_paths(ops).map_err(notify::Error::from)?;
        Ok(())
    }
  7. Use Notify Debouncer Full (debouncer)

    main

    The notify-debouncer-full crate provides advanced debouncing capabilities:

    • monitor_debounced: A basic usage example for standard debouncing.
    • debouncer_full: An advanced example demonstrating how to access the internal file ID cache.
  8. Use Debouncer Mini (mini debouncer)

    main

    The notify-debouncer-mini crate provides lightweight debouncing options:

    • debouncer_mini: A basic usage example for the mini debouncer.
    • debouncer_mini_custom: Demonstrates how to use the mini debouncer with a specific backend, such as PollWatcher.
  9. Migrate from v4 to v5: Events and Debouncing

    main

    In notify v5, the library only provides precise events. The RawEvent type from v4 has been replaced by Event.

    If your application requires debouncing, you must now use the separate notify-debouncer-mini crate. The old DebouncedEvent type has been removed. The new notify-debouncer-mini crate reports an Any-like event (also named DebouncedEvent), but it is recommended to verify the actual file state rather than relying solely on the event kind, as event behavior is highly platform-specific.

  10. Handle Event path representation changes

    main

    In notify v9, Event.paths and Watcher::watched_paths() use the same root representation passed to Watcher::watch or Watcher::update_paths.

    If you watch a relative path like src, events will report relative paths like src/lib.rs. If you require absolute paths, you must convert the path to an absolute path before calling watch or update_paths.

    let path = std::env::current_dir()?.join("src");
    watcher.watch(&path, notify::RecursiveMode::Recursive)?;
  11. Configure notify v5 Features

    main

    Internal Channels

    notify v5 uses crossbeam-channel by default. If you are using tokio and encounter compatibility issues, you may need to disable this feature.

    macOS Backend

    For macOS, you can choose between the default fsevent backend or the kqueue backend by enabling the macos_kqueue feature.