Repository: ParthJadhav/Rust_Search (language: rust)

Issue:
Possibility to set a limit for upcoming files
^ Title
---
I will work on it


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 5526746..8d40a94 100644
--- a/README.md
+++ b/README.md
@@ -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)
diff --git a/src/builder.rs b/src/builder.rs
index 281a2b5..a139e3d 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -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.
@@ -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,
@@ -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".
@@ -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,
diff --git a/src/search.rs b/src/search.rs
index 24d077d..f7b36c7 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -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()
     }
 }
 
@@ -57,9 +54,10 @@ 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>,
@@ -67,6 +65,7 @@ impl Search {
         search_input: Option<&str>,
         file_ext: Option<&str>,
         depth: Option<usize>,
+        limit: Option<usize>,
         strict: bool,
         ignore_case: bool,
         with_hidden: bool,
@@ -92,6 +91,7 @@ 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 {
@@ -99,7 +99,14 @@ impl Search {
 
                     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,
                         };
                     }
@@ -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()),
+            }
+        }
     }
 }
 


Test patch: