1 use std::io::{Error, ErrorKind, Result}; 2 use std::path::PathBuf; 3 use std::vec::Vec; 4 5 extern crate inotify; 6 use inotify::Inotify; 7 8 pub struct FileWatcherImpl { 9 inotify: Inotify, 10 watches: Vec<FileWatchImpl> 11 } 12 13 pub struct FileWatchImpl { 14 descriptor: inotify::WatchDescriptor, 15 } 16 17 impl FileWatcherImpl { init() -> Result<FileWatcherImpl>18 pub fn init() -> Result<FileWatcherImpl> { 19 let ino = match Inotify::init() { 20 Ok(i) => i, 21 Err(msg) => return Result::Err(msg), 22 }; 23 24 return Result::Ok(FileWatcherImpl { 25 inotify: ino, 26 watches: vec![] 27 }); 28 } 29 add_watch(&mut self, file_path: &PathBuf) -> Result<&FileWatchImpl>30 pub fn add_watch(&mut self, file_path: &PathBuf) -> Result<&FileWatchImpl> { 31 let mask: inotify::WatchMask = inotify::WatchMask::MODIFY; 32 33 let watch = match self.inotify.add_watch(file_path, mask) { 34 Ok(w) => w, 35 Err(msg) => return Result::Err(msg), 36 }; 37 38 let fw = FileWatchImpl { 39 descriptor: watch, 40 }; 41 42 self.watches.push(fw); 43 return Result::Ok(&self.watches.last().unwrap()); 44 } 45 rm_watch(&mut self, fw: &FileWatchImpl) -> Result<()>46 pub fn rm_watch(&mut self, fw: &FileWatchImpl) -> Result<()> { 47 for i in 0..self.watches.len() { 48 let item_ref = self.watches.get(i).unwrap(); 49 if item_ref.descriptor == fw.descriptor { 50 let item = self.watches.remove(i); 51 return self.inotify.rm_watch(item.descriptor); 52 } 53 } 54 55 return Result::Err(Error::new( 56 ErrorKind::InvalidInput, 57 "Passed FileWatch does not belong to this FileWatcher instance" 58 )); 59 } 60 start(&mut self) -> Result<()>61 pub fn start(&mut self) -> Result<()> { 62 return Result::Ok(()); 63 } 64 any_events(&mut self) -> Result<bool>65 pub fn any_events(&mut self) -> Result<bool> { 66 let mut buffer = [0; 1024]; 67 let events = match self.inotify.read_events(&mut buffer) { 68 Result::Ok(ev) => ev, 69 Result::Err(err) => return Result::Err(Error::from(err)), 70 }; 71 72 return Result::Ok(events.count() > 0); 73 } 74 } 75