vfs: Snapshots, roughly

This commit is contained in:
Lucien Greathouse
2020-02-19 23:58:09 -08:00
parent 6322c1f46d
commit 1b24cd36e0
3 changed files with 90 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
mod memory_backend;
mod noop_backend;
mod snapshot;
mod std_backend;
use std::io;
@@ -8,6 +9,7 @@ use std::sync::{Arc, Mutex};
pub use memory_backend::MemoryBackend;
pub use noop_backend::NoopBackend;
pub use snapshot::VfsSnapshot;
pub use std_backend::StdBackend;
mod sealed {

View File

@@ -1,16 +1,71 @@
use std::collections::{BTreeSet, HashMap};
use std::io;
use std::path::Path;
use std::path::{Path, PathBuf};
use crate::{Metadata, ReadDir, VfsBackend, VfsEvent};
use crate::{Metadata, ReadDir, VfsBackend, VfsEvent, VfsSnapshot};
/// `VfsBackend` that reads from an in-memory filesystem.
#[derive(Debug)]
#[non_exhaustive]
pub struct MemoryBackend;
pub struct MemoryBackend {
entries: HashMap<PathBuf, Entry>,
orphans: BTreeSet<PathBuf>,
}
impl MemoryBackend {
pub fn new() -> Self {
Self
Self {
entries: HashMap::new(),
orphans: BTreeSet::new(),
}
}
pub fn load_snapshot<P: Into<PathBuf>>(&mut self, path: P, snapshot: VfsSnapshot) {
let path = path.into();
if let Some(parent_path) = path.parent() {
if let Some(parent_entry) = self.entries.get_mut(parent_path) {
if let Entry::Dir { children } = parent_entry {
children.insert(path.clone());
} else {
panic!(
"Tried to load snapshot as child of file, {}",
parent_path.display()
);
}
} else {
self.orphans.insert(path.clone());
}
} else {
self.orphans.insert(path.clone());
}
match snapshot {
VfsSnapshot::File { contents } => {
self.entries.insert(path, Entry::File { contents });
}
VfsSnapshot::Dir { children } => {
self.entries.insert(
path.clone(),
Entry::Dir {
children: BTreeSet::new(),
},
);
for (child_name, child) in children {
let full_path = path.join(child_name);
self.load_snapshot(full_path, child);
}
}
};
}
}
#[derive(Debug)]
enum Entry {
File { contents: Vec<u8> },
Dir { children: BTreeSet<PathBuf> },
}
impl VfsBackend for MemoryBackend {

29
vfs/src/snapshot.rs Normal file
View File

@@ -0,0 +1,29 @@
use std::collections::BTreeMap;
#[non_exhaustive]
pub enum VfsSnapshot {
File {
contents: Vec<u8>,
},
Dir {
children: BTreeMap<String, VfsSnapshot>,
},
}
impl VfsSnapshot {
pub fn file<C: Into<Vec<u8>>>(contents: C) -> Self {
Self::File {
contents: contents.into(),
}
}
pub fn dir<K: Into<String>, I: IntoIterator<Item = (K, VfsSnapshot)>>(children: I) -> Self {
Self::Dir {
children: children
.into_iter()
.map(|(key, value)| (key.into(), value))
.collect(),
}
}
}