1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #![allow(non_snake_case)] use super::WatcherTrait; use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher}; use std::fs; use std::path::Path; use std::path::PathBuf; use std::sync::mpsc; use std::sync::Arc; use std::sync::Mutex; use std::thread; use std::time::Duration;
pub struct FileWatcher { path: PathBuf, pub content: Arc<Mutex<String>>, pub version: Arc<Mutex<usize>>, }
impl FileWatcher { pub fn New(path: &Path) -> Self { if path.exists() { let file_content = fs::read_to_string(path).unwrap(); let content = Arc::new(Mutex::new(file_content)); let version = Arc::new(Mutex::new(1)); Self { path: PathBuf::from(path), content, version, } } else { error!("watch an nonexist file!"); panic!("watch an nonexist file!"); } } }
impl WatcherTrait for FileWatcher { fn watch(&mut self) { let path = fs::canonicalize(&self.path).unwrap(); let content_guard = self.content.clone(); let version_guard = self.version.clone(); thread::spawn(move || { let (tx1, rx1) = mpsc::channel(); let mut watcher: RecommendedWatcher = Watcher::new(tx1, Duration::from_secs(1)).unwrap(); watcher .watch(path.parent().unwrap(), RecursiveMode::NonRecursive) .unwrap();
loop { match rx1.recv() { Ok(event) => { info!("watch event: {:?}", event); match event { DebouncedEvent::Remove(p) | DebouncedEvent::Write(p) | DebouncedEvent::Create(p) => { if path == p { let mut content = content_guard.lock().unwrap(); let mut version = version_guard.lock().unwrap(); (*version) += 1; match fs::read_to_string(&p) { Ok(c) => { *content = c; info!("wrote file: {:?} #{}", p, *version); } Err(_) => warn!("file not exist: {:?}", &p), } } } _ => {} } } Err(e) => { error!("watch error: {:?}", e); } } } }); }
fn content(&self) -> String { let content_guard = self.content.clone(); let content = content_guard.lock().unwrap(); (*content).clone() }
fn version(&self) -> usize { let version_guard = self.version.clone(); let version = version_guard.lock().unwrap(); *version } }
|