Skip to content

Commit a6dc118

Browse files
committed
feat(path): File type predicates
Part of assert-rs#8.
1 parent 4284e9f commit a6dc118

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

src/predicate/path/ft.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright (c) 2018 The predicates-rs Project Developers.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
use std::path;
10+
use std::fs;
11+
12+
use Predicate;
13+
14+
#[derive(Clone, Copy, Debug)]
15+
enum FileType {
16+
File,
17+
Dir,
18+
Symlink,
19+
}
20+
21+
impl FileType {
22+
fn eval(self, ft: &fs::FileType) -> bool {
23+
match self {
24+
FileType::File => ft.is_file(),
25+
FileType::Dir => ft.is_dir(),
26+
FileType::Symlink => ft.is_symlink(),
27+
}
28+
}
29+
}
30+
31+
/// Predicate that checks the `std::fs::FileType`.
32+
///
33+
/// This is created by the `predicate::path::is_file`, `predicate::path::is_dir`, and `predicate::path::is_symlink`.
34+
#[derive(Debug)]
35+
pub struct FileTypePredicate {
36+
ft: FileType,
37+
follow: bool,
38+
}
39+
40+
impl FileTypePredicate {
41+
/// Follow symbolic links.
42+
///
43+
/// When yes is true, symbolic links are followed as if they were normal directories and files.
44+
///
45+
/// Default: disabled.
46+
pub fn follow_links(mut self, yes: bool) -> Self {
47+
self.follow = yes;
48+
self
49+
}
50+
}
51+
52+
impl Predicate for FileTypePredicate {
53+
type Item = path::Path;
54+
55+
fn eval(&self, path: &path::Path) -> bool {
56+
let metadata = if self.follow {
57+
path.metadata()
58+
} else {
59+
path.symlink_metadata()
60+
};
61+
metadata
62+
.map(|m| self.ft.eval(&m.file_type()))
63+
.unwrap_or(false)
64+
}
65+
}
66+
67+
/// Creates a new `Predicate` that ensures the path points to a file.
68+
///
69+
/// # Examples
70+
///
71+
/// ```
72+
/// use std::path::Path;
73+
/// use predicates::predicate::*;
74+
///
75+
/// let predicate_fn = path::is_file();
76+
/// assert_eq!(true, predicate_fn.eval(Path::new("Cargo.toml")));
77+
/// assert_eq!(false, predicate_fn.eval(Path::new("src")));
78+
/// assert_eq!(false, predicate_fn.eval(Path::new("non-existent-file.foo")));
79+
/// ```
80+
pub fn is_file() -> FileTypePredicate {
81+
FileTypePredicate {
82+
ft: FileType::File,
83+
follow: false,
84+
}
85+
}
86+
87+
/// Creates a new `Predicate` that ensures the path points to a directory.
88+
///
89+
/// # Examples
90+
///
91+
/// ```
92+
/// use std::path::Path;
93+
/// use predicates::predicate::*;
94+
///
95+
/// let predicate_fn = path::is_dir();
96+
/// assert_eq!(false, predicate_fn.eval(Path::new("Cargo.toml")));
97+
/// assert_eq!(true, predicate_fn.eval(Path::new("src")));
98+
/// assert_eq!(false, predicate_fn.eval(Path::new("non-existent-file.foo")));
99+
/// ```
100+
pub fn is_dir() -> FileTypePredicate {
101+
FileTypePredicate {
102+
ft: FileType::Dir,
103+
follow: false,
104+
}
105+
}
106+
107+
/// Creates a new `Predicate` that ensures the path points to a symlink.
108+
///
109+
/// # Examples
110+
///
111+
/// ```
112+
/// use std::path::Path;
113+
/// use predicates::predicate::*;
114+
///
115+
/// let predicate_fn = path::is_symlink();
116+
/// assert_eq!(false, predicate_fn.eval(Path::new("Cargo.toml")));
117+
/// assert_eq!(false, predicate_fn.eval(Path::new("src")));
118+
/// assert_eq!(false, predicate_fn.eval(Path::new("non-existent-file.foo")));
119+
/// ```
120+
pub fn is_symlink() -> FileTypePredicate {
121+
FileTypePredicate {
122+
ft: FileType::Symlink,
123+
follow: false,
124+
}
125+
}

src/predicate/path/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@
1212
1313
mod existence;
1414
pub use self::existence::{exists, missing, ExistencePredicate};
15+
mod ft;
16+
pub use self::ft::{is_dir, is_file, is_symlink, FileTypePredicate};

0 commit comments

Comments
 (0)