Skip to content

Commit

Permalink
feat: add ability to set limit of results in output
Browse files Browse the repository at this point in the history
Co-authored-by: Parth Jadhav <jadhavparth99@gmail.com>
  • Loading branch information
TheAwiteb and ParthJadhav committed Nov 8, 2022
1 parent 0b6210f commit 9c729a8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ fn main(){
.location("~/path/to/directory")
.search_input("what to search")
.more_locations(vec!["/anotherPath/to/search", "/keepAddingIfYouWant/"])
.limit(1000) // results to return
.ext("extension")
.strict()
.depth(1)
Expand Down
21 changes: 21 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub struct SearchBuilder {
file_ext: Option<String>,
/// The depth to search to, defaults to no limit.
depth: Option<usize>,
/// The limit of results to return, defaults to no limit.
limit: Option<usize>,
/// When set to true, Searches for exact match, defaults to false.
strict: bool,
/// Set search option to be case insensitive, defaults to false.
Expand All @@ -32,6 +34,7 @@ impl SearchBuilder {
self.search_input.as_deref(),
self.file_ext.as_deref(),
self.depth,
self.limit,
self.strict,
self.ignore_case,
self.hidden,
Expand Down Expand Up @@ -110,6 +113,23 @@ impl SearchBuilder {
self
}

/// Set the limit of results to return. This will limit the amount of results returned.
/// ### Arguments
/// * `limit` - The limit of results to return.
/// ### Examples
/// ```rust
/// use rust_search::SearchBuilder;
///
/// let search: Vec<String> = SearchBuilder::default()
/// .limit(5)
/// .build()
/// .collect();
/// ```
pub fn limit(mut self, limit: usize) -> Self {
self.limit = Some(limit);
self
}

/// Searches for exact match.
///
/// For example, if the search input is "Search", the file "Search.rs" will be found, but not "Searcher.rs".
Expand Down Expand Up @@ -195,6 +215,7 @@ impl Default for SearchBuilder {
search_input: None,
file_ext: None,
depth: None,
limit: None,
strict: false,
ignore_case: false,
hidden: false,
Expand Down
33 changes: 25 additions & 8 deletions src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,14 @@ use regex::Regex;
/// let paths_vec: Vec<String> = search.collect();
/// ```
pub struct Search {
rx: mpsc::Receiver<String>,
rx: Box<dyn Iterator<Item = String>>,
}

impl Iterator for Search {
type Item = String;

fn next(&mut self) -> Option<Self::Item> {
match self.rx.recv() {
Ok(v) => Some(v),
Err(_) => None,
}
self.rx.next()
}
}

Expand All @@ -57,16 +54,18 @@ impl Search {
/// * `search_input` - The search input, defaults to any word
/// * `file_ext` - The file extension to search for, defaults to any file extension
/// * `depth` - The depth to search to, defaults to no limit
/// * `limit` - The limit of results to return, defaults to no limit
/// * `strict` - Whether to search for the exact word or not
/// * `ignore_case` - Whether to ignore case or not
/// * `hidden` - Whether to search hidden files or not, files starting with a dot
/// * `hidden` - Whether to search hidden files or not
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
search_location: impl AsRef<Path>,
more_locations: Option<Vec<impl AsRef<Path>>>,
search_input: Option<&str>,
file_ext: Option<&str>,
depth: Option<usize>,
limit: Option<usize>,
strict: bool,
ignore_case: bool,
with_hidden: bool,
Expand All @@ -92,14 +91,22 @@ impl Search {
walker.build_parallel().run(|| {
let tx: Sender<String> = tx.clone();
let reg_exp: Regex = regex_search_input.clone();
let mut counter = 0;

Box::new(move |path_entry| {
if let Ok(entry) = path_entry {
let path: String = entry.path().display().to_string();

if reg_exp.is_match(&path) {
return match tx.send(path) {
Ok(_) => WalkState::Continue,
Ok(_) => {
counter += 1;
if limit.is_some() && counter >= limit.unwrap() {
WalkState::Quit
} else {
WalkState::Continue
}
}
Err(_) => WalkState::Quit,
};
}
Expand All @@ -109,7 +116,17 @@ impl Search {
})
});

Self { rx }
if let Some(limit) = limit {
// This will take the first `limit` elements from the iterator
// will return all if there are less than `limit` elements
Self {
rx: Box::new(rx.into_iter().take(limit)),
}
} else {
Self {
rx: Box::new(rx.into_iter()),
}
}
}
}

Expand Down

0 comments on commit 9c729a8

Please sign in to comment.