1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use std::{collections::BTreeMap, ffi::OsString, path::Path, sync::RwLock};
use once_cell::sync::OnceCell;
use walkdir::WalkDir;
use super::{FrameworkError, FrameworkGlobal};
mod hook;
pub struct VirtualFileSystem {
overrides: RwLock<BTreeMap<OsString, OsString>>,
}
impl FrameworkGlobal for VirtualFileSystem {
fn cell() -> &'static OnceCell<Self> {
static INSTANCE: OnceCell<VirtualFileSystem> = OnceCell::new();
&INSTANCE
}
fn create() -> Result<Self, FrameworkError> {
hook::install_vfs_hooks()?;
Ok(VirtualFileSystem {
overrides: RwLock::new(BTreeMap::default()),
})
}
}
impl VirtualFileSystem {
pub fn add_override_root<P: AsRef<Path>>(&self, path: P) {
let mut overrides = self.overrides.write().unwrap();
let root = path.as_ref();
for entry in WalkDir::new(root) {
match entry {
Ok(dir_entry) => {
let override_path = dir_entry.path();
let overridden_path = override_path
.strip_prefix(root)
.expect("override entry was outside of override root");
log::trace!("overriding {:?} with {:?}", overridden_path, override_path);
overrides.insert(
overridden_path.as_os_str().to_owned(),
override_path.as_os_str().to_owned(),
);
}
Err(e) => {
log::warn!("inaccessible file in vfs override root: {:#?}", e)
}
}
}
log::info!("vfs override added for {:?}", root);
}
pub fn find_override(&self, path: &OsString) -> Option<OsString> {
Some(self.overrides.read().unwrap().get(path)?.clone())
}
}