]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
1 | # Notify |
2 | ||
3 | [![» Crate](https://flat.badgen.net/crates/v/notify)][crate] | |
4 | [![» Docs](https://flat.badgen.net/badge/api/docs.rs/df3600)][docs] | |
5 | [![» CI](https://flat.badgen.net/travis/notify-rs/notify/main)][build] | |
6 | [![» Downloads](https://flat.badgen.net/crates/d/notify)][crate] | |
7 | [![» Conduct](https://flat.badgen.net/badge/contributor/covenant/5e0d73)][coc] | |
8 | [![» Public Domain](https://flat.badgen.net/badge/license/CC0-1.0/purple)][cc0] | |
9 | ||
10 | _Cross-platform filesystem notification library for Rust._ | |
11 | ||
12 | **Caution! This is unstable code!** | |
13 | ||
14 | You likely want either [the latest 4.0 release] or [5.0.0-pre.3]. | |
15 | ||
16 | [the latest 4.0 release]: https://github.com/notify-rs/notify/tree/v4.0.13#notify | |
17 | [5.0.0-pre.3]: https://github.com/notify-rs/notify/tree/v5.0.0-pre.3#notify | |
18 | ||
19 | (Looking for desktop notifications instead? Have a look at [notify-rust] or | |
20 | [alert-after]!) | |
21 | ||
22 | - **incomplete [Guides and in-depth docs][wiki]** | |
23 | - [API Documentation][docs] | |
24 | - [Crate page][crate] | |
25 | - [Changelog][changelog] | |
26 | - Earliest supported Rust version: **1.32.0** | |
27 | ||
28 | As used by: [alacritty], [cargo watch], [cobalt], [docket], [mdBook], [pax] | |
29 | [rdiff], [rust-analyzer], [timetrack], [watchexec], [xi-editor], and others. | |
30 | ||
31 | ## Installation | |
32 | ||
33 | ```toml | |
34 | [dependencies] | |
35 | crossbeam-channel = "0.4.0" | |
36 | notify = "5.0.0-pre.3" | |
37 | ``` | |
38 | ||
39 | ## Usage | |
40 | ||
41 | The examples below are aspirational only, to preview what the final release may | |
42 | have looked like. They may not work. Refer to [the API documentation][docs] instead. | |
43 | ||
44 | ```rust | |
45 | use notify::{RecommendedWatcher, RecursiveMode, Result, watcher}; | |
46 | use std::time::Duration; | |
47 | ||
48 | fn main() -> Result<()> { | |
49 | // Automatically select the best implementation for your platform. | |
50 | // You can also access each implementation directly e.g. INotifyWatcher. | |
51 | let mut watcher = watcher(Duration::from_secs(2))?; | |
52 | ||
53 | // Add a path to be watched. All files and directories at that path and | |
54 | // below will be monitored for changes. | |
55 | watcher.watch("/home/test/notify", RecursiveMode::Recursive)?; | |
56 | ||
57 | // This is a simple loop, but you may want to use more complex logic here, | |
58 | // for example to handle I/O. | |
59 | for event in &watcher { | |
60 | match event { | |
61 | Ok(event) => println!("changed: {:?}", event.path), | |
62 | Err(err) => println!("watch error: {:?}", err), | |
63 | }; | |
64 | } | |
65 | ||
66 | Ok(()) | |
67 | } | |
68 | ``` | |
69 | ||
70 | ### With a channel | |
71 | ||
72 | To get a channel for advanced or flexible cases, use: | |
73 | ||
74 | ```rust | |
75 | let rx = watcher.channel(); | |
76 | ||
77 | loop { | |
78 | match rx.recv() { | |
79 | // ... | |
80 | } | |
81 | } | |
82 | ``` | |
83 | ||
84 | To pass in a channel manually: | |
85 | ||
86 | ```rust | |
87 | let (tx, rx) = crossbeam_channel::unbounded(); | |
88 | let mut watcher: RecommendedWatcher = Watcher::with_channel(tx, Duration::from_secs(2))?; | |
89 | ||
90 | for event in rx.iter() { | |
91 | // ... | |
92 | } | |
93 | ``` | |
94 | ||
95 | ### With precise events | |
96 | ||
97 | By default, Notify issues generic events that carry little additional | |
98 | information beyond what path was affected. On some platforms, more is | |
99 | available; stay aware though that how exactly that manifests varies. To enable | |
100 | precise events, use: | |
101 | ||
102 | ```rust | |
103 | use notify::Config; | |
104 | watcher.configure(Config::PreciseEvents(true)); | |
105 | ``` | |
106 | ||
107 | ### With notice events | |
108 | ||
109 | Sometimes you want to respond to some events straight away, but not give up the | |
110 | advantages of debouncing. Notice events appear once immediately when the occur | |
111 | during a debouncing period, and then a second time as usual at the end of the | |
112 | debouncing period: | |
113 | ||
114 | ```rust | |
115 | use notify::Config; | |
116 | watcher.configure(Config::NoticeEvents(true)); | |
117 | ``` | |
118 | ||
119 | ### With ongoing events | |
120 | ||
121 | Sometimes frequent writes may be missed or not noticed often enough. Ongoing | |
122 | write events can be enabled to emit more events even while debouncing: | |
123 | ||
124 | ```rust | |
125 | use notify::Config; | |
126 | watcher.configure(Config::OngoingEvents(Some(Duration::from_millis(500)))); | |
127 | ``` | |
128 | ||
129 | ### Without debouncing | |
130 | ||
131 | To receive events as they are emitted, without debouncing at all: | |
132 | ||
133 | ```rust | |
134 | let mut watcher = immediate_watcher()?; | |
135 | ``` | |
136 | ||
137 | With a channel: | |
138 | ||
139 | ```rust | |
140 | let (tx, rx) = unbounded(); | |
141 | let mut watcher: RecommendedWatcher = Watcher::immediate_with_channel(tx)?; | |
142 | ``` | |
143 | ||
144 | ### Serde | |
145 | ||
146 | Events can be serialisable via [serde]. To enable the feature: | |
147 | ||
148 | ```toml | |
149 | notify = { version = "5.0.0-pre.3", features = ["serde"] } | |
150 | ``` | |
151 | ||
152 | ## Platforms | |
153 | ||
154 | - Linux / Android: inotify | |
155 | - macOS: FSEvents | |
156 | - Windows: ReadDirectoryChangesW | |
157 | - All platforms: polling | |
158 | ||
159 | ### FSEvents | |
160 | ||
161 | Due to the inner security model of FSEvents (see [FileSystemEventSecurity]), | |
162 | some event cannot be observed easily when trying to follow files that do not | |
163 | belong to you. In this case, reverting to the pollwatcher can fix the issue, | |
164 | with a slight performance cost. | |
165 | ||
166 | ## License | |
167 | ||
168 | Notify was undergoing a transition to using the | |
169 | [Artistic License 2.0][artistic] from [CC Zero 1.0][cc0]. A part of | |
170 | the code is only under CC0, and another part, including _all new code_ since | |
171 | commit [`3378ac5a`], is under _both_ CC0 and Artistic. When the project was to be | |
172 | entirely free of CC0 code, the license would be formally changed (and that would | |
173 | have incurred a major version bump). As part of this, contributions to Notify since | |
174 | would agree to release under both. | |
175 | ||
176 | [`3378ac5a`]: https://github.com/notify-rs/notify/commit/3378ac5ad5f174dfeacce6edadd7ded1a08d384e | |
177 | ||
178 | ## Origins | |
179 | ||
180 | Inspired by Go's [fsnotify] and Node.js's [Chokidar], born out of need for | |
181 | [cargo watch], and general frustration at the non-existence of C/Rust | |
182 | cross-platform notify libraries. | |
183 | ||
184 | Written by [Félix Saparelli] and awesome [contributors]. | |
185 | ||
186 | [Chokidar]: https://github.com/paulmillr/chokidar | |
187 | [FileSystemEventSecurity]: https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/FSEvents_ProgGuide/FileSystemEventSecurity/FileSystemEventSecurity.html | |
188 | [Félix Saparelli]: https://passcod.name | |
189 | [alacritty]: https://github.com/jwilm/alacritty | |
190 | [alert-after]: https://github.com/frewsxcv/alert-after | |
191 | [artistic]: ./LICENSE.ARTISTIC | |
192 | [build]: https://travis-ci.com/notify-rs/notify | |
193 | [cargo watch]: https://github.com/passcod/cargo-watch | |
194 | [cc0]: ./LICENSE | |
195 | [changelog]: ./CHANGELOG.md | |
196 | [cobalt]: https://github.com/cobalt-org/cobalt.rs | |
197 | [coc]: http://contributor-covenant.org/version/1/4/ | |
198 | [contributors]: https://github.com/notify-rs/notify/graphs/contributors | |
199 | [crate]: https://crates.io/crates/notify | |
200 | [docket]: https://iwillspeak.github.io/docket/ | |
201 | [docs]: https://docs.rs/notify/5.0.0-pre.3/notify/ | |
202 | [fsnotify]: https://github.com/go-fsnotify/fsnotify | |
203 | [handlebars-iron]: https://github.com/sunng87/handlebars-iron | |
204 | [hotwatch]: https://github.com/francesca64/hotwatch | |
205 | [mdBook]: https://github.com/rust-lang-nursery/mdBook | |
206 | [notify-rust]: https://github.com/hoodie/notify-rust | |
207 | [pax]: https://pax.js.org/ | |
208 | [rdiff]: https://github.com/dyule/rdiff | |
209 | [rust-analyzer]: https://github.com/rust-analyzer/rust-analyzer | |
210 | [serde]: https://serde.rs/ | |
211 | [timetrack]: https://github.com/joshmcguigan/timetrack | |
212 | [watchexec]: https://github.com/mattgreen/watchexec | |
213 | [wiki]: https://github.com/notify-rs/notify/wiki | |
214 | [xi-editor]: https://xi-editor.io/ |