This commit is contained in:
Lucien Greathouse
2020-02-18 22:42:31 -08:00
parent 838e8f6bde
commit b4963f4ff7
3 changed files with 78 additions and 16 deletions

View File

@@ -8,11 +8,23 @@ 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>;
mod sealed {
use super::*;
pub trait Sealed {}
impl Sealed for NoopBackend {}
impl Sealed for StdBackend {}
}
pub trait VfsBackend: sealed::Sealed {
fn read(&mut self, path: &Path) -> io::Result<Vec<u8>>;
fn write(&mut self, path: &Path, data: &[u8]) -> io::Result<()>;
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir>;
fn metadata(&mut self, path: &Path) -> io::Result<Metadata>;
fn watch(&mut self, path: &Path) -> io::Result<()>;
fn unwatch(&mut self, path: &Path) -> io::Result<()>;
}
pub struct DirEntry {
@@ -52,7 +64,6 @@ impl Metadata {
}
struct VfsLock {
data: (),
backend: Box<dyn VfsBackend>,
}
@@ -86,7 +97,6 @@ pub struct Vfs {
impl Vfs {
pub fn new<B: VfsBackend + 'static>(backend: B) -> Self {
let lock = VfsLock {
data: (),
backend: Box::new(backend),
};

View File

@@ -3,31 +3,52 @@ use std::path::Path;
use crate::{Metadata, ReadDir, VfsBackend};
#[non_exhaustive]
pub struct NoopBackend;
impl NoopBackend {
pub fn new() -> Self {
Self
}
}
impl VfsBackend for NoopBackend {
fn read(&self, path: &Path) -> io::Result<Vec<u8>> {
fn read(&mut 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<()> {
fn write(&mut 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> {
fn read_dir(&mut 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> {
fn metadata(&mut self, _path: &Path) -> io::Result<Metadata> {
Err(io::Error::new(
io::ErrorKind::Other,
"NoopBackend doesn't do anything",
))
}
fn watch(&mut self, _path: &Path) -> io::Result<()> {
Err(io::Error::new(
io::ErrorKind::Other,
"NoopBackend doesn't do anything",
))
}
fn unwatch(&mut self, _path: &Path) -> io::Result<()> {
Err(io::Error::new(
io::ErrorKind::Other,
"NoopBackend doesn't do anything",

View File

@@ -1,21 +1,40 @@
use std::fs;
use std::io;
use std::path::Path;
use std::sync::mpsc;
use std::time::Duration;
use notify::{watcher, DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
use crate::{DirEntry, Metadata, ReadDir, VfsBackend};
pub struct StdBackend;
pub struct StdBackend {
watcher: RecommendedWatcher,
watcher_receiver: mpsc::Receiver<DebouncedEvent>,
}
impl StdBackend {
pub fn new() -> StdBackend {
let (tx, rx) = mpsc::channel();
let watcher = watcher(tx, Duration::from_millis(50)).unwrap();
Self {
watcher,
watcher_receiver: rx,
}
}
}
impl VfsBackend for StdBackend {
fn read(&self, path: &Path) -> io::Result<Vec<u8>> {
fn read(&mut self, path: &Path) -> io::Result<Vec<u8>> {
fs::read(path)
}
fn write(&self, path: &Path, data: &[u8]) -> io::Result<()> {
fn write(&mut self, path: &Path, data: &[u8]) -> io::Result<()> {
fs::write(path, data)
}
fn read_dir(&self, path: &Path) -> io::Result<ReadDir> {
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir> {
let inner = fs::read_dir(path)?.map(|entry| {
Ok(DirEntry {
path: entry?.path(),
@@ -27,11 +46,23 @@ impl VfsBackend for StdBackend {
})
}
fn metadata(&self, path: &Path) -> io::Result<Metadata> {
fn metadata(&mut self, path: &Path) -> io::Result<Metadata> {
let inner = fs::metadata(path)?;
Ok(Metadata {
is_file: inner.is_file(),
})
}
fn watch(&mut self, path: &Path) -> io::Result<()> {
self.watcher
.watch(path, RecursiveMode::NonRecursive)
.map_err(|inner| io::Error::new(io::ErrorKind::Other, inner))
}
fn unwatch(&mut self, path: &Path) -> io::Result<()> {
self.watcher
.unwatch(path)
.map_err(|inner| io::Error::new(io::ErrorKind::Other, inner))
}
}