Skip to content

Commit

Permalink
Implement a file content predicate
Browse files Browse the repository at this point in the history
Fixes #31
  • Loading branch information
farodin91 committed May 29, 2018
1 parent efd199b commit 363c2cd
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 0 deletions.
85 changes: 85 additions & 0 deletions src/path/fc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) 2018 The predicates-rs Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<P>
where
P: Predicate<[u8]>,
{
p: P,
}

impl<P> FileContentPredicate<P>
where
P: Predicate<[u8]>,
{
fn eval(&self, path: &path::Path) -> io::Result<bool> {
let mut buffer = Vec::new();

// read the whole file
fs::File::open(path)?.read_to_end(&mut buffer)?;
Ok(self.p.eval(&buffer))
}
}

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

impl<P> Predicate<path::Path> for FileContentPredicate<P>
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<Self> {
FileContentPredicate { p: self }
}
}

impl<P> PredicateFileContentExt for P
where
P: Predicate<[u8]>,
{
}
2 changes: 2 additions & 0 deletions src/path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
1 change: 1 addition & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Empty file added tests/empty_file
Empty file.
1 change: 1 addition & 0 deletions tests/hello_world
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello World!

0 comments on commit 363c2cd

Please sign in to comment.