diff options
Diffstat (limited to 'crates/ra_vfs/src/lib.rs')
-rw-r--r-- | crates/ra_vfs/src/lib.rs | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs new file mode 100644 index 000000000..8f6abadb7 --- /dev/null +++ b/crates/ra_vfs/src/lib.rs | |||
@@ -0,0 +1,128 @@ | |||
1 | //! VFS stands for Virtual File System. | ||
2 | //! | ||
3 | //! When doing analysis, we don't want to do any IO, we want to keep all source | ||
4 | //! code in memory. However, the actual source code is stored on disk, so you | ||
5 | //! need to get it into the memory in the first place somehow. VFS is the | ||
6 | //! component which does this. | ||
7 | //! | ||
8 | //! It also is responsible for watching the disk for changes, and for merging | ||
9 | //! editor state (modified, unsaved files) with disk state. | ||
10 | //! | ||
11 | //! VFS is based on a concept of roots: a set of directories on the file system | ||
12 | //! whihc are watched for changes. Typically, there will be a root for each | ||
13 | //! Cargo package. | ||
14 | mod arena; | ||
15 | mod io; | ||
16 | |||
17 | use std::{ | ||
18 | cmp::Reverse, | ||
19 | path::{Path, PathBuf}, | ||
20 | ffi::OsStr, | ||
21 | sync::Arc, | ||
22 | }; | ||
23 | |||
24 | use relative_path::RelativePathBuf; | ||
25 | use crate::arena::{ArenaId, Arena}; | ||
26 | |||
27 | /// `RootFilter` is a predicate that checks if a file can belong to a root | ||
28 | struct RootFilter { | ||
29 | root: PathBuf, | ||
30 | file_filter: fn(&Path) -> bool, | ||
31 | } | ||
32 | |||
33 | impl RootFilter { | ||
34 | fn new(root: PathBuf) -> RootFilter { | ||
35 | RootFilter { | ||
36 | root, | ||
37 | file_filter: rs_extension_filter, | ||
38 | } | ||
39 | } | ||
40 | fn can_contain(&self, path: &Path) -> bool { | ||
41 | (self.file_filter)(path) && path.starts_with(&self.root) | ||
42 | } | ||
43 | } | ||
44 | |||
45 | fn rs_extension_filter(p: &Path) -> bool { | ||
46 | p.extension() == Some(OsStr::new("rs")) | ||
47 | } | ||
48 | |||
49 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
50 | pub struct VfsRoot(u32); | ||
51 | |||
52 | impl ArenaId for VfsRoot { | ||
53 | fn from_u32(idx: u32) -> VfsRoot { | ||
54 | VfsRoot(idx) | ||
55 | } | ||
56 | fn to_u32(self) -> u32 { | ||
57 | self.0 | ||
58 | } | ||
59 | } | ||
60 | |||
61 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
62 | pub struct VfsFile(u32); | ||
63 | |||
64 | impl ArenaId for VfsFile { | ||
65 | fn from_u32(idx: u32) -> VfsFile { | ||
66 | VfsFile(idx) | ||
67 | } | ||
68 | fn to_u32(self) -> u32 { | ||
69 | self.0 | ||
70 | } | ||
71 | } | ||
72 | |||
73 | struct VfsFileData { | ||
74 | root: VfsRoot, | ||
75 | path: RelativePathBuf, | ||
76 | text: Arc<String>, | ||
77 | } | ||
78 | |||
79 | #[derive(Default)] | ||
80 | struct Vfs { | ||
81 | roots: Arena<VfsRoot, RootFilter>, | ||
82 | files: Arena<VfsFile, VfsFileData>, | ||
83 | // pending_changes: Vec<PendingChange>, | ||
84 | } | ||
85 | |||
86 | impl Vfs { | ||
87 | pub fn new(mut roots: Vec<PathBuf>) -> Vfs { | ||
88 | let mut res = Vfs::default(); | ||
89 | |||
90 | roots.sort_by_key(|it| Reverse(it.as_os_str().len())); | ||
91 | |||
92 | for path in roots { | ||
93 | res.roots.alloc(RootFilter::new(path)); | ||
94 | } | ||
95 | res | ||
96 | } | ||
97 | |||
98 | pub fn add_file_overlay(&mut self, path: &Path, content: String) {} | ||
99 | |||
100 | pub fn change_file_overlay(&mut self, path: &Path, new_content: String) {} | ||
101 | |||
102 | pub fn remove_file_overlay(&mut self, path: &Path) {} | ||
103 | |||
104 | pub fn commit_changes(&mut self) -> Vec<VfsChange> { | ||
105 | unimplemented!() | ||
106 | } | ||
107 | } | ||
108 | |||
109 | #[derive(Debug, Clone)] | ||
110 | pub enum VfsChange { | ||
111 | AddRoot { | ||
112 | root: VfsRoot, | ||
113 | files: Vec<(VfsFile, RelativePathBuf, Arc<String>)>, | ||
114 | }, | ||
115 | AddFile { | ||
116 | file: VfsFile, | ||
117 | root: VfsRoot, | ||
118 | path: RelativePathBuf, | ||
119 | text: Arc<String>, | ||
120 | }, | ||
121 | RemoveFile { | ||
122 | file: VfsFile, | ||
123 | }, | ||
124 | ChangeFile { | ||
125 | file: VfsFile, | ||
126 | text: Arc<String>, | ||
127 | }, | ||
128 | } | ||