summaryrefslogtreecommitdiff
path: root/src/watch/notify_event.rs
diff options
context:
space:
mode:
authormo8it <mo8it@proton.me>2024-09-18 01:43:48 +0200
committermo8it <mo8it@proton.me>2024-09-18 01:43:48 +0200
commit89c40ba25672b2da17e2fcc5bc742462699d54dd (patch)
treef46f89010e2cd19034db5c69d4dc5ffb6fb0f6c3 /src/watch/notify_event.rs
parente56ae6d65144d0a0bc8cc6759c89e59658a71497 (diff)
Optimize the file watcher
Diffstat (limited to 'src/watch/notify_event.rs')
-rw-r--r--src/watch/notify_event.rs91
1 files changed, 53 insertions, 38 deletions
diff --git a/src/watch/notify_event.rs b/src/watch/notify_event.rs
index 9b23525..5ed8fd1 100644
--- a/src/watch/notify_event.rs
+++ b/src/watch/notify_event.rs
@@ -1,7 +1,10 @@
-use notify_debouncer_mini::{DebounceEventResult, DebouncedEventKind};
-use std::sync::mpsc::Sender;
+use notify::{
+ event::{MetadataKind, ModifyKind},
+ Event, EventKind,
+};
+use std::sync::{atomic::Ordering::Relaxed, mpsc::Sender};
-use super::WatchEvent;
+use super::{WatchEvent, EXERCISE_RUNNING};
pub struct NotifyEventHandler {
pub sender: Sender<WatchEvent>,
@@ -9,44 +12,56 @@ pub struct NotifyEventHandler {
pub exercise_names: &'static [&'static [u8]],
}
-impl notify_debouncer_mini::DebounceEventHandler for NotifyEventHandler {
- fn handle_event(&mut self, input_event: DebounceEventResult) {
- let output_event = match input_event {
- Ok(input_event) => {
- let Some(exercise_ind) = input_event
- .iter()
- .filter_map(|input_event| {
- if input_event.kind != DebouncedEventKind::Any {
- return None;
- }
-
- let file_name = input_event.path.file_name()?.to_str()?.as_bytes();
-
- if file_name.len() < 4 {
- return None;
- }
- let (file_name_without_ext, ext) = file_name.split_at(file_name.len() - 3);
-
- if ext != b".rs" {
- return None;
- }
-
- self.exercise_names
- .iter()
- .position(|exercise_name| *exercise_name == file_name_without_ext)
- })
- .min()
- else {
- return;
- };
+impl notify::EventHandler for NotifyEventHandler {
+ fn handle_event(&mut self, input_event: notify::Result<Event>) {
+ if EXERCISE_RUNNING.load(Relaxed) {
+ return;
+ }
- WatchEvent::FileChange { exercise_ind }
+ let input_event = match input_event {
+ Ok(v) => v,
+ Err(e) => {
+ // An error occurs when the receiver is dropped.
+ // After dropping the receiver, the debouncer guard should also be dropped.
+ let _ = self.sender.send(WatchEvent::NotifyErr(e));
+ return;
}
- Err(e) => WatchEvent::NotifyErr(e),
};
- // An error occurs when the receiver is dropped.
- // After dropping the receiver, the debouncer guard should also be dropped.
- let _ = self.sender.send(output_event);
+ match input_event.kind {
+ EventKind::Any => (),
+ EventKind::Modify(modify_kind) => match modify_kind {
+ ModifyKind::Any | ModifyKind::Data(_) => (),
+ ModifyKind::Metadata(metadata_kind) => match metadata_kind {
+ MetadataKind::Any | MetadataKind::WriteTime => (),
+ MetadataKind::AccessTime
+ | MetadataKind::Permissions
+ | MetadataKind::Ownership
+ | MetadataKind::Extended
+ | MetadataKind::Other => return,
+ },
+ ModifyKind::Name(_) | ModifyKind::Other => return,
+ },
+ EventKind::Access(_)
+ | EventKind::Create(_)
+ | EventKind::Remove(_)
+ | EventKind::Other => return,
+ }
+
+ let _ = input_event
+ .paths
+ .into_iter()
+ .filter_map(|path| {
+ let file_name = path.file_name()?.to_str()?.as_bytes();
+
+ let [file_name_without_ext @ .., b'.', b'r', b's'] = file_name else {
+ return None;
+ };
+
+ self.exercise_names
+ .iter()
+ .position(|exercise_name| *exercise_name == file_name_without_ext)
+ })
+ .try_for_each(|exercise_ind| self.sender.send(WatchEvent::FileChange { exercise_ind }));
}
}