VFS crate

This commit is contained in:
Lucien Greathouse
2020-02-18 22:30:12 -08:00
parent 8f21514855
commit 838e8f6bde
6 changed files with 214 additions and 7 deletions

20
Cargo.lock generated
View File

@@ -762,7 +762,7 @@ dependencies = [
[[package]]
name = "inotify"
version = "0.6.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1037,15 +1037,14 @@ dependencies = [
[[package]]
name = "notify"
version = "4.0.14"
version = "4.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"inotify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1672,7 +1671,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rbx_binary 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2359,6 +2358,13 @@ name = "version_check"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vfs"
version = "0.1.0"
dependencies = [
"notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "walkdir"
version = "2.2.9"
@@ -2546,7 +2552,7 @@ dependencies = [
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718"
"checksum inotify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24e40d6fd5d64e2082e0c796495c8ef5ad667a96d03e5aaa0becfd9d47bcbfb8"
"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
"checksum insta 0.12.0 (git+https://github.com/mitsuhiko/insta)" = "<none>"
"checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349"
@@ -2578,7 +2584,7 @@ dependencies = [
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b"
"checksum notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"

View File

@@ -32,12 +32,14 @@ members = [
"rojo-test",
"rojo-insta-ext",
"clibrojo",
"vfs",
]
default-members = [
".",
"rojo-test",
"rojo-insta-ext",
"vfs",
]
[lib]

10
vfs/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "vfs"
version = "0.1.0"
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
notify = "4.0.15"

116
vfs/src/lib.rs Normal file
View File

@@ -0,0 +1,116 @@
mod noop_backend;
mod std_backend;
use std::io;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
pub use noop_backend::NoopBackend;
pub use std_backend::StdBackend;
pub trait VfsBackend {
fn read(&self, path: &Path) -> io::Result<Vec<u8>>;
fn write(&self, path: &Path, data: &[u8]) -> io::Result<()>;
fn read_dir(&self, path: &Path) -> io::Result<ReadDir>;
fn metadata(&self, path: &Path) -> io::Result<Metadata>;
}
pub struct DirEntry {
path: PathBuf,
}
impl DirEntry {
pub fn path(&self) -> &Path {
&self.path
}
}
pub struct ReadDir {
inner: Box<dyn Iterator<Item = io::Result<DirEntry>>>,
}
impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
pub struct Metadata {
is_file: bool,
}
impl Metadata {
pub fn is_file(&self) -> bool {
self.is_file
}
pub fn is_dir(&self) -> bool {
!self.is_file
}
}
struct VfsLock {
data: (),
backend: Box<dyn VfsBackend>,
}
impl VfsLock {
pub fn read<P: AsRef<Path>>(&mut self, path: P) -> io::Result<Arc<Vec<u8>>> {
let path = path.as_ref();
let contents = self.backend.read(path)?;
Ok(Arc::new(contents))
}
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(
&mut self,
path: P,
contents: C,
) -> io::Result<()> {
let path = path.as_ref();
let contents = contents.as_ref();
self.backend.write(path, contents)
}
pub fn read_dir<P: AsRef<Path>>(&mut self, path: P) -> io::Result<ReadDir> {
let path = path.as_ref();
self.backend.read_dir(path)
}
}
pub struct Vfs {
inner: Mutex<VfsLock>,
}
impl Vfs {
pub fn new<B: VfsBackend + 'static>(backend: B) -> Self {
let lock = VfsLock {
data: (),
backend: Box::new(backend),
};
Self {
inner: Mutex::new(lock),
}
}
pub fn read<P: AsRef<Path>>(&self, path: P) -> io::Result<Arc<Vec<u8>>> {
let path = path.as_ref();
let mut inner = self.inner.lock().unwrap();
inner.read(path)
}
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(&self, path: P, contents: C) -> io::Result<()> {
let path = path.as_ref();
let contents = contents.as_ref();
let mut inner = self.inner.lock().unwrap();
inner.write(path, contents)
}
pub fn read_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<ReadDir> {
let path = path.as_ref();
let mut inner = self.inner.lock().unwrap();
inner.read_dir(path)
}
}

36
vfs/src/noop_backend.rs Normal file
View File

@@ -0,0 +1,36 @@
use std::io;
use std::path::Path;
use crate::{Metadata, ReadDir, VfsBackend};
pub struct NoopBackend;
impl VfsBackend for NoopBackend {
fn read(&self, path: &Path) -> io::Result<Vec<u8>> {
Err(io::Error::new(
io::ErrorKind::Other,
"NoopBackend doesn't do anything",
))
}
fn write(&self, path: &Path, data: &[u8]) -> io::Result<()> {
Err(io::Error::new(
io::ErrorKind::Other,
"NoopBackend doesn't do anything",
))
}
fn read_dir(&self, path: &Path) -> io::Result<ReadDir> {
Err(io::Error::new(
io::ErrorKind::Other,
"NoopBackend doesn't do anything",
))
}
fn metadata(&self, path: &Path) -> io::Result<Metadata> {
Err(io::Error::new(
io::ErrorKind::Other,
"NoopBackend doesn't do anything",
))
}
}

37
vfs/src/std_backend.rs Normal file
View File

@@ -0,0 +1,37 @@
use std::fs;
use std::io;
use std::path::Path;
use crate::{DirEntry, Metadata, ReadDir, VfsBackend};
pub struct StdBackend;
impl VfsBackend for StdBackend {
fn read(&self, path: &Path) -> io::Result<Vec<u8>> {
fs::read(path)
}
fn write(&self, path: &Path, data: &[u8]) -> io::Result<()> {
fs::write(path, data)
}
fn read_dir(&self, path: &Path) -> io::Result<ReadDir> {
let inner = fs::read_dir(path)?.map(|entry| {
Ok(DirEntry {
path: entry?.path(),
})
});
Ok(ReadDir {
inner: Box::new(inner),
})
}
fn metadata(&self, path: &Path) -> io::Result<Metadata> {
let inner = fs::metadata(path)?;
Ok(Metadata {
is_file: inner.is_file(),
})
}
}