diff options
Diffstat (limited to 'src/checker.rs')
-rw-r--r-- | src/checker.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/checker.rs b/src/checker.rs new file mode 100644 index 0000000..6021711 --- /dev/null +++ b/src/checker.rs @@ -0,0 +1,70 @@ +use finder::Checker; +#[cfg(unix)] +use libc; +#[cfg(unix)] +use std::ffi::CString; +use std::fs; +#[cfg(unix)] +use std::os::unix::ffi::OsStrExt; +use std::path::Path; + +pub struct ExecutableChecker; + +impl ExecutableChecker { + pub fn new() -> ExecutableChecker { + ExecutableChecker + } +} + +impl Checker for ExecutableChecker { + #[cfg(unix)] + fn is_valid(&self, path: &Path) -> bool { + CString::new(path.as_os_str().as_bytes()) + .and_then(|c| Ok(unsafe { libc::access(c.as_ptr(), libc::X_OK) == 0 })) + .unwrap_or(false) + } + + #[cfg(windows)] + fn is_valid(&self, _path: &Path) -> bool { + true + } +} + +pub struct ExistedChecker; + +impl ExistedChecker { + pub fn new() -> ExistedChecker { + ExistedChecker + } +} + +impl Checker for ExistedChecker { + fn is_valid(&self, path: &Path) -> bool { + fs::metadata(path) + .map(|metadata| metadata.is_file()) + .unwrap_or(false) + } +} + +pub struct CompositeChecker { + checkers: Vec<Box<dyn Checker>>, +} + +impl CompositeChecker { + pub fn new() -> CompositeChecker { + CompositeChecker { + checkers: Vec::new(), + } + } + + pub fn add_checker(mut self, checker: Box<dyn Checker>) -> CompositeChecker { + self.checkers.push(checker); + self + } +} + +impl Checker for CompositeChecker { + fn is_valid(&self, path: &Path) -> bool { + self.checkers.iter().all(|checker| checker.is_valid(path)) + } +} |