Skip to content

Commit 1174daa

Browse files
committed
rework docs and example documentation
1 parent cf37946 commit 1174daa

16 files changed

Lines changed: 143 additions & 177 deletions

File tree

README.md

Lines changed: 12 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,32 @@
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]
17+
- [Examples][examples]
2418
- [Crate page][crate]
2519
- [Changelog][changelog]
26-
- Earliest supported Rust version: **1.47.0**
20+
- [Upgrading from v5](UPGRADING_V4_TO_V5.md)
21+
- Earliest supported Rust version: **1.56**
22+
- **incomplete [Guides and in-depth docs][wiki]**
2723

2824
As used by: [alacritty], [cargo watch], [cobalt], [docket], [mdBook], [pax],
2925
[rdiff], [rust-analyzer], [timetrack], [watchexec], [xi-editor], [watchfiles],
3026
and others.
3127

32-
## Installation
28+
## Base Installation
3329

3430
```toml
3531
[dependencies]
36-
crossbeam-channel = "0.4.0"
3732
notify = "5.0.0-pre.15"
3833
```
3934

4035
## Usage
4136

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.
37+
A basic example
4438

4539
```rust
4640
use notify::{RecommendedWatcher, RecursiveMode, Result, watcher};
@@ -68,100 +62,18 @@ fn main() -> Result<()> {
6862
}
6963
```
7064

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-
15365
## Platforms
15466

15567
- Linux / Android: inotify
156-
- macOS: FSEvents
68+
- macOS: FSEvents or kqueue, see features
15769
- Windows: ReadDirectoryChangesW
15870
- FreeBSD / NetBSD / OpenBSD / DragonflyBSD: kqueue
15971
- All platforms: polling
16072

16173
### FSEvents
16274

16375
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
76+
some events cannot be observed easily when trying to follow files that do not
16577
belong to you. In this case, reverting to the pollwatcher can fix the issue,
16678
with a slight performance cost.
16779

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

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

188100
[Chokidar]: https://github.com/paulmillr/chokidar
189101
[FileSystemEventSecurity]: https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/FSEvents_ProgGuide/FileSystemEventSecurity/FileSystemEventSecurity.html
102+
[debouncer]: https://github.com/notify-rs/notify/tree/main/notify-debouncer-mini
190103
[Félix Saparelli]: https://passcod.name
191104
[alacritty]: https://github.com/jwilm/alacritty
192105
[alert-after]: https://github.com/frewsxcv/alert-after
@@ -215,3 +128,4 @@ Written by [Félix Saparelli] and awesome [contributors].
215128
[wiki]: https://github.com/notify-rs/notify/wiki
216129
[xi-editor]: https://xi-editor.io/
217130
[watchfiles]: https://watchfiles.helpmanual.io/
131+
[examples]: examples/

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)