Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub struct SearchBuilder {
hidden: bool,
/// Filters Vector, defaults to empty vec
filters: Vec<FilterType>,
/// When set to false, will not apply filters to directories and will exclude them from results.
dirs: bool,
}

impl SearchBuilder {
Expand All @@ -42,6 +44,7 @@ impl SearchBuilder {
self.ignore_case,
self.hidden,
self.filters.clone(),
self.dirs,
)
}

Expand Down Expand Up @@ -233,6 +236,23 @@ impl SearchBuilder {
);
self
}

/// Choose whether to apply filters to directories and include matches in search results. Defaults to true.
/// ### Arguments
/// * `value`
/// ### Examples
/// ```rust
/// use rust_search::SearchBuilder;
///
/// let search: Vec<String> = SearchBuilder::default()
/// .dirs(false)
/// .build()
/// .collect();
/// ```
pub fn dirs(mut self, value: bool) -> Self {
self.dirs = value;
self
}
}

impl Default for SearchBuilder {
Expand All @@ -249,6 +269,7 @@ impl Default for SearchBuilder {
ignore_case: false,
hidden: false,
filters: vec![],
dirs: true,
}
}
}
5 changes: 4 additions & 1 deletion src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ pub enum FilterType {
}

impl FilterType {
pub fn apply(&self, dir: &DirEntry) -> bool {
pub fn apply(&self, dir: &DirEntry, filter_dirs: bool) -> bool {
if let Ok(m) = dir.metadata() {
if !filter_dirs && m.file_type().is_dir() {
return true;
}
match self {
Self::Created(cmp, time) => {
if let Ok(created) = m.created() {
Expand Down
14 changes: 13 additions & 1 deletion src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ impl Search {
/// * `ignore_case` - Whether to ignore case or not
/// * `hidden` - Whether to search hidden files or not
/// * `filters` - Vector of filters to search by `DirEntry` data
/// * `dirs` - Whether to apply filters to directories and include them in results.
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
search_location: impl AsRef<Path>,
Expand All @@ -71,6 +72,7 @@ impl Search {
ignore_case: bool,
with_hidden: bool,
filters: Vec<FilterType>,
dirs: bool,
) -> Self {
let regex_search_input =
utils::build_regex_search_input(search_input, file_ext, strict, ignore_case);
Expand All @@ -85,7 +87,7 @@ impl Search {

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

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

Box::new(move |path_entry| {
if let Ok(entry) = path_entry {
if !dirs {
// if dirs is false and entry is a directory,
// proceed with the search without sending its path or incrementing the counter
if let Ok(m) = entry.metadata() {
if m.file_type().is_dir() {
return WalkState::Continue;
}
}
}

let path = entry.path();
if let Some(file_name) = path.file_name() {
// Lossy means that if the file name is not valid UTF-8
Expand Down