Skip to content

Commit 0afcc27

Browse files
committed
rework docs and example documentation
1 parent cf37946 commit 0afcc27

16 files changed

Lines changed: 140 additions & 176 deletions

File tree

README.md

Lines changed: 10 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,31 @@
99

1010
_Cross-platform filesystem notification library for Rust._
1111

12-
**Caution! This is unstable code!**
13-
14-
You likely want either [the latest 4.0 release] or [5.0.0-pre.15].
15-
16-
[the latest 4.0 release]: https://github.com/notify-rs/notify/tree/v4.0.16#notify
17-
[5.0.0-pre.15]: https://github.com/notify-rs/notify/tree/5.0.0-pre.15#notify
18-
1912
(Looking for desktop notifications instead? Have a look at [notify-rust] or
2013
[alert-after]!)
2114

22-
- **incomplete [Guides and in-depth docs][wiki]**
2315
- [API Documentation][docs]
16+
- [Debouncer Documentation][debouncer]
2417
- [Crate page][crate]
2518
- [Changelog][changelog]
26-
- Earliest supported Rust version: **1.47.0**
19+
- [Upgrading from v5](UPGRADING_V4_TO_V5.md)
20+
- Earliest supported Rust version: **1.56**
21+
- **incomplete [Guides and in-depth docs][wiki]**
2722

2823
As used by: [alacritty], [cargo watch], [cobalt], [docket], [mdBook], [pax],
2924
[rdiff], [rust-analyzer], [timetrack], [watchexec], [xi-editor], [watchfiles],
3025
and others.
3126

32-
## Installation
27+
## Base Installation
3328

3429
```toml
3530
[dependencies]
36-
crossbeam-channel = "0.4.0"
3731
notify = "5.0.0-pre.15"
3832
```
3933

4034
## Usage
4135

42-
The examples below are aspirational only, to preview what the final release may
43-
have looked like. They may not work. Refer to [the API documentation][docs] instead.
36+
A basic example
4437

4538
```rust
4639
use notify::{RecommendedWatcher, RecursiveMode, Result, watcher};
@@ -68,100 +61,18 @@ fn main() -> Result<()> {
6861
}
6962
```
7063

71-
### With a channel
72-
73-
To get a channel for advanced or flexible cases, use:
74-
75-
```rust
76-
let rx = watcher.channel();
77-
78-
loop {
79-
match rx.recv() {
80-
// ...
81-
}
82-
}
83-
```
84-
85-
To pass in a channel manually:
86-
87-
```rust
88-
let (tx, rx) = crossbeam_channel::unbounded();
89-
let mut watcher: RecommendedWatcher = Watcher::with_channel(tx, Duration::from_secs(2))?;
90-
91-
for event in rx.iter() {
92-
// ...
93-
}
94-
```
95-
96-
### With precise events
97-
98-
By default, Notify issues generic events that carry little additional
99-
information beyond what path was affected. On some platforms, more is
100-
available; stay aware though that how exactly that manifests varies. To enable
101-
precise events, use:
102-
103-
```rust
104-
use notify::Config;
105-
watcher.configure(Config::PreciseEvents(true));
106-
```
107-
108-
### With notice events
109-
110-
Sometimes you want to respond to some events straight away, but not give up the
111-
advantages of debouncing. Notice events appear once immediately when the occur
112-
during a debouncing period, and then a second time as usual at the end of the
113-
debouncing period:
114-
115-
```rust
116-
use notify::Config;
117-
watcher.configure(Config::NoticeEvents(true));
118-
```
119-
120-
### With ongoing events
121-
122-
Sometimes frequent writes may be missed or not noticed often enough. Ongoing
123-
write events can be enabled to emit more events even while debouncing:
124-
125-
```rust
126-
use notify::Config;
127-
watcher.configure(Config::OngoingEvents(Some(Duration::from_millis(500))));
128-
```
129-
130-
### Without debouncing
131-
132-
To receive events as they are emitted, without debouncing at all:
133-
134-
```rust
135-
let mut watcher = immediate_watcher()?;
136-
```
137-
138-
With a channel:
139-
140-
```rust
141-
let (tx, rx) = unbounded();
142-
let mut watcher: RecommendedWatcher = Watcher::immediate_with_channel(tx)?;
143-
```
144-
145-
### Serde
146-
147-
Events can be serialisable via [serde]. To enable the feature:
148-
149-
```toml
150-
notify = { version = "5.0.0-pre.15", features = ["serde"] }
151-
```
152-
15364
## Platforms
15465

15566
- Linux / Android: inotify
156-
- macOS: FSEvents
67+
- macOS: FSEvents or kqueue, see features
15768
- Windows: ReadDirectoryChangesW
15869
- FreeBSD / NetBSD / OpenBSD / DragonflyBSD: kqueue
15970
- All platforms: polling
16071

16172
### FSEvents
16273

16374
Due to the inner security model of FSEvents (see [FileSystemEventSecurity]),
164-
some event cannot be observed easily when trying to follow files that do not
75+
some events cannot be observed easily when trying to follow files that do not
16576
belong to you. In this case, reverting to the pollwatcher can fix the issue,
16677
with a slight performance cost.
16778

@@ -183,10 +94,11 @@ Inspired by Go's [fsnotify] and Node.js's [Chokidar], born out of need for
18394
[cargo watch], and general frustration at the non-existence of C/Rust
18495
cross-platform notify libraries.
18596

186-
Written by [Félix Saparelli] and awesome [contributors].
97+
Originally created by [Félix Saparelli] and awesome [contributors].
18798

18899
[Chokidar]: https://github.com/paulmillr/chokidar
189100
[FileSystemEventSecurity]: https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/FSEvents_ProgGuide/FileSystemEventSecurity/FileSystemEventSecurity.html
101+
[debouncer]: https://github.com/notify-rs/notify/tree/main/notify-debouncer-mini
190102
[Félix Saparelli]: https://passcod.name
191103
[alacritty]: https://github.com/jwilm/alacritty
192104
[alert-after]: https://github.com/frewsxcv/alert-after

UPGRADING_V4_TO_V5.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Upgrading from notify v4 to v5
2+
3+
This guide documents changes between v4 and v5 for upgrading existing code.
4+
5+
Notify v5 only contains precise events. Debouncing is done by a separate crate [notify-debouncer-mini](https://github.com/notify-rs/notify/tree/main/notify-debouncer-mini).
6+
7+
If you've used the default debounced API, please see [here](https://github.com/notify-rs/notify/blob/main/examples/debounced.rs) for an example.
8+
9+
For precise events you can see [here](https://github.com/notify-rs/notify/blob/main/examples/monitor_raw.rs).
10+
11+
Notify v5 by default uses crossbeam-channel internally. You can disable this (required for tokio) as documented in the crate.
12+
13+
Plattform support in v5 now includes BSD and kqueue on macos in addition to fsevent.

examples/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ name = "watcher_kind"
3030
path = "watcher_kind.rs"
3131

3232
# specifically in its own sub folder
33-
# to prevent audit from complaining
33+
# to prevent cargo audit from complaining
3434
#[[example]]
3535
#name = "hot_reload_tide"

examples/async_monitor.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ use futures::{
55
use notify::{Event, RecommendedWatcher, RecursiveMode, Watcher};
66
use std::path::Path;
77

8+
/// Async, futures channel based event watching
9+
fn main() {
10+
let path = std::env::args()
11+
.nth(1)
12+
.expect("Argument 1 needs to be a path");
13+
println!("watching {}", path);
14+
15+
futures::executor::block_on(async {
16+
if let Err(e) = async_watch(path).await {
17+
println!("error: {:?}", e)
18+
}
19+
});
20+
}
21+
822
fn async_watcher() -> notify::Result<(RecommendedWatcher, Receiver<notify::Result<Event>>)> {
923
let (mut tx, rx) = channel(1);
1024

@@ -34,17 +48,4 @@ async fn async_watch<P: AsRef<Path>>(path: P) -> notify::Result<()> {
3448
}
3549

3650
Ok(())
37-
}
38-
39-
fn main() {
40-
let path = std::env::args()
41-
.nth(1)
42-
.expect("Argument 1 needs to be a path");
43-
println!("watching {}", path);
44-
45-
futures::executor::block_on(async {
46-
if let Err(e) = async_watch(path).await {
47-
println!("error: {:?}", e)
48-
}
49-
});
50-
}
51+
}

examples/debounced.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use std::{path::Path, time::Duration};
33
use notify::{RecursiveMode, Watcher};
44
use notify_debouncer_mini::new_debouncer;
55

6+
/// Example for debouncer
67
fn main() {
8+
// emit some events by changing a file
79
std::thread::spawn(|| {
810
let path = Path::new("test.txt");
911
let _ = std::fs::remove_file(&path);
@@ -13,15 +15,18 @@ fn main() {
1315
}
1416
});
1517

18+
// setup debouncer
1619
let (tx, rx) = std::sync::mpsc::channel();
1720

21+
// No specific tickrate, max debounce time 2 seconds
1822
let mut debouncer = new_debouncer(Duration::from_secs(2), None, tx).unwrap();
1923

2024
debouncer
2125
.watcher()
2226
.watch(Path::new("."), RecursiveMode::Recursive)
2327
.unwrap();
2428

29+
// print all events, non returning
2530
for events in rx {
2631
for e in events {
2732
println!("{:?}", e);

examples/debounced_full_custom.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use notify_debouncer_mini::new_debouncer;
55

66
/// Debouncer with custom backend and waiting for exit
77
fn main() {
8+
// emit some events by changing a file
89
std::thread::spawn(|| {
910
let path = Path::new("test.txt");
1011
let _ = std::fs::remove_file(&path);
@@ -14,15 +15,16 @@ fn main() {
1415
}
1516
});
1617

18+
// setup debouncer
1719
let (tx, rx) = std::sync::mpsc::channel();
18-
20+
// select backend via fish operator, here PollWatcher backend
1921
let mut debouncer = new_debouncer_opt::<_,notify::PollWatcher>(Duration::from_secs(2), None, tx).unwrap();
2022

2123
debouncer
2224
.watcher()
2325
.watch(Path::new("."), RecursiveMode::Recursive)
2426
.unwrap();
25-
27+
// print all events, non returning
2628
for events in rx {
2729
for e in events {
2830
println!("{:?}", e);

examples/hot_reload_tide/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@ serde_json = "1.0"
1313
serde = "1.0.115"
1414
notify = { version = "5.0.0-pre.15", features = ["serde"], path = "../../notify" }
1515

16+
# required to prevent mixing with workspace
17+
# hack to prevent cargo audit from catching this
1618
[workspace]

examples/monitor_raw.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
22
use std::path::Path;
33

4+
fn main() {
5+
let path = std::env::args()
6+
.nth(1)
7+
.expect("Argument 1 needs to be a path");
8+
println!("watching {}", path);
9+
if let Err(e) = watch(path) {
10+
println!("error: {:?}", e)
11+
}
12+
}
13+
414
fn watch<P: AsRef<Path>>(path: P) -> notify::Result<()> {
515
let (tx, rx) = std::sync::mpsc::channel();
616

@@ -20,14 +30,4 @@ fn watch<P: AsRef<Path>>(path: P) -> notify::Result<()> {
2030
}
2131

2232
Ok(())
23-
}
24-
25-
fn main() {
26-
let path = std::env::args()
27-
.nth(1)
28-
.expect("Argument 1 needs to be a path");
29-
println!("watching {}", path);
30-
if let Err(e) = watch(path) {
31-
println!("error: {:?}", e)
32-
}
33-
}
33+
}

examples/watcher_kind.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
1-
use std::time::Duration;
1+
use std::{path::Path, time::Duration};
22

33
use notify::{poll::PollWatcherConfig, *};
44
fn main() {
5-
let (tx, _rx) = std::sync::mpsc::channel();
6-
let _watcher: Box<dyn Watcher> = if RecommendedWatcher::kind() == WatcherKind::PollWatcher {
5+
let (tx, rx) = std::sync::mpsc::channel();
6+
let mut watcher: Box<dyn Watcher> = if RecommendedWatcher::kind() == WatcherKind::PollWatcher {
7+
// custom config for PollWatcher kind
78
let config = PollWatcherConfig {
89
poll_interval: Duration::from_secs(1),
910
..Default::default()
1011
};
1112
Box::new(PollWatcher::with_config(tx, config).unwrap())
1213
} else {
14+
// use default config for everything else
1315
Box::new(RecommendedWatcher::new(tx).unwrap())
1416
};
15-
// use _watcher here
17+
18+
// watch some stuff
19+
watcher
20+
.watch(Path::new("."), RecursiveMode::Recursive)
21+
.unwrap();
22+
23+
// just print all events, this blocks forever
24+
for e in rx {
25+
println!("{:?}", e);
26+
}
1627
}

notify-debouncer-mini/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Debouncer for notify
2-
//!
2+
//!
33
//! # Installation
44
//!
55
//! ```toml
@@ -31,11 +31,11 @@
3131
//! debouncer.watcher().watch(Path::new("."), RecursiveMode::Recursive).unwrap();
3232
//! # }
3333
//! ```
34-
//!
34+
//!
3535
//! # Features
36-
//!
36+
//!
3737
//! The following feature can be turned on or off.
38-
//!
38+
//!
3939
//! - `crossbeam-channel` enabled by default, adds DebounceEventHandler support for crossbeam channels.
4040
//! - `serde` enabled serde support for events.
4141
#[cfg(feature = "serde")]

0 commit comments

Comments
 (0)