Skip to content

Commit 288433e

Browse files
authored
feat: transition to builder pattern & add features
1 parent 2d1fbcd commit 288433e

File tree

5 files changed

+399
-117
lines changed

5 files changed

+399
-117
lines changed

README.md

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,25 @@ Add `rust_search = "0.1.4"` in Cargo.toml.
1515
rust_search = "0.1.4"
1616
```
1717

18-
Then, use it in your code:
18+
## Examples
19+
20+
Genral use
1921

2022
```rust
21-
use rust_search::Search;
23+
use rust_search::SearchBuilder;
2224

2325
fn main(){
24-
let depth = 1;
25-
26-
let search = Search::new("/path/to/directory", Some("fileName"), Some(".fileExtension"), Some(depth));
26+
let search: Vec<String> = SearchBuilder::default()
27+
.location("/path/to/search")
28+
.search_input("what to search")
29+
.more_locations(vec!["/anotherPath/to/search", "/keepAddingIfYouWant/"])
30+
.ext(".extension")
31+
.strict()
32+
.depth(1)
33+
.ignore_case()
34+
.hidden()
35+
.build()
36+
.collect();
2737

2838
for path in search {
2939
println!("{}", path);
@@ -34,25 +44,38 @@ fn main(){
3444
To get all the files with a specific extension in a directory, use:
3545

3646
```rust
37-
use rust_search::Search;
47+
use rust_search::SearchBuilder;
3848

39-
Search::new("/path/to/directory", None, Some(".fileExtension"), Some(1));
49+
let files: Vec<String> = SearchBuilder::default()
50+
.location("/path/to/directory")
51+
.ext("file_extension")
52+
.build()
53+
.collect();
4054
```
4155

4256
To get all the files in a directory, use:
4357

4458
```rust
45-
use rust_search::Search;
59+
use rust_search::SearchBuilder;
4660

47-
Search::new("/path/to/directory", None, None, Some(1));
61+
let files: Vec<String> = SearchBuilder::default()
62+
.location("/path/to/directory")
63+
.depth(1)
64+
.build()
65+
.collect();
4866
```
4967

68+
👉 For more examples, please refer to the [Documentation](https://docs.rs/rust_search/latest/rust_search/)
69+
5070
## ⚙️ Benchmarks
71+
5172
The difference in sample size is due to the fact that fd and glob are different tools and have different use cases. fd is a command line tool that searches for files and directories. glob is a library that can be used to search for files and directories. The benchmark is done on a MacBook Air M2, 16 GB Unified memory.
5273

5374
Benchmarks are done using [hyperfine](https://github.com/sharkdp/hyperfine),
5475
Benchmarks files are available in the [benchmarks](https://drive.google.com/drive/folders/1ug6ojNixS5jAe6Lh6M0o2d3tku73zQ9w?usp=sharing) drive folder.
76+
5577
### - Rust vs Glob
78+
5679
The benchmark was done on a directories containing 300K files.
5780

5881
| Command / Library | Mean [s] | Min [s] | Max [s] | Relative |
@@ -61,7 +84,9 @@ The benchmark was done on a directories containing 300K files.
6184
| `glob` | 22.728 ± 0.023 | 22.690 | 22.746 | 17.25 ± 0.03 |
6285

6386
---
87+
6488
### - Rust vs FD
89+
6590
The benchmark was done on a directories containing 45K files.
6691

6792
| Command / Library | Mean [ms] | Min [ms] | Max [ms] | Relative |
@@ -72,6 +97,7 @@ The benchmark was done on a directories containing 45K files.
7297
---
7398

7499
### Results:-
100+
75101
```diff
76102
+ Rust_Search is 17.25 times faster than Glob.
77103

@@ -80,7 +106,7 @@ The benchmark was done on a directories containing 45K files.
80106

81107
## 🔵 Discord server & Linkedin
82108

83-
Click the button below to join the discord server or Linkedin
109+
Click the button below to join the discord server or Linkedin
84110

85111
<a href="https://discord.gg/hqDPyNb9m3" target="_blank"><img src="https://user-images.githubusercontent.com/42001064/126635148-9a736436-5a6d-4298-8d8e-acda11aec74c.png" alt="Join Discord Server" width="180px" ></a>
86112
<a href="https://www.linkedin.com/in/parthjadhav04" target="_blank"><img src="https://img.shields.io/badge/Linkedin-blue?style=flat-square&logo=linkedin" alt="Connect on Linkedin" width="180px" height="58"></a>
@@ -93,3 +119,25 @@ Any contributions would be greatly valued as this library is still in its early
93119
- Benchmarks
94120
- Implementation guidlines
95121
- Code Improvement
122+
123+
If you want to contribute to this project, please follow the steps below:
124+
125+
1. Fork the project
126+
2. Clone the forked repository
127+
3. Create a feature branch
128+
4. Make changes to the code
129+
5. Commit the changes
130+
6. Push the changes to the forked repository
131+
7. Create a pull request
132+
8. Wait for the pull request to be reviewed and merged (if approved)
133+
134+
## License
135+
136+
This project is licensed under the terms of the MIT license.
137+
138+
## Discord server & Linkedin
139+
140+
Click the button below to join the discord server or Linkedin
141+
142+
<a href="https://discord.gg/hqDPyNb9m3" target="_blank"><img src="https://user-images.githubusercontent.com/42001064/126635148-9a736436-5a6d-4298-8d8e-acda11aec74c.png" alt="Join Discord Server" width="180px" ></a>
143+
<a href="https://www.linkedin.com/in/parthjadhav04" target="_blank"><img src="https://img.shields.io/badge/Linkedin-blue?style=flat-square&logo=linkedin" alt="Connect on Linkedin" width="180px" height="58"></a>

src/builder.rs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
use std::path::{Path, PathBuf};
2+
3+
use crate::Search;
4+
5+
/// Builder for a [`Search`] instance, allowing for more complex searches.
6+
pub struct SearchBuilder {
7+
/// The location to search in, defaults to the current directory.
8+
search_location: PathBuf,
9+
/// Vector of additional locations to search in.
10+
more_locations: Option<Vec<PathBuf>>,
11+
/// The search input, defaults to search for every word.
12+
search_input: Option<String>,
13+
/// The file extension to search for, defaults to any file extension.
14+
file_ext: Option<String>,
15+
/// The depth to search to, defaults to no limit.
16+
depth: Option<usize>,
17+
/// When set to true, Searches for exact match, defaults to false.
18+
strict: bool,
19+
/// Set search option to be case insensitive, defaults to false.
20+
ignore_case: bool,
21+
/// Search for hidden files, defaults to false.
22+
hidden: bool,
23+
}
24+
25+
impl SearchBuilder {
26+
/// Build a new [`Search`] instance.
27+
#[allow(deprecated)]
28+
pub fn build(&self) -> Search {
29+
Search::new(
30+
&self.search_location,
31+
self.more_locations.clone(),
32+
self.search_input.as_deref(),
33+
self.file_ext.as_deref(),
34+
self.depth,
35+
self.strict,
36+
self.ignore_case,
37+
self.hidden,
38+
)
39+
}
40+
41+
/// Set the search location to search in.
42+
/// ### Arguments
43+
/// * `location` - The location to search in.
44+
/// ### Examples
45+
/// ```rust
46+
/// use rust_search::SearchBuilder;
47+
///
48+
/// let search: Vec<String> = SearchBuilder::default()
49+
/// .location("src")
50+
/// .build()
51+
/// .collect();
52+
/// ```
53+
pub fn location(mut self, location: impl AsRef<Path>) -> Self {
54+
self.search_location = location.as_ref().to_path_buf();
55+
self
56+
}
57+
58+
/// Set the search input.
59+
/// ### Arguments
60+
/// * `input` - The search input.
61+
/// ### Examples
62+
/// ```rust
63+
/// use rust_search::SearchBuilder;
64+
///
65+
/// let search: Vec<String> = SearchBuilder::default()
66+
/// .search_input("Search")
67+
/// .build()
68+
/// .collect();
69+
/// ```
70+
pub fn search_input(mut self, input: impl Into<String>) -> Self {
71+
self.search_input = Some(input.into());
72+
self
73+
}
74+
75+
/// Set the file extension to search for.
76+
/// ### Arguments
77+
/// * `ext` - The file extension to search for.
78+
/// ### Examples
79+
/// ```rust
80+
/// use rust_search::SearchBuilder;
81+
///
82+
/// let search: Vec<String> = SearchBuilder::default()
83+
/// .ext(".rs")
84+
/// .build()
85+
/// .collect();
86+
/// ```
87+
pub fn ext(mut self, ext: impl Into<String>) -> Self {
88+
self.file_ext = Some(ext.into());
89+
self
90+
}
91+
92+
/// Set the depth to search to.
93+
/// ### Arguments
94+
/// * `depth` - The depth to search to.
95+
/// ### Examples
96+
/// ```rust
97+
/// use rust_search::SearchBuilder;
98+
///
99+
/// let search: Vec<String> = SearchBuilder::default()
100+
/// .depth(1)
101+
/// .build()
102+
/// .collect();
103+
/// ```
104+
pub fn depth(mut self, depth: usize) -> Self {
105+
self.depth = Some(depth);
106+
self
107+
}
108+
109+
/// Searches for exact match
110+
/// ### Examples
111+
/// ```rust
112+
/// use rust_search::SearchBuilder;
113+
///
114+
/// let search: Vec<String> = SearchBuilder::default()
115+
/// .search_input("name")
116+
/// .strict()
117+
/// .build()
118+
/// .collect();
119+
/// ```
120+
pub fn strict(mut self) -> Self {
121+
self.strict = true;
122+
self
123+
}
124+
125+
/// Set search option to be case insensitive.
126+
/// ### Examples
127+
/// ```rust
128+
/// use rust_search::SearchBuilder;
129+
///
130+
/// let search: Vec<String> = SearchBuilder::default()
131+
/// .search_input("name")
132+
/// .ignore_case()
133+
/// .build()
134+
/// .collect();
135+
/// ```
136+
pub fn ignore_case(mut self) -> Self {
137+
self.ignore_case = true;
138+
self
139+
}
140+
141+
/// Searches for hidden files
142+
/// ### Examples
143+
/// ```rust
144+
/// use rust_search::SearchBuilder;
145+
///
146+
/// let search: Vec<String> = SearchBuilder::default()
147+
/// .with_hidden()
148+
/// .build()
149+
/// .collect();
150+
/// ```
151+
pub fn hidden(mut self) -> Self {
152+
self.hidden = true;
153+
self
154+
}
155+
156+
/// Add extra locations to search in.
157+
/// ### Arguments
158+
/// * `more_locations` - Vec<> of locations to search in.
159+
/// ### Examples
160+
/// ```rust
161+
/// use rust_search::SearchBuilder;
162+
///
163+
/// let search: Vec<String> = SearchBuilder::default()
164+
/// .more_locations(vec!["/Users/username/b/", "/Users/username/c/"])
165+
/// .build()
166+
/// .collect();
167+
/// ```
168+
pub fn more_locations(mut self, more_locations: Vec<impl AsRef<Path>>) -> Self {
169+
self.more_locations = Some(
170+
more_locations
171+
.into_iter()
172+
.map(|x| x.as_ref().to_path_buf())
173+
.collect(),
174+
);
175+
self
176+
}
177+
}
178+
179+
impl Default for SearchBuilder {
180+
fn default() -> Self {
181+
Self {
182+
search_location: std::env::current_dir().expect("Failed to get current directory"),
183+
more_locations: None,
184+
search_input: None,
185+
file_ext: None,
186+
depth: None,
187+
strict: false,
188+
ignore_case: false,
189+
hidden: false,
190+
}
191+
}
192+
}

0 commit comments

Comments
 (0)