diff options
Diffstat (limited to 'crates/server/src/vfs.rs')
-rw-r--r-- | crates/server/src/vfs.rs | 76 |
1 files changed, 42 insertions, 34 deletions
diff --git a/crates/server/src/vfs.rs b/crates/server/src/vfs.rs index 2acc3f55f..69a7654af 100644 --- a/crates/server/src/vfs.rs +++ b/crates/server/src/vfs.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | path::PathBuf, | 2 | path::{PathBuf, Path}, |
3 | fs, | 3 | fs, |
4 | }; | 4 | }; |
5 | 5 | ||
@@ -20,46 +20,54 @@ pub struct FileEvent { | |||
20 | #[derive(Debug)] | 20 | #[derive(Debug)] |
21 | pub enum FileEventKind { | 21 | pub enum FileEventKind { |
22 | Add(String), | 22 | Add(String), |
23 | #[allow(unused)] | ||
24 | Remove, | ||
25 | } | 23 | } |
26 | 24 | ||
27 | pub fn watch(roots: Vec<PathBuf>) -> (Receiver<Vec<FileEvent>>, ThreadWatcher) { | 25 | pub fn roots_loader() -> (Sender<PathBuf>, Receiver<(PathBuf, Vec<FileEvent>)>, ThreadWatcher) { |
28 | let (sender, receiver) = bounded(16); | 26 | let (path_sender, path_receiver) = bounded::<PathBuf>(2048); |
29 | let watcher = ThreadWatcher::spawn("vfs", move || run(roots, sender)); | 27 | let (event_sender, event_receiver) = bounded::<(PathBuf, Vec<FileEvent>)>(1); |
30 | (receiver, watcher) | 28 | let thread = ThreadWatcher::spawn("roots loader", move || { |
29 | path_receiver | ||
30 | .into_iter() | ||
31 | .map(|path| { | ||
32 | debug!("loading {} ...", path.as_path().display()); | ||
33 | let events = load_root(path.as_path()); | ||
34 | debug!("... loaded {}", path.as_path().display()); | ||
35 | (path, events) | ||
36 | }) | ||
37 | .for_each(|it| event_sender.send(it)) | ||
38 | }); | ||
39 | |||
40 | (path_sender, event_receiver, thread) | ||
31 | } | 41 | } |
32 | 42 | ||
33 | fn run(roots: Vec<PathBuf>, sender: Sender<Vec<FileEvent>>) { | 43 | fn load_root(path: &Path) -> Vec<FileEvent> { |
34 | for root in roots { | 44 | let mut res = Vec::new(); |
35 | let mut events = Vec::new(); | 45 | for entry in WalkDir::new(path) { |
36 | for entry in WalkDir::new(root.as_path()) { | 46 | let entry = match entry { |
37 | let entry = match entry { | 47 | Ok(entry) => entry, |
38 | Ok(entry) => entry, | 48 | Err(e) => { |
39 | Err(e) => { | 49 | warn!("watcher error: {}", e); |
40 | warn!("watcher error: {}", e); | ||
41 | continue; | ||
42 | } | ||
43 | }; | ||
44 | if !entry.file_type().is_file() { | ||
45 | continue; | 50 | continue; |
46 | } | 51 | } |
47 | let path = entry.path(); | 52 | }; |
48 | if path.extension().and_then(|os| os.to_str()) != Some("rs") { | 53 | if !entry.file_type().is_file() { |
54 | continue; | ||
55 | } | ||
56 | let path = entry.path(); | ||
57 | if path.extension().and_then(|os| os.to_str()) != Some("rs") { | ||
58 | continue; | ||
59 | } | ||
60 | let text = match fs::read_to_string(path) { | ||
61 | Ok(text) => text, | ||
62 | Err(e) => { | ||
63 | warn!("watcher error: {}", e); | ||
49 | continue; | 64 | continue; |
50 | } | 65 | } |
51 | let text = match fs::read_to_string(path) { | 66 | }; |
52 | Ok(text) => text, | 67 | res.push(FileEvent { |
53 | Err(e) => { | 68 | path: path.to_owned(), |
54 | warn!("watcher error: {}", e); | 69 | kind: FileEventKind::Add(text), |
55 | continue; | 70 | }) |
56 | } | ||
57 | }; | ||
58 | events.push(FileEvent { | ||
59 | path: path.to_owned(), | ||
60 | kind: FileEventKind::Add(text), | ||
61 | }) | ||
62 | } | ||
63 | sender.send(events) | ||
64 | } | 71 | } |
72 | res | ||
65 | } | 73 | } |