aboutsummaryrefslogtreecommitdiff
path: root/crates/vfs/src/file_set.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/vfs/src/file_set.rs')
-rw-r--r--crates/vfs/src/file_set.rs42
1 files changed, 42 insertions, 0 deletions
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs
index 49ca593ac..348b6dbfd 100644
--- a/crates/vfs/src/file_set.rs
+++ b/crates/vfs/src/file_set.rs
@@ -9,6 +9,7 @@ use rustc_hash::FxHashMap;
9 9
10use crate::{AnchoredPath, FileId, Vfs, VfsPath}; 10use crate::{AnchoredPath, FileId, Vfs, VfsPath};
11 11
12/// A set of [`VfsPath`]s identified by [`FileId`]s.
12#[derive(Default, Clone, Eq, PartialEq)] 13#[derive(Default, Clone, Eq, PartialEq)]
13pub struct FileSet { 14pub struct FileSet {
14 files: FxHashMap<VfsPath, FileId>, 15 files: FxHashMap<VfsPath, FileId>,
@@ -16,9 +17,15 @@ pub struct FileSet {
16} 17}
17 18
18impl FileSet { 19impl FileSet {
20 /// Returns the number of stored paths.
19 pub fn len(&self) -> usize { 21 pub fn len(&self) -> usize {
20 self.files.len() 22 self.files.len()
21 } 23 }
24
25 /// Get the id of the file corresponding to `path`.
26 ///
27 /// If either `path`'s [`anchor`](AnchoredPath::anchor) or the resolved path is not in
28 /// the set, returns [`None`].
22 pub fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> { 29 pub fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
23 let mut base = self.paths[&path.anchor].clone(); 30 let mut base = self.paths[&path.anchor].clone();
24 base.pop(); 31 base.pop();
@@ -26,19 +33,26 @@ impl FileSet {
26 self.files.get(&path).copied() 33 self.files.get(&path).copied()
27 } 34 }
28 35
36 /// Get the id corresponding to `path` if it exists in the set.
29 pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> { 37 pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> {
30 self.files.get(path) 38 self.files.get(path)
31 } 39 }
32 40
41 /// Get the path corresponding to `file` if it exists in the set.
33 pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> { 42 pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> {
34 self.paths.get(file) 43 self.paths.get(file)
35 } 44 }
36 45
46 /// Insert the `file_id, path` pair into the set.
47 ///
48 /// # Note
49 /// Multiple [`FileId`] can be mapped to the same [`VfsPath`], and vice-versa.
37 pub fn insert(&mut self, file_id: FileId, path: VfsPath) { 50 pub fn insert(&mut self, file_id: FileId, path: VfsPath) {
38 self.files.insert(path.clone(), file_id); 51 self.files.insert(path.clone(), file_id);
39 self.paths.insert(file_id, path); 52 self.paths.insert(file_id, path);
40 } 53 }
41 54
55 /// Iterate over this set's ids.
42 pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ { 56 pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ {
43 self.paths.keys().copied() 57 self.paths.keys().copied()
44 } 58 }
@@ -50,6 +64,23 @@ impl fmt::Debug for FileSet {
50 } 64 }
51} 65}
52 66
67/// This contains path prefixes to partition a [`Vfs`] into [`FileSet`]s.
68///
69/// # Example
70/// ```rust
71/// # use vfs::{file_set::FileSetConfigBuilder, VfsPath, Vfs};
72/// let mut builder = FileSetConfigBuilder::default();
73/// builder.add_file_set(vec![VfsPath::new_virtual_path("/src".to_string())]);
74/// let config = builder.build();
75/// let mut file_system = Vfs::default();
76/// file_system.set_file_contents(VfsPath::new_virtual_path("/src/main.rs".to_string()), Some(vec![]));
77/// file_system.set_file_contents(VfsPath::new_virtual_path("/src/lib.rs".to_string()), Some(vec![]));
78/// file_system.set_file_contents(VfsPath::new_virtual_path("/build.rs".to_string()), Some(vec![]));
79/// // contains the sets :
80/// // { "/src/main.rs", "/src/lib.rs" }
81/// // { "build.rs" }
82/// let sets = config.partition(&file_system);
83/// ```
53#[derive(Debug)] 84#[derive(Debug)]
54pub struct FileSetConfig { 85pub struct FileSetConfig {
55 n_file_sets: usize, 86 n_file_sets: usize,
@@ -63,9 +94,14 @@ impl Default for FileSetConfig {
63} 94}
64 95
65impl FileSetConfig { 96impl FileSetConfig {
97 /// Returns a builder for `FileSetConfig`.
66 pub fn builder() -> FileSetConfigBuilder { 98 pub fn builder() -> FileSetConfigBuilder {
67 FileSetConfigBuilder::default() 99 FileSetConfigBuilder::default()
68 } 100 }
101
102 /// Partition `vfs` into `FileSet`s.
103 ///
104 /// Creates a new [`FileSet`] for every set of prefixes in `self`.
69 pub fn partition(&self, vfs: &Vfs) -> Vec<FileSet> { 105 pub fn partition(&self, vfs: &Vfs) -> Vec<FileSet> {
70 let mut scratch_space = Vec::new(); 106 let mut scratch_space = Vec::new();
71 let mut res = vec![FileSet::default(); self.len()]; 107 let mut res = vec![FileSet::default(); self.len()];
@@ -91,6 +127,7 @@ impl FileSetConfig {
91 } 127 }
92} 128}
93 129
130/// Builder for [`FileSetConfig`].
94pub struct FileSetConfigBuilder { 131pub struct FileSetConfigBuilder {
95 roots: Vec<Vec<VfsPath>>, 132 roots: Vec<Vec<VfsPath>>,
96} 133}
@@ -102,12 +139,17 @@ impl Default for FileSetConfigBuilder {
102} 139}
103 140
104impl FileSetConfigBuilder { 141impl FileSetConfigBuilder {
142 /// Returns the number of sets currently held.
105 pub fn len(&self) -> usize { 143 pub fn len(&self) -> usize {
106 self.roots.len() 144 self.roots.len()
107 } 145 }
146
147 /// Add a new set of paths prefixes.
108 pub fn add_file_set(&mut self, roots: Vec<VfsPath>) { 148 pub fn add_file_set(&mut self, roots: Vec<VfsPath>) {
109 self.roots.push(roots) 149 self.roots.push(roots)
110 } 150 }
151
152 /// Build the `FileSetConfig`.
111 pub fn build(self) -> FileSetConfig { 153 pub fn build(self) -> FileSetConfig {
112 let n_file_sets = self.roots.len() + 1; 154 let n_file_sets = self.roots.len() + 1;
113 let map = { 155 let map = {