//! Object safe interface for file watching and reading. use std::fmt; use paths::{AbsPath, AbsPathBuf}; #[derive(Debug)] pub enum Entry { Files(Vec), Directory { path: AbsPathBuf, include: Vec }, } #[derive(Debug)] pub struct Config { pub load: Vec, pub watch: Vec, } pub enum Message { Progress { n_entries_total: usize, n_entries_done: usize }, Loaded { files: Vec<(AbsPathBuf, Option>)> }, } pub type Sender = Box; pub trait Handle: fmt::Debug { fn spawn(sender: Sender) -> Self where Self: Sized; fn set_config(&mut self, config: Config); fn invalidate(&mut self, path: AbsPathBuf); fn load_sync(&mut self, path: &AbsPath) -> Option>; } impl Entry { pub fn rs_files_recursively(base: AbsPathBuf) -> Entry { Entry::Directory { path: base, include: globs(&["*.rs", "!/.git/"]) } } pub fn local_cargo_package(base: AbsPathBuf) -> Entry { Entry::Directory { path: base, include: globs(&["*.rs", "!/target/", "!/.git/"]) } } pub fn cargo_package_dependency(base: AbsPathBuf) -> Entry { Entry::Directory { path: base, include: globs(&["*.rs", "!/tests/", "!/examples/", "!/benches/", "!/.git/"]), } } } fn globs(globs: &[&str]) -> Vec { globs.iter().map(|it| it.to_string()).collect() } impl fmt::Debug for Message { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Message::Loaded { files } => { f.debug_struct("Loaded").field("n_files", &files.len()).finish() } Message::Progress { n_entries_total, n_entries_done } => f .debug_struct("Progress") .field("n_entries_total", n_entries_total) .field("n_entries_done", n_entries_done) .finish(), } } } #[test] fn handle_is_object_safe() { fn _assert(_: &dyn Handle) {} }