diff --git a/src/path/fc.rs b/src/path/fc.rs new file mode 100644 index 0000000..8509092 --- /dev/null +++ b/src/path/fc.rs @@ -0,0 +1,85 @@ +// Copyright (c) 2018 The predicates-rs Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; +use std::fs; +use std::io::{self, Read}; +use std::path; + +use Predicate; + +/// Predicate adaper that converts a `path` to file content predicate to byte predicate. +/// +/// This is created by `pred.from_path()`. +#[derive(Clone, Debug)] +pub struct FileContentPredicate

+where + P: Predicate<[u8]>, +{ + p: P, +} + +impl

FileContentPredicate

+where + P: Predicate<[u8]>, +{ + fn eval(&self, path: &path::Path) -> io::Result { + let mut buffer = Vec::new(); + + // read the whole file + fs::File::open(path)?.read_to_end(&mut buffer)?; + Ok(self.p.eval(&buffer)) + } +} + +impl

fmt::Display for FileContentPredicate

+where + P: Predicate<[u8]>, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.p) + } +} + +impl

Predicate for FileContentPredicate

+where + P: Predicate<[u8]>, +{ + fn eval(&self, path: &path::Path) -> bool { + self.eval(path).unwrap_or(false) + } +} + +/// `Predicate` extension adapting a `slice` Predicate. +pub trait PredicateFileContentExt +where + Self: Predicate<[u8]>, + Self: Sized, +{ + /// Returns a `FileContentPredicate` that adapts `Self` to a file content `Predicate`. + /// + /// # Examples + /// + /// ``` + /// use predicates::prelude::*; + /// use std::path::Path; + /// + /// let predicate_fn = predicate::str::is_empty().not().from_utf8().from_file_path(); + /// assert_eq!(true, predicate_fn.eval(Path::new("./tests/hello_world"))); + /// assert_eq!(false, predicate_fn.eval(Path::new("./tests/empty_file"))); + /// ``` + fn from_file_path(self) -> FileContentPredicate { + FileContentPredicate { p: self } + } +} + +impl

PredicateFileContentExt for P +where + P: Predicate<[u8]>, +{ +} diff --git a/src/path/mod.rs b/src/path/mod.rs index bcc9a89..9954c54 100644 --- a/src/path/mod.rs +++ b/src/path/mod.rs @@ -14,3 +14,5 @@ mod existence; pub use self::existence::{exists, missing, ExistencePredicate}; mod ft; pub use self::ft::{is_dir, is_file, is_symlink, FileTypePredicate}; +mod fc; +pub use self::fc::{FileContentPredicate, PredicateFileContentExt}; diff --git a/src/prelude.rs b/src/prelude.rs index 1052804..02fd93d 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -11,6 +11,7 @@ pub use core::Predicate; pub use boolean::PredicateBooleanExt; pub use boxed::PredicateBoxExt; +pub use path::PredicateFileContentExt; pub use str::PredicateStrExt; pub use name::PredicateNameExt; diff --git a/tests/empty_file b/tests/empty_file new file mode 100644 index 0000000..e69de29 diff --git a/tests/hello_world b/tests/hello_world new file mode 100644 index 0000000..c57eff5 --- /dev/null +++ b/tests/hello_world @@ -0,0 +1 @@ +Hello World! \ No newline at end of file