Skip to content

Commit cee15b4

Browse files
committed
Add support for watch_filtered to Windows.
1 parent 03d7061 commit cee15b4

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

notify/src/windows.rs

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl ReadDirectoryRequest {
6262
}
6363

6464
enum Action {
65-
Watch(PathBuf, RecursiveMode),
65+
Watch(PathBuf, RecursiveMode, WatchFilter),
6666
Unwatch(PathBuf),
6767
Stop,
6868
Configure(Config, BoundSender<Result<bool>>),
@@ -85,7 +85,7 @@ struct ReadDirectoryChangesServer {
8585
event_handler: Arc<Mutex<dyn EventHandler>>,
8686
meta_tx: Sender<MetaEvent>,
8787
cmd_tx: Sender<Result<PathBuf>>,
88-
watches: HashMap<PathBuf, WatchState>,
88+
watches: HashMap<PathBuf, (WatchState, WatchFilter)>,
8989
wakeup_sem: HANDLE,
9090
}
9191

@@ -127,14 +127,17 @@ impl ReadDirectoryChangesServer {
127127

128128
while let Ok(action) = self.rx.try_recv() {
129129
match action {
130-
Action::Watch(path, recursive_mode) => {
131-
let res = self.add_watch(path, recursive_mode.is_recursive());
132-
let _ = self.cmd_tx.send(res);
130+
Action::Watch(path, recursive_mode, watch_filter) => {
131+
let res = self.add_watch(path, recursive_mode.is_recursive(), watch_filter);
132+
let _ = match res {
133+
None => Ok(()),
134+
Some(res) => self.cmd_tx.send(res),
135+
};
133136
}
134137
Action::Unwatch(path) => self.remove_watch(path),
135138
Action::Stop => {
136139
stopped = true;
137-
for ws in self.watches.values() {
140+
for (ws, _) in self.watches.values() {
138141
stop_watch(ws, &self.meta_tx);
139142
}
140143
break;
@@ -164,13 +167,22 @@ impl ReadDirectoryChangesServer {
164167
}
165168
}
166169

167-
fn add_watch(&mut self, path: PathBuf, is_recursive: bool) -> Result<PathBuf> {
170+
fn add_watch(
171+
&mut self,
172+
path: PathBuf,
173+
is_recursive: bool,
174+
watch_filter: WatchFilter,
175+
) -> Option<Result<PathBuf>> {
176+
if !watch_filter.should_watch(&path) {
177+
return None;
178+
}
179+
168180
// path must exist and be either a file or directory
169181
if !path.is_dir() && !path.is_file() {
170-
return Err(
171-
Error::generic("Input watch path is neither a file nor a directory.")
172-
.add_path(path),
173-
);
182+
return Some(Err(Error::generic(
183+
"Input watch path is neither a file nor a directory.",
184+
)
185+
.add_path(path)));
174186
}
175187

176188
let (watching_file, dir_target) = {
@@ -200,7 +212,7 @@ impl ReadDirectoryChangesServer {
200212
);
201213

202214
if handle == INVALID_HANDLE_VALUE {
203-
return Err(if watching_file {
215+
return Some(Err(if watching_file {
204216
Error::generic(
205217
"You attempted to watch a single file, but parent \
206218
directory could not be opened.",
@@ -209,7 +221,7 @@ impl ReadDirectoryChangesServer {
209221
} else {
210222
// TODO: Call GetLastError for better error info?
211223
Error::path_not_found().add_path(path)
212-
});
224+
}));
213225
}
214226
}
215227
let wf = if watching_file {
@@ -223,7 +235,9 @@ impl ReadDirectoryChangesServer {
223235
unsafe {
224236
CloseHandle(handle);
225237
}
226-
return Err(Error::generic("Failed to create semaphore for watch.").add_path(path));
238+
return Some(Err(
239+
Error::generic("Failed to create semaphore for watch.").add_path(path)
240+
));
227241
}
228242
let rd = ReadData {
229243
dir: dir_target,
@@ -235,13 +249,13 @@ impl ReadDirectoryChangesServer {
235249
dir_handle: handle,
236250
complete_sem: semaphore,
237251
};
238-
self.watches.insert(path.clone(), ws);
252+
self.watches.insert(path.clone(), (ws, watch_filter));
239253
start_read(&rd, self.event_handler.clone(), handle, self.tx.clone());
240-
Ok(path)
254+
Some(Ok(path))
241255
}
242256

243257
fn remove_watch(&mut self, path: PathBuf) {
244-
if let Some(ws) = self.watches.remove(&path) {
258+
if let Some((ws, _)) = self.watches.remove(&path) {
245259
stop_watch(&ws, &self.meta_tx);
246260
}
247261
}
@@ -527,7 +541,12 @@ impl ReadDirectoryChangesWatcher {
527541
}
528542
}
529543

530-
fn watch_inner(&mut self, path: &Path, recursive_mode: RecursiveMode) -> Result<()> {
544+
fn watch_inner(
545+
&mut self,
546+
path: &Path,
547+
recursive_mode: RecursiveMode,
548+
watch_filter: WatchFilter,
549+
) -> Result<()> {
531550
let pb = if path.is_absolute() {
532551
path.to_owned()
533552
} else {
@@ -540,7 +559,7 @@ impl ReadDirectoryChangesWatcher {
540559
"Input watch path is neither a file nor a directory.",
541560
));
542561
}
543-
self.send_action_require_ack(Action::Watch(pb.clone(), recursive_mode), &pb)
562+
self.send_action_require_ack(Action::Watch(pb.clone(), recursive_mode, watch_filter), &pb)
544563
}
545564

546565
fn unwatch_inner(&mut self, path: &Path) -> Result<()> {
@@ -572,13 +591,13 @@ impl Watcher for ReadDirectoryChangesWatcher {
572591
&mut self,
573592
path: &Path,
574593
recursive_mode: RecursiveMode,
575-
_watch_filter: WatchFilter,
594+
watch_filter: WatchFilter,
576595
) -> crate::Result<()> {
577-
self.watch_inner(path, recursive_mode)
596+
self.watch_inner(path, recursive_mode, watch_filter)
578597
}
579598

580599
fn watch(&mut self, path: &Path, recursive_mode: RecursiveMode) -> Result<()> {
581-
self.watch_inner(path, recursive_mode)
600+
self.watch_inner(path, recursive_mode, WatchFilter::accept_all())
582601
}
583602

584603
fn unwatch(&mut self, path: &Path) -> Result<()> {

0 commit comments

Comments
 (0)