use walkdir::WalkDir;
use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watcher};
-use crate::{Roots, VfsRoot};
+use crate::{Roots, VfsRoot, VfsTask};
pub(crate) enum Task {
AddRoot { root: VfsRoot },
/// `TaskResult` transfers files read on the IO thread to the VFS on the main
/// thread.
#[derive(Debug)]
-pub enum TaskResult {
+pub(crate) enum TaskResult {
/// Emitted when we've recursively scanned a source root during the initial
/// load.
BulkLoadRoot { root: VfsRoot, files: Vec<(RelativePathBuf, String)> },
const WATCHER_DELAY: Duration = Duration::from_millis(250);
-pub(crate) type Worker = thread_worker::Worker<Task, TaskResult>;
+pub(crate) type Worker = thread_worker::Worker<Task, VfsTask>;
pub(crate) fn start(roots: Arc<Roots>) -> Worker {
// This is a pretty elaborate setup of threads & channels! It is
// explained by the following concerns:
fn watch_root(
watcher: Option<&mut RecommendedWatcher>,
- sender: &Sender<TaskResult>,
+ sender: &Sender<VfsTask>,
roots: &Roots,
root: VfsRoot,
) {
Some((path, text))
})
.collect();
- sender.send(TaskResult::BulkLoadRoot { root, files }).unwrap();
+ let res = TaskResult::BulkLoadRoot { root, files };
+ sender.send(VfsTask(res)).unwrap();
log::debug!("... loaded {}", root_path.display());
}
fn handle_change(
watcher: Option<&mut RecommendedWatcher>,
- sender: &Sender<TaskResult>,
+ sender: &Sender<VfsTask>,
roots: &Roots,
path: PathBuf,
kind: ChangeKind,
.try_for_each(|rel_path| {
let abs_path = rel_path.to_path(&roots.path(root));
let text = read_to_string(&abs_path);
- sender.send(TaskResult::SingleFile { root, path: rel_path, text })
+ let res = TaskResult::SingleFile { root, path: rel_path, text };
+ sender.send(VfsTask(res))
})
.unwrap()
}
ChangeKind::Write | ChangeKind::Remove => {
let text = read_to_string(&path);
- sender.send(TaskResult::SingleFile { root, path: rel_path, text }).unwrap();
+ let res = TaskResult::SingleFile { root, path: rel_path, text };
+ sender.send(VfsTask(res)).unwrap();
}
}
}
roots::Roots,
};
-pub use crate::{
- io::TaskResult as VfsTask,
- roots::VfsRoot,
-};
+pub use crate::roots::VfsRoot;
+
+/// Opaque wrapper around file-system event.
+///
+/// Calling code is expected to just pass `VfsTask` to `handle_task` method. It
+/// is exposed as a public API so that the caller can plug vfs events into the
+/// main event loop and be notified when changes happen.
+pub struct VfsTask(TaskResult);
+
+impl fmt::Debug for VfsTask {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("VfsTask { ... }")
+ }
+}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VfsFile(pub u32);
mem::replace(&mut self.pending_changes, Vec::new())
}
- pub fn task_receiver(&self) -> &Receiver<io::TaskResult> {
+ pub fn task_receiver(&self) -> &Receiver<VfsTask> {
self.worker.receiver()
}
- pub fn handle_task(&mut self, task: io::TaskResult) {
- match task {
+ pub fn handle_task(&mut self, task: VfsTask) {
+ match task.0 {
TaskResult::BulkLoadRoot { root, files } => {
let mut cur_files = Vec::new();
// While we were scanning the root in the background, a file might have