mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-23 22:25:26 +00:00
Watching
This commit is contained in:
@@ -8,11 +8,23 @@ use std::sync::{Arc, Mutex};
|
|||||||
pub use noop_backend::NoopBackend;
|
pub use noop_backend::NoopBackend;
|
||||||
pub use std_backend::StdBackend;
|
pub use std_backend::StdBackend;
|
||||||
|
|
||||||
pub trait VfsBackend {
|
mod sealed {
|
||||||
fn read(&self, path: &Path) -> io::Result<Vec<u8>>;
|
use super::*;
|
||||||
fn write(&self, path: &Path, data: &[u8]) -> io::Result<()>;
|
|
||||||
fn read_dir(&self, path: &Path) -> io::Result<ReadDir>;
|
pub trait Sealed {}
|
||||||
fn metadata(&self, path: &Path) -> io::Result<Metadata>;
|
|
||||||
|
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 {
|
pub struct DirEntry {
|
||||||
@@ -52,7 +64,6 @@ impl Metadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct VfsLock {
|
struct VfsLock {
|
||||||
data: (),
|
|
||||||
backend: Box<dyn VfsBackend>,
|
backend: Box<dyn VfsBackend>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +97,6 @@ pub struct Vfs {
|
|||||||
impl Vfs {
|
impl Vfs {
|
||||||
pub fn new<B: VfsBackend + 'static>(backend: B) -> Self {
|
pub fn new<B: VfsBackend + 'static>(backend: B) -> Self {
|
||||||
let lock = VfsLock {
|
let lock = VfsLock {
|
||||||
data: (),
|
|
||||||
backend: Box::new(backend),
|
backend: Box::new(backend),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,31 +3,52 @@ use std::path::Path;
|
|||||||
|
|
||||||
use crate::{Metadata, ReadDir, VfsBackend};
|
use crate::{Metadata, ReadDir, VfsBackend};
|
||||||
|
|
||||||
|
#[non_exhaustive]
|
||||||
pub struct NoopBackend;
|
pub struct NoopBackend;
|
||||||
|
|
||||||
|
impl NoopBackend {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl VfsBackend for NoopBackend {
|
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(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"NoopBackend doesn't do anything",
|
"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(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"NoopBackend doesn't do anything",
|
"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(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"NoopBackend doesn't do anything",
|
"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(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"NoopBackend doesn't do anything",
|
"NoopBackend doesn't do anything",
|
||||||
|
|||||||
@@ -1,21 +1,40 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
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};
|
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 {
|
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)
|
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)
|
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| {
|
let inner = fs::read_dir(path)?.map(|entry| {
|
||||||
Ok(DirEntry {
|
Ok(DirEntry {
|
||||||
path: entry?.path(),
|
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)?;
|
let inner = fs::metadata(path)?;
|
||||||
|
|
||||||
Ok(Metadata {
|
Ok(Metadata {
|
||||||
is_file: inner.is_file(),
|
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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user