#![deny(missing_docs)]
#[macro_use]
extern crate log;
#[macro_use]
extern crate bitflags;
#[cfg(target_os="linux")]
extern crate mio;
#[cfg(target_os="macos")]
extern crate fsevent_sys;
#[cfg(target_os="windows")]
extern crate winapi;
extern crate libc;
extern crate filetime;
pub use self::op::Op;
use std::io;
use std::path::{Path, PathBuf};
use std::sync::mpsc::Sender;
use std::convert::AsRef;
use std::fmt;
use std::error::Error as StdError;
use std::result::Result as StdResult;
#[cfg(target_os="macos")]
pub use self::fsevent::FsEventWatcher;
#[cfg(target_os="linux")]
pub use self::inotify::INotifyWatcher;
#[cfg(target_os="windows")]
pub use self::windows::ReadDirectoryChangesWatcher;
pub use self::null::NullWatcher;
pub use self::poll::PollWatcher;
#[cfg(target_os="linux")]
pub mod inotify;
#[cfg(target_os="macos")]
pub mod fsevent;
#[cfg(target_os="windows")]
pub mod windows;
pub mod null;
pub mod poll;
pub mod op {
bitflags! {
flags Op: u32 {
const CHMOD = 0b000001,
const CREATE = 0b000010,
const REMOVE = 0b000100,
const RENAME = 0b001000,
const WRITE = 0b010000,
const IGNORED = 0b100000,
}
}
}
#[derive(Debug)]
pub struct Event {
pub path: Option<PathBuf>,
pub op: Result<Op>,
}
unsafe impl Send for Event {}
#[derive(Debug)]
pub enum Error {
Generic(String),
Io(io::Error),
NotImplemented,
PathNotFound,
WatchNotFound,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let error = String::from(match *self {
Error::PathNotFound => "No path was found.",
Error::WatchNotFound => "No watch was found.",
Error::NotImplemented => "Not implemented.",
Error::Generic(ref err) => err.as_ref(),
Error::Io(ref err) => err.description(),
});
write!(f, "{}", error)
}
}
pub type Result<T> = StdResult<T, Error>;
impl StdError for Error {
fn description(&self) -> &str {
match *self {
Error::PathNotFound => "No path was found",
Error::WatchNotFound => "No watch was found",
Error::NotImplemented => "Not implemented",
Error::Generic(_) => "Generic error",
Error::Io(_) => "I/O Error",
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
Error::Io(ref cause) => Some(cause),
_ => None
}
}
}
pub trait Watcher: Sized {
fn new(Sender<Event>) -> Result<Self>;
fn watch<P: AsRef<Path>>(&mut self, P) -> Result<()>;
fn unwatch<P: AsRef<Path>>(&mut self, P) -> Result<()>;
}
#[cfg(target_os = "linux")]
pub type RecommendedWatcher = INotifyWatcher;
#[cfg(target_os = "macos")]
pub type RecommendedWatcher = FsEventWatcher;
#[cfg(target_os = "windows")]
pub type RecommendedWatcher = ReadDirectoryChangesWatcher;
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
pub type RecommendedWatcher = PollWatcher;
pub fn new(tx: Sender<Event>) -> Result<RecommendedWatcher> {
Watcher::new(tx)
}
#[test]
fn display_formatted_errors() {
let expected = "Some error";
assert_eq!(expected,
format!("{}", Error::Generic(String::from(expected))));
assert_eq!(expected,
format!("{}",
Error::Io(io::Error::new(io::ErrorKind::Other, expected))));
}