1- use regex:: Regex ;
21use std:: ffi:: OsStr ;
32use std:: fs;
43use std:: path:: Path ;
54use std:: path:: PathBuf ;
65
7- pub fn find_file_paths ( input : & str ) -> Vec < String > {
8- let pattern = r#"(\./[^\s<>:\",|?*]+(?:/[^\s<>:\",|?*]+)*|\.\./[^\s<>:\"|?*]+(?:/[^\s<>:\"|?*]+)*|[a-zA-Z]:\\[^\s<>:\",|?*]+(?:\\[^\s<>:\",|?*]+)*|/[^<>\s:\",|?*\r\n]+(?:/[^<>:\"|?*\r\n]+)*)"# ;
9- let re = Regex :: new ( pattern) . unwrap ( ) ;
10- re. find_iter ( input)
11- . map ( |m| m. as_str ( ) . to_string ( ) )
12- . collect ( )
13- }
14-
156pub fn list_all_file_items ( path : & Path ) -> Vec < String > {
167 let read_result = fs:: read_dir ( path) ;
178 let mut result = Vec :: new ( ) ;
@@ -29,20 +20,29 @@ pub fn list_all_file_items(path: &Path) -> Vec<String> {
2920 result
3021}
3122
32- pub fn get_file_items ( text : & str , root_folder : & str ) -> Vec < String > {
23+ const MAX_LINE_LENGTH : usize = 600 ;
24+
25+ pub fn get_file_items ( current_line : & str , root_folder : & str ) -> Vec < ( String , usize ) > {
26+ if current_line. len ( ) >= MAX_LINE_LENGTH {
27+ return Vec :: new ( ) ;
28+ }
29+
3330 let mut file_items = Vec :: new ( ) ;
34- let file_paths = find_file_paths ( & text) ;
35- // info!("file path size: {}", file_paths.len());
36- for file_path in file_paths. iter ( ) {
37- let mut root = PathBuf :: from ( root_folder) ;
38- root = root. join ( file_path) ;
39- if !root. is_dir ( ) {
40- root = root. parent ( ) . map ( |p| p. to_path_buf ( ) ) . unwrap ( ) ;
31+ for ( j, _) in current_line. char_indices ( ) . filter ( |& ( _, ch) | ch == '/' || ch == '\\' ) {
32+ for i in 0 ..j {
33+ let p = & current_line[ i..j] ;
34+
35+ for base in [ root_folder, "" ] . iter ( ) . map ( PathBuf :: from) {
36+ let path = base. join ( p) ;
37+ file_items. extend (
38+ list_all_file_items ( & path)
39+ . into_iter ( )
40+ . map ( |file_path| ( file_path, j) )
41+ ) ;
42+ }
4143 }
42- let possible = list_all_file_items ( & root) ;
43- file_items. extend ( possible) ;
44- // info!("file path: {}", file_path);
4544 }
45+
4646 file_items. sort ( ) ;
4747 file_items. dedup ( ) ;
4848 file_items
@@ -74,82 +74,4 @@ mod tests {
7474 let items = list_all_file_items ( Path :: new ( "doesnt_exist" ) ) ;
7575 assert_eq ! ( 0 , items. len( ) ) ;
7676 }
77-
78- #[ test]
79- fn test_find_file_paths ( ) {
80- let example = "path/to/my_file.txt" ;
81- assert_eq ! ( find_file_paths( example) , vec![ "/to/my_file.txt" ] ) ;
82-
83- let example = "Check these paths: C:\\ Users\\ User\\ file.txt, /home/user/docs/report.pdf" ;
84- assert_eq ! (
85- find_file_paths( example) ,
86- vec![ "C:\\ Users\\ User\\ file.txt" , "/home/user/docs/report.pdf" ]
87- ) ;
88-
89- let example = "./file.txt" ;
90- assert_eq ! ( find_file_paths( example) , vec![ "./file.txt" ] ) ;
91-
92- let example = "./" ;
93- assert_eq ! ( find_file_paths( example) , Vec :: <String >:: new( ) ) ;
94-
95- let example = "Some text with a path ./src/main.rs in it." ;
96- assert_eq ! ( find_file_paths( example) , vec![ "./src/main.rs" ] ) ;
97-
98- let example = "Multiple paths: ./file1.txt, ./file2.txt, ./file3.txt" ;
99- assert_eq ! (
100- find_file_paths( example) ,
101- vec![ "./file1.txt" , "./file2.txt" , "./file3.txt" ]
102- ) ;
103-
104- let example = "A path with spaces: /path/to/a_long_name_file.txt" ;
105- assert_eq ! ( find_file_paths( example) , vec![ "/path/to/a_long_name_file.txt" ] ) ;
106-
107- let example = "A relative path: ../parent/file.txt" ;
108- assert_eq ! ( find_file_paths( example) , vec![ "../parent/file.txt" ] ) ;
109-
110- let example = "Just the drive letter: C:\\ " ;
111- assert_eq ! ( find_file_paths( example) , Vec :: <String >:: new( ) ) ;
112-
113- let example = "A more complex windows path: D:\\ MyDocuments\\ Project\\ file.pdf" ;
114- assert_eq ! (
115- find_file_paths( example) ,
116- vec![ "D:\\ MyDocuments\\ Project\\ file.pdf" ]
117- ) ;
118-
119- let example =
120- "Mix of paths: ./local/file.txt and /absolute/file.txt and C:\\ windows\\ file.exe" ;
121- assert_eq ! (
122- find_file_paths( example) ,
123- vec![
124- "./local/file.txt" ,
125- "/absolute/file.txt" ,
126- "C:\\ windows\\ file.exe"
127- ]
128- ) ;
129-
130- let example = "No paths here." ;
131- assert_eq ! ( find_file_paths( example) , Vec :: <String >:: new( ) ) ;
132-
133- let example = "Path at the end: /opt/app/data" ;
134- assert_eq ! ( find_file_paths( example) , vec![ "/opt/app/data" ] ) ;
135-
136- let example =
137- "This is a test with a long path: /very/long/path/to/a/deeply/nested/file.txt" ;
138- assert_eq ! (
139- find_file_paths( example) ,
140- vec![ "/very/long/path/to/a/deeply/nested/file.txt" ]
141- ) ;
142-
143- let example = "This is a test with a long windows path: C:\\ very\\ long\\ path\\ to\\ a\\ deeply\\ nested\\ file.txt" ;
144- assert_eq ! (
145- find_file_paths( example) ,
146- vec![ "C:\\ very\\ long\\ path\\ to\\ a\\ deeply\\ nested\\ file.txt" ]
147- ) ;
148-
149- let example = "This is a test with a long relative path: ./very/long/path/to/a/deeply/nested/file.txt" ;
150- assert_eq ! (
151- find_file_paths( example) ,
152- vec![ "./very/long/path/to/a/deeply/nested/file.txt" ]
153- ) ;
154- }
15577}
0 commit comments