path_matchers/
lib.rs

1/*!
2# A collection of path matchers.
3
4## Features
5
6- Matches path with another path or glob expression.
7- Allows to combine multiple path matchers.
8
9## Usage
10
11Add dependency to Cargo.toml:
12
13```toml
14[dependencies]
15path-matchers = "1.0"
16```
17
18Use it where appropriate:
19
20```rust
21use std::path::PathBuf;
22use path_matchers::{any, glob, PathMatcher, PathMatcherExt};
23
24fn main() {
25    let path1 = PathBuf::from("images/big/best.png");
26    let path2 = PathBuf::from("images/small/32x32/best.jpg");
27
28    // check both paths matches `images/**/best.*`
29    let all_best_images = glob("images/**/best.*").unwrap();
30
31    assert!(all_best_images.matches(&path1));
32    assert!(all_best_images.matches(&path2));
33
34    let all_jpgs = glob("images/**/*.jpg").unwrap();
35    assert!(!all_jpgs.matches(&path1));
36    assert!(all_jpgs.matches(&path2));
37
38    let all_pngs = glob("images/**/*.png").unwrap();
39    assert!(all_pngs.matches(&path1));
40    assert!(!all_pngs.matches(&path2));
41
42    // now we can combine two matchers to match both jpgs and pngs
43    let all_pics = all_jpgs.or(all_pngs);
44    assert!(all_pics.matches(&path1));
45    assert!(all_pics.matches(&path2));
46
47    // you can also use macro for the same
48    let all_jpgs = glob("images/**/*.jpg").unwrap();
49    let all_pngs = glob("images/**/*.png").unwrap();
50    let all_pics = any!(all_jpgs, all_pngs);
51    assert!(all_pics.matches(&path1));
52    assert!(all_pics.matches(&path2));
53}
54```
55
56*/
57
58mod path_matcher_and;
59#[doc(hidden)]
60pub mod path_matcher_any;
61mod path_matcher_equal;
62mod path_matcher_func;
63#[cfg(feature = "glob")]
64mod path_matcher_glob;
65mod path_matcher_not;
66mod path_matcher_or;
67mod path_matcher_starts_with;
68#[cfg(test)]
69mod path_matcher_true;
70
71use std::path::Path;
72
73/// Allows to match a path against implemented condition.
74pub trait PathMatcher {
75    /// Matches path against this matcher.
76    fn matches(&self, path: &Path) -> bool;
77
78    /// Converts this matcher to boxed representation.
79    ///
80    /// Can be used for [`any_of`].
81    fn boxed<'a>(self) -> Box<dyn PathMatcher + 'a>
82    where
83        Self: Sized + 'a,
84    {
85        Box::new(self)
86    }
87}
88
89/// Extends [`PathMatcher`] with combinator functions.
90pub trait PathMatcherExt: PathMatcher + Sized {
91    fn and<R: PathMatcher>(self, right: R) -> PathMatcherAnd<Self, R> {
92        PathMatcherAnd(self, right)
93    }
94
95    fn or<R: PathMatcher>(self, right: R) -> PathMatcherOr<Self, R> {
96        PathMatcherOr(self, right)
97    }
98}
99
100impl<F> PathMatcherExt for F where F: PathMatcher + Sized {}
101
102impl<F> PathMatcher for F
103where
104    F: Fn(&Path) -> bool,
105{
106    fn matches(&self, path: &Path) -> bool {
107        self(path)
108    }
109}
110
111pub use path_matcher_and::and;
112use path_matcher_and::PathMatcherAnd;
113pub use path_matcher_any::any_of;
114pub use path_matcher_equal::equal;
115pub use path_matcher_func::func;
116#[cfg(feature = "glob")]
117pub use path_matcher_glob::{glob, PatternError};
118pub use path_matcher_not::not;
119pub use path_matcher_or::or;
120use path_matcher_or::PathMatcherOr;
121pub use path_matcher_starts_with::starts_with;