rusty_files/core/
config.rs1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct SearchConfig {
6 pub index_path: PathBuf,
7 pub thread_count: usize,
8 pub max_file_size_for_content: u64,
9 pub enable_content_search: bool,
10 pub enable_fuzzy_search: bool,
11 pub fuzzy_threshold: f64,
12 pub cache_size: usize,
13 pub bloom_filter_capacity: usize,
14 pub bloom_filter_error_rate: f64,
15 pub max_search_results: usize,
16 pub batch_size: usize,
17 pub follow_symlinks: bool,
18 pub index_hidden_files: bool,
19 pub exclusion_patterns: Vec<String>,
20 pub watch_debounce_ms: u64,
21 pub enable_access_tracking: bool,
22 pub db_pool_size: u32,
23}
24
25impl Default for SearchConfig {
26 fn default() -> Self {
27 Self {
28 index_path: PathBuf::from("./filesearch.db"),
29 thread_count: num_cpus() * 2,
30 max_file_size_for_content: 10 * 1024 * 1024,
31 enable_content_search: false,
32 enable_fuzzy_search: true,
33 fuzzy_threshold: 0.7,
34 cache_size: 1000,
35 bloom_filter_capacity: 10_000_000,
36 bloom_filter_error_rate: 0.0001,
37 max_search_results: 1000,
38 batch_size: 1000,
39 follow_symlinks: false,
40 index_hidden_files: false,
41 exclusion_patterns: vec![
42 ".git".to_string(),
43 "node_modules".to_string(),
44 "target".to_string(),
45 ".DS_Store".to_string(),
46 ],
47 watch_debounce_ms: 500,
48 enable_access_tracking: true,
49 db_pool_size: 10,
50 }
51 }
52}
53
54impl SearchConfig {
55 pub fn from_file(path: &PathBuf) -> crate::core::error::Result<Self> {
56 let content = std::fs::read_to_string(path)?;
57 let config: Self = if path.extension().and_then(|s| s.to_str()) == Some("json") {
58 serde_json::from_str(&content)
59 .map_err(|e| crate::core::error::SearchError::Configuration(e.to_string()))?
60 } else {
61 toml::from_str(&content)
62 .map_err(|e| crate::core::error::SearchError::Configuration(e.to_string()))?
63 };
64 Ok(config)
65 }
66
67 pub fn to_file(&self, path: &PathBuf) -> crate::core::error::Result<()> {
68 let content = if path.extension().and_then(|s| s.to_str()) == Some("json") {
69 serde_json::to_string_pretty(self)
70 .map_err(|e| crate::core::error::SearchError::Configuration(e.to_string()))?
71 } else {
72 toml::to_string_pretty(self)
73 .map_err(|e| crate::core::error::SearchError::Configuration(e.to_string()))?
74 };
75 std::fs::write(path, content)?;
76 Ok(())
77 }
78}
79
80pub struct SearchConfigBuilder {
81 config: SearchConfig,
82}
83
84impl SearchConfigBuilder {
85 pub fn new() -> Self {
86 Self {
87 config: SearchConfig::default(),
88 }
89 }
90
91 pub fn index_path<P: Into<PathBuf>>(mut self, path: P) -> Self {
92 self.config.index_path = path.into();
93 self
94 }
95
96 pub fn thread_count(mut self, count: usize) -> Self {
97 self.config.thread_count = count;
98 self
99 }
100
101 pub fn max_file_size_for_content(mut self, size: u64) -> Self {
102 self.config.max_file_size_for_content = size;
103 self
104 }
105
106 pub fn enable_content_search(mut self, enable: bool) -> Self {
107 self.config.enable_content_search = enable;
108 self
109 }
110
111 pub fn enable_fuzzy_search(mut self, enable: bool) -> Self {
112 self.config.enable_fuzzy_search = enable;
113 self
114 }
115
116 pub fn fuzzy_threshold(mut self, threshold: f64) -> Self {
117 self.config.fuzzy_threshold = threshold;
118 self
119 }
120
121 pub fn cache_size(mut self, size: usize) -> Self {
122 self.config.cache_size = size;
123 self
124 }
125
126 pub fn max_search_results(mut self, max: usize) -> Self {
127 self.config.max_search_results = max;
128 self
129 }
130
131 pub fn batch_size(mut self, size: usize) -> Self {
132 self.config.batch_size = size;
133 self
134 }
135
136 pub fn follow_symlinks(mut self, follow: bool) -> Self {
137 self.config.follow_symlinks = follow;
138 self
139 }
140
141 pub fn index_hidden_files(mut self, index: bool) -> Self {
142 self.config.index_hidden_files = index;
143 self
144 }
145
146 pub fn exclusion_patterns(mut self, patterns: Vec<String>) -> Self {
147 self.config.exclusion_patterns = patterns;
148 self
149 }
150
151 pub fn add_exclusion_pattern<S: Into<String>>(mut self, pattern: S) -> Self {
152 self.config.exclusion_patterns.push(pattern.into());
153 self
154 }
155
156 pub fn watch_debounce_ms(mut self, ms: u64) -> Self {
157 self.config.watch_debounce_ms = ms;
158 self
159 }
160
161 pub fn enable_access_tracking(mut self, enable: bool) -> Self {
162 self.config.enable_access_tracking = enable;
163 self
164 }
165
166 pub fn db_pool_size(mut self, size: u32) -> Self {
167 self.config.db_pool_size = size;
168 self
169 }
170
171 pub fn build(self) -> SearchConfig {
172 self.config
173 }
174}
175
176impl Default for SearchConfigBuilder {
177 fn default() -> Self {
178 Self::new()
179 }
180}
181
182fn num_cpus() -> usize {
183 std::thread::available_parallelism()
184 .map(|n| n.get())
185 .unwrap_or(4)
186}