Skip to content

Commit 63cab48

Browse files
committed
use regex for searching.
1 parent 73225b6 commit 63cab48

File tree

2 files changed

+76
-30
lines changed

2 files changed

+76
-30
lines changed

File-Explorer/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,11 @@ edition = "2021"
88
[dependencies]
99
walkdir = "2.3"
1010
druid = "0.8.3"
11+
regex = "1.5"
12+
13+
14+
[profile.dev]
15+
panic = "abort"
16+
17+
[profile.release]
18+
panic = "abort"

File-Explorer/src/main.rs

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
use druid::{AppLauncher, Data, Env, Lens, LocalizedString, Selector, SingleUse, Target, Widget, WidgetExt, WindowDesc};
2-
use std::path::{Path, PathBuf};
3-
use std::sync::{Arc, Mutex};
4-
use walkdir::WalkDir;
5-
use std::env;
1+
use druid::{widget, AppLauncher, Data, Lens, LocalizedString, Widget, WidgetExt, WindowDesc};
2+
use regex::Regex;
3+
64

75

6+
use std::path::{Path, PathBuf};
7+
use std::sync::{mpsc, Arc, Mutex};
8+
use std::thread;
9+
use walkdir::WalkDir;
810

911
#[derive(Clone, Data, Lens)]
1012
struct AppState {
@@ -14,43 +16,79 @@ struct AppState {
1416
result: String,
1517
}
1618

19+
#[derive(Clone, Data, Lens)]
20+
struct SearchUpdate {
21+
result: String,
22+
}
23+
1724
fn build_ui() -> impl Widget<AppState> {
18-
druid::widget::Flex::column()
19-
.with_child(druid::widget::TextBox::new().lens(AppState::search_term))
20-
.with_child(druid::widget::Button::new("Search").on_click(|_, data: &mut AppState, _| {
21-
let root_path = data.root_path.lock().unwrap().clone();
22-
let search_term = data.search_term.clone();
23-
24-
let result = search_files(&root_path, &search_term);
25-
data.result = result;
26-
}))
27-
.with_child(druid::widget::Label::new(|data: &AppState, _env: &_| data.result.clone()))
25+
let label = widget::Label::new(|data: &AppState, _env: &_| data.result.clone()).with_text_size(20.0);
26+
27+
let scrollable_label = druid::widget::Scroll::new(label);
28+
29+
widget::Flex::column()
30+
.with_child(widget::TextBox::new().lens(AppState::search_term))
31+
.with_child(
32+
widget::Button::new("Search").on_click(|_, data: &mut AppState, _| {
33+
let root_path = data.root_path.lock().unwrap().clone();
34+
let search_term = data.search_term.clone();
35+
36+
let (tx, rx) = mpsc::channel();
37+
let tx_copy = tx.clone();
38+
39+
thread::spawn(move || {
40+
let result = search_files(&root_path, &search_term, Some(tx));
41+
let _ = tx_copy.send(SearchUpdate { result });
42+
});
43+
44+
let mut result = String::new();
45+
for update in rx.iter() {
46+
result.push_str(&update.result);
47+
data.result = result.clone();
48+
}
49+
}),
50+
)
51+
.with_child(scrollable_label)
2852
}
2953

30-
fn search_files(root_path: &Path, search_term: &str) -> String {
54+
fn search_files(
55+
root_path: &Path,
56+
search_term: &str,
57+
tx: Option<mpsc::Sender<SearchUpdate>>,
58+
) -> String {
3159
let mut result = String::new();
60+
let search_term_regex = Regex::new(&format!(r"(?i){}", search_term)).expect("Invalid regex");
3261

33-
for entry in WalkDir::new(root_path) {
34-
if let Ok(entry) = entry {
35-
let path = entry.path();
36-
if path.is_file() {
37-
if let Some(file_name) = path.file_name() {
38-
if file_name.to_string_lossy().contains(search_term) {
39-
result.push_str(&format!("{}\n", path.display()));
40-
}
41-
}
62+
WalkDir::new(root_path)
63+
.into_iter()
64+
.filter_map(|entry| entry.ok())
65+
.filter(|entry| entry.path().is_file())
66+
.filter(|entry| {
67+
entry
68+
.file_name()
69+
.to_str()
70+
.map(|name| search_term_regex.is_match(name))
71+
.unwrap_or(false)
72+
})
73+
.for_each(|entry| {
74+
let found_path = format!("{}\n", entry.path().display());
75+
result.push_str(&found_path);
76+
if let Some(tx) = &tx {
77+
let _ = tx.send(SearchUpdate {
78+
result: found_path.clone(),
79+
});
4280
}
43-
}
44-
}
81+
});
4582

4683
result
4784
}
4885

86+
4987
fn main() {
5088
let main_window = WindowDesc::new(build_ui())
51-
.title(LocalizedString::new("File Explorer"));
89+
.title(LocalizedString::new("File Explorer"));
5290

53-
let root_path = Arc::new(Mutex::new(env::current_dir().unwrap()));
91+
let root_path = Arc::new(Mutex::new(std::env::current_dir().unwrap()));
5492

5593
let app_state = AppState {
5694
root_path: root_path.clone(),
@@ -62,4 +100,4 @@ fn main() {
62100
.log_to_console()
63101
.launch(app_state)
64102
.expect("Failed to launch application");
65-
}
103+
}

0 commit comments

Comments
 (0)