Skip to content

Instantly share code, notes, and snippets.

@passcod
Created March 10, 2017 12:14
Show Gist options
  • Save passcod/318a90e3e5ebf795007911da2b63e096 to your computer and use it in GitHub Desktop.
Save passcod/318a90e3e5ebf795007911da2b63e096 to your computer and use it in GitHub Desktop.
extern crate backend;
extern crate futures;
extern crate inotify;
use backend::prelude::*;
use backend::Buffer;
use futures::{Poll, Stream};
use inotify::INotify;
use std::path::PathBuf;
pub struct Backend {
inotify: INotify,
buffer: Buffer
}
impl NotifyBackend for Backend {
fn capabilities() -> Vec<Capability> {
vec![
Capability::WatchFiles,
Capability::WatchFolders,
]
}
fn new(paths: Vec<PathBuf>) -> BackendResult<Backend> {
let ino = INotify::init()
.or_else(|err| Err(BackendError::Io(err)))?;
for path in paths {
// Watch all events
ino.add_watch(&path, 0b111111111111)
.or_else(|err| Err(BackendError::Io(err)))?;
}
Ok(Backend { buffer: Buffer::new(), inotify: ino })
}
}
impl Drop for Backend {
fn drop(&mut self) {}
}
impl Stream for Backend {
type Item = StreamItem;
type Error = StreamError;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
let from_kernel = self.inotify.available_events()
.or_else(|err| Err(StreamError::Io(err)))?;
// is_ignored() and is_queue_overflow() should throw errors.
for e in from_kernel {
self.buffer.push(Event {
kind: if e.is_access() {
EventKind::Access(AccessKind::Any)
} else if e.is_attrib() {
EventKind::Modify(ModifyKind::Metadata(MetadataKind::Any))
} else if e.is_close_write() {
EventKind::Access(AccessKind::Close(AccessMode::Write))
} else if e.is_close_nowrite() {
EventKind::Access(AccessKind::Close(AccessMode::Read))
} else if e.is_create() {
EventKind::Create(if e.is_dir() {
CreateKind::Folder
} else {
CreateKind::File
})
} else if e.is_delete() {
EventKind::Remove(if e.is_dir() {
RemoveKind::Folder
} else {
RemoveKind::File
})
} else if e.is_delete_self() {
EventKind::Remove(if e.is_dir() {
RemoveKind::Folder
} else {
RemoveKind::File
})
} else if e.is_modify() {
EventKind::Modify(ModifyKind::Data(DataChange::Any))
} else if e.is_move_self() {
EventKind::Modify(ModifyKind::Name(RenameMode::Any))
} else if e.is_moved_from() {
EventKind::Modify(ModifyKind::Name(RenameMode::From))
} else if e.is_moved_to() {
EventKind::Modify(ModifyKind::Name(RenameMode::To))
} else if e.is_open() {
EventKind::Access(AccessKind::Open(AccessMode::Any))
} else if e.is_unmount() {
EventKind::Other("unmount".into())
} else {
EventKind::Any
},
paths: vec![e.name.clone()],
cookie: match e.cookie {
0 => None,
c @ _ => Some(c)
}
})
}
self.buffer.poll()
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment