scan_lib/lib.rs
1pub mod file_operations;
2pub mod dir_operations;
3pub mod path_manipulation;
4
5use std::collections::HashSet;
6use std::fs;
7use std::fs::File;
8use std::io::BufRead;
9use std::io::BufReader;
10use std::io::Write;
11use std::fs::OpenOptions;
12
13/// The `DirectorySearcher` struct in Rust provides functionality to search directories for specific
14/// files while maintaining a blacklist of paths.
15///
16/// Properties:
17///
18/// * `blacklist`: The `blacklist` property in the `DirectorySearcher` struct is a HashSet that stores
19/// strings representing paths that should be excluded from the search. This blacklist is used to skip
20/// certain directories during the search process.
21/// * `blacklist_file_write`: The `blacklist_file_write` property in the `DirectorySearcher` struct is
22/// of type `File`. It is used to store a file handle for writing to the blacklist file. This file
23/// handle is used to append entries to the blacklist file when needed, such as when a path is added to
24pub struct DirectorySearcher{
25 blacklist: HashSet<String>,
26 blacklist_file_write: File,
27}
28
29impl DirectorySearcher {
30 /// The function creates a new instance of DirectorySearcher with a blacklist HashSet and a file for
31 /// writing blacklist entries.
32 ///
33 /// Returns:
34 ///
35 /// A new instance of the `DirectorySearcher` struct is being returned.
36 pub fn new() -> Self {
37 let file= match OpenOptions::new().append(true).open("src\\blacklist.txt") {
38 Ok(file) => file,
39 Err(_e) => file_operations::new_file_return_append()
40 };
41 DirectorySearcher{
42 blacklist: HashSet::new(),
43 blacklist_file_write: file,
44 }
45 }
46 /// The function `update_blacklist` reads a file named "blacklist.txt" and updates a blacklist
47 /// collection with its contents.
48 pub fn update_blacklist(&mut self) {
49 let file: File = match OpenOptions::new().read(true).open("src\\blacklist.txt") {
50 Ok(file) => file,
51 Err(_e) => file_operations::new_file_return()
52 };
53 let reader: BufReader<File> = BufReader::new(file);
54 self.blacklist.clear();
55 for line in reader.lines() {
56 if let Ok(line) = line {
57 self.blacklist.insert(line);
58 }
59 }
60 }
61
62 /// The function searches for a specific string in file paths within a given root directory while
63 /// avoiding blacklisted paths.
64 ///
65 /// Arguments:
66 ///
67 /// * `root_path`: The `root_path` parameter is a reference to a string that represents the root
68 /// path from which the search operation will start. This path is the starting point for searching
69 /// for files or directories containing the specified search term.
70 /// * `be_searched_`: The `be_searched_` parameter in the `search` function is a reference to a
71 /// string that represents the keyword or phrase that is being searched for within the paths. This
72 /// parameter is expected to be in its original form without any modifications.
73 ///
74 /// Returns:
75 ///
76 /// A vector of strings containing the paths that match the search criteria.
77 pub(crate) fn search(&mut self, root_path: &str, be_searched_: &str) -> Vec<String> {
78 if self.blacklist.contains(&root_path.to_string()) {
79 return Vec::new();
80 }
81 let be_searched: String = be_searched_.to_lowercase();
82 let paths: Vec<String> = self.get_paths(&root_path.trim());
83 let mut matchers: Vec<String> = Vec::new();
84 let mut dirs: Vec<String> = Vec::new();
85 for i in paths.iter() {
86 if dir_operations::is_dir(i) {
87 dirs.push(i.to_string());
88 }
89 let breakers: Vec<&str> = i.split("\\").collect();
90 if breakers[breakers.len() - 1].contains(&be_searched) {
91 matchers.push(i.to_string());
92 }
93 }
94 dirs.into_iter().for_each(|dir| matchers.append(&mut self.search(&dir, &be_searched)));
95 matchers
96 }
97
98 /// The function `get_paths` reads directory contents and returns a vector of file paths, handling
99 /// errors by writing to a blacklist file if necessary.
100 ///
101 /// Arguments:
102 ///
103 /// * `path`: The `path` parameter in the `get_paths` function is a reference to a string (`&str`)
104 /// which represents the directory path from which you want to read the directory entries.
105 ///
106 /// Returns:
107 ///
108 /// The `get_paths` function returns a `Vec<String>`. If the `fs::read_dir(path)` call is
109 /// successful, it populates the vector with paths obtained from the directory entries. If there is
110 /// an error, it writes the path to a blacklist file and returns an empty vector.
111 fn get_paths(&mut self, path: &str) -> Vec<String> {
112 if let Ok(paths) = fs::read_dir(path) {
113 let mut paths_: Vec<String> = Vec::new();
114 for path in paths {
115 paths_.push(path.unwrap().path().display().to_string());
116 }
117 return paths_;
118 } else {
119 let _ = self.blacklist_file_write.write(path.as_bytes()).unwrap();
120 let _ = self.blacklist_file_write.write(b"\n").unwrap();
121 return Vec::new();
122 }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 pub fn is_working() {
132 let mut searcher = DirectorySearcher::new();
133 searcher.search("F:", "java");
134 }
135}