1- extern crate walkdir;
2- extern crate regex;
3-
4-
5- use std:: env;
6- use std:: fs:: File ;
7- use std:: io:: { self , BufRead } ;
8-
9- use regex:: Regex ;
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 } ;
104use walkdir:: WalkDir ;
5+ use std:: env;
116
12- fn search_by_name ( directory : & str , file_name : & str ) {
13- let file_name_regex = Regex :: new ( file_name) . expect ( "Invalid regex" ) ;
147
15- for entry in WalkDir :: new ( directory) {
16- let entry = entry. expect ( "Error reading directory entry" ) ;
17- let file_path = entry. path ( ) ;
188
19- if let Some ( file_name ) = file_path . file_name ( ) {
20- if file_name_regex . is_match ( file_name . to_str ( ) . unwrap_or ( "" ) ) {
21- println ! ( "{}" , file_path . display ( ) ) ;
22- }
23- }
24- }
9+ # [ derive ( Clone , Data , Lens ) ]
10+ struct AppState {
11+ # [ lens ( ignore ) ]
12+ root_path : Arc < Mutex < PathBuf > > ,
13+ search_term : String ,
14+ result : String ,
2515}
2616
27- fn search_by_content ( directory : & str , content : & str ) {
28- for entry in WalkDir :: new ( directory) {
29- let entry = entry. expect ( "Error reading directory entry" ) ;
30- let file_path = entry. path ( ) ;
17+ 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 ( ) ;
3123
32- if file_path. is_file ( ) {
33- if let Ok ( file) = File :: open ( file_path) {
34- let reader = io:: BufReader :: new ( file) ;
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 ( ) ) )
28+ }
29+
30+ fn search_files ( root_path : & Path , search_term : & str ) -> String {
31+ let mut result = String :: new ( ) ;
3532
36- for line in reader. lines ( ) {
37- if let Ok ( line) = line {
38- if line. contains ( content) {
39- println ! ( "{}" , file_path. display( ) ) ;
40- break ;
41- }
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( ) ) ) ;
4240 }
4341 }
4442 }
4543 }
4644 }
45+
46+ result
4747}
4848
4949fn main ( ) {
50- let args: Vec < String > = env:: args ( ) . collect ( ) ;
50+ let main_window = WindowDesc :: new ( build_ui ( ) )
51+ . title ( LocalizedString :: new ( "File Explorer" ) ) ;
5152
52- if args. len ( ) < 3 {
53- println ! ( "Usage: {} <directory> <search_term> [options: -n for name, -c for content]" , args[ 0 ] ) ;
54- return ;
55- }
53+ let root_path = Arc :: new ( Mutex :: new ( env:: current_dir ( ) . unwrap ( ) ) ) ;
5654
57- let directory = & args[ 1 ] ;
58- let search_term = & args[ 2 ] ;
55+ let app_state = AppState {
56+ root_path : root_path. clone ( ) ,
57+ search_term : String :: new ( ) ,
58+ result : String :: new ( ) ,
59+ } ;
5960
60- if args. len ( ) == 3 {
61- // Default search by name
62- search_by_name ( directory, search_term) ;
63- } else {
64- let option = & args[ 3 ] ;
65- match option. as_str ( ) {
66- "-n" => search_by_name ( directory, search_term) ,
67- "-c" => search_by_content ( directory, search_term) ,
68- _ => println ! ( "Invalid option: {}" , option) ,
69- }
70- }
71- }
61+ AppLauncher :: with_window ( main_window)
62+ . log_to_console ( )
63+ . launch ( app_state)
64+ . expect ( "Failed to launch application" ) ;
65+ }
0 commit comments