diff --git a/Cargo.lock b/Cargo.lock index c59f3e99..d77b059b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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)" = "" "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" diff --git a/Cargo.toml b/Cargo.toml index c01c5acc..c6b89947 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,12 +32,14 @@ members = [ "rojo-test", "rojo-insta-ext", "clibrojo", + "vfs", ] default-members = [ ".", "rojo-test", "rojo-insta-ext", + "vfs", ] [lib] diff --git a/vfs/Cargo.toml b/vfs/Cargo.toml new file mode 100644 index 00000000..b6eabf28 --- /dev/null +++ b/vfs/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "vfs" +version = "0.1.0" +authors = ["Lucien Greathouse "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +notify = "4.0.15" diff --git a/vfs/src/lib.rs b/vfs/src/lib.rs new file mode 100644 index 00000000..7246111f --- /dev/null +++ b/vfs/src/lib.rs @@ -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>; + fn write(&self, path: &Path, data: &[u8]) -> io::Result<()>; + fn read_dir(&self, path: &Path) -> io::Result; + fn metadata(&self, path: &Path) -> io::Result; +} + +pub struct DirEntry { + path: PathBuf, +} + +impl DirEntry { + pub fn path(&self) -> &Path { + &self.path + } +} + +pub struct ReadDir { + inner: Box>>, +} + +impl Iterator for ReadDir { + type Item = io::Result; + + fn next(&mut self) -> Option { + 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, +} + +impl VfsLock { + pub fn read>(&mut self, path: P) -> io::Result>> { + let path = path.as_ref(); + let contents = self.backend.read(path)?; + Ok(Arc::new(contents)) + } + + pub fn write, 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>(&mut self, path: P) -> io::Result { + let path = path.as_ref(); + self.backend.read_dir(path) + } +} + +pub struct Vfs { + inner: Mutex, +} + +impl Vfs { + pub fn new(backend: B) -> Self { + let lock = VfsLock { + data: (), + backend: Box::new(backend), + }; + + Self { + inner: Mutex::new(lock), + } + } + + pub fn read>(&self, path: P) -> io::Result>> { + let path = path.as_ref(); + let mut inner = self.inner.lock().unwrap(); + inner.read(path) + } + + pub fn write, 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>(&self, path: P) -> io::Result { + let path = path.as_ref(); + let mut inner = self.inner.lock().unwrap(); + inner.read_dir(path) + } +} diff --git a/vfs/src/noop_backend.rs b/vfs/src/noop_backend.rs new file mode 100644 index 00000000..95e66205 --- /dev/null +++ b/vfs/src/noop_backend.rs @@ -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> { + 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 { + Err(io::Error::new( + io::ErrorKind::Other, + "NoopBackend doesn't do anything", + )) + } + + fn metadata(&self, path: &Path) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "NoopBackend doesn't do anything", + )) + } +} diff --git a/vfs/src/std_backend.rs b/vfs/src/std_backend.rs new file mode 100644 index 00000000..1e2d4f6d --- /dev/null +++ b/vfs/src/std_backend.rs @@ -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> { + fs::read(path) + } + + fn write(&self, path: &Path, data: &[u8]) -> io::Result<()> { + fs::write(path, data) + } + + fn read_dir(&self, path: &Path) -> io::Result { + 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 { + let inner = fs::metadata(path)?; + + Ok(Metadata { + is_file: inner.is_file(), + }) + } +}