Skip to content

Commit 40b3926

Browse files
author
Scrim
committed
feat: add flag to exclude directories from results and filtering
1 parent 2403afb commit 40b3926

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

src/builder.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub struct SearchBuilder {
2525
hidden: bool,
2626
/// Filters Vector, defaults to empty vec
2727
filters: Vec<FilterType>,
28+
/// When set to false, will not apply filters to directories and will exclude them from results.
29+
dirs: bool,
2830
}
2931

3032
impl SearchBuilder {
@@ -42,6 +44,7 @@ impl SearchBuilder {
4244
self.ignore_case,
4345
self.hidden,
4446
self.filters.clone(),
47+
self.dirs,
4548
)
4649
}
4750

@@ -233,6 +236,23 @@ impl SearchBuilder {
233236
);
234237
self
235238
}
239+
240+
/// Choose whether to apply filters to directories and include matches in search results. Defaults to true.
241+
/// ### Arguments
242+
/// * `value`
243+
/// ### Examples
244+
/// ```rust
245+
/// use rust_search::SearchBuilder;
246+
///
247+
/// let search: Vec<String> = SearchBuilder::default()
248+
/// .dirs(false)
249+
/// .build()
250+
/// .collect();
251+
/// ```
252+
pub fn dirs(mut self, value: bool) -> Self {
253+
self.dirs = value;
254+
self
255+
}
236256
}
237257

238258
impl Default for SearchBuilder {
@@ -249,6 +269,7 @@ impl Default for SearchBuilder {
249269
ignore_case: false,
250270
hidden: false,
251271
filters: vec![],
272+
dirs: true,
252273
}
253274
}
254275
}

src/filter.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ pub enum FilterType {
1414
}
1515

1616
impl FilterType {
17-
pub fn apply(&self, dir: &DirEntry) -> bool {
17+
pub fn apply(&self, dir: &DirEntry, filter_dirs: bool) -> bool {
1818
if let Ok(m) = dir.metadata() {
19+
if !filter_dirs && m.file_type().is_dir() {
20+
return true;
21+
}
1922
match self {
2023
Self::Created(cmp, time) => {
2124
if let Ok(created) = m.created() {

src/search.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ impl Search {
5959
/// * `ignore_case` - Whether to ignore case or not
6060
/// * `hidden` - Whether to search hidden files or not
6161
/// * `filters` - Vector of filters to search by `DirEntry` data
62+
/// * `dirs` - Whether to apply filters to directories and include them in results.
6263
#[allow(clippy::too_many_arguments)]
6364
pub(crate) fn new(
6465
search_location: impl AsRef<Path>,
@@ -71,6 +72,7 @@ impl Search {
7172
ignore_case: bool,
7273
with_hidden: bool,
7374
filters: Vec<FilterType>,
75+
dirs: bool,
7476
) -> Self {
7577
let regex_search_input =
7678
utils::build_regex_search_input(search_input, file_ext, strict, ignore_case);
@@ -85,7 +87,7 @@ impl Search {
8587

8688
// filters getting applied to walker
8789
// only if all filters are true then the walker will return the file
88-
walker.filter_entry(move |dir| filters.iter().all(|f| f.apply(dir)));
90+
walker.filter_entry(move |entry| filters.iter().all(|f| f.apply(entry, dirs)));
8991

9092
if let Some(locations) = more_locations {
9193
for location in locations {
@@ -101,6 +103,16 @@ impl Search {
101103

102104
Box::new(move |path_entry| {
103105
if let Ok(entry) = path_entry {
106+
if !dirs {
107+
// if dirs is false and entry is a directory,
108+
// proceed with the search without sending its path or incrementing the counter
109+
if let Ok(m) = entry.metadata() {
110+
if m.file_type().is_dir() {
111+
return WalkState::Continue;
112+
}
113+
}
114+
}
115+
104116
let path = entry.path();
105117
if let Some(file_name) = path.file_name() {
106118
// Lossy means that if the file name is not valid UTF-8

0 commit comments

Comments
 (0)