1
- use std:: io:: { Read , Write } ;
1
+ use std:: { io:: { Read , Write } , path :: PathBuf } ;
2
2
use super :: language:: * ;
3
3
4
4
pub struct CodeFile {
@@ -18,25 +18,10 @@ impl CodeFile {
18
18
continue
19
19
} ;
20
20
let path = file. path ( ) ;
21
- let Some ( file_name) = path. file_name ( ) . and_then ( |filename| filename. to_str ( ) ) else {
22
- // Non-UTF-8 name
23
- continue
24
- } ;
25
- let Some ( extension) = path. extension ( ) . and_then ( |ext| ext. to_str ( ) ) else {
26
- // A hidden file (like .gitignore), or a file with no '.', or a file with weird non-UTF-8 extension.
27
- continue
28
- } ;
29
- let Some ( language) = Language :: from_str ( extension) else {
30
- // Unsupported language
31
- continue ;
32
- } ;
21
+ let Some ( valid_file) = Self :: is_valid_file ( & path) else { continue } ;
22
+ let file_name = valid_file. 0 ;
23
+ code_file = Some ( valid_file. 1 ) ;
33
24
34
- code_file = Some (
35
- CodeFile {
36
- language, path : path. clone ( ) , question_title : String :: new ( ) , code : String :: new ( )
37
- }
38
- ) ;
39
-
40
25
if file_name. starts_with ( "main" ) {
41
26
break ;
42
27
}
@@ -65,10 +50,32 @@ impl CodeFile {
65
50
"Failed to read file {}" ,
66
51
code_file. path. display( )
67
52
) ) ;
53
+
54
+ let ( question_title, parsed_code) = Self :: parse_code ( & code) ;
55
+ code_file. question_title = question_title;
56
+ code_file. code = parsed_code;
57
+ code_file
58
+ }
59
+
60
+ fn is_valid_file < ' a > ( path : & ' a std:: path:: PathBuf ) -> Option < ( & ' a str , Self ) > {
61
+ let file_name = path. file_name ( ) . and_then ( |filename| filename. to_str ( ) ) ?;
62
+ let extension = path. extension ( ) . and_then ( |ext| ext. to_str ( ) ) ?;
63
+ let language = Language :: from_str ( extension) ?;
64
+
65
+ Some (
66
+ ( file_name, CodeFile {
67
+ language, path : path. clone ( ) , question_title : String :: new ( ) , code : String :: new ( )
68
+ } )
69
+ )
70
+ }
71
+
72
+ fn parse_code ( code : & str ) -> ( String , String ) {
73
+ let question_title: String ;
74
+ let parsed_code: String ;
68
75
let start = code
69
76
. find ( "#LCSTART" )
70
77
. map ( |idx| idx +
71
- // This returning None the user
78
+ // This returning None means the user
72
79
// wants to submit a practically empty file,
73
80
// but hey we don't judge!
74
81
code[ idx..] . find ( '\n' ) . unwrap_or ( 0 ) )
@@ -78,51 +85,31 @@ impl CodeFile {
78
85
if let Some ( problem) = code. find ( "leetcode.com/problems/" ) {
79
86
let problem = ( & code[ problem..] ) . split_whitespace ( ) . next ( ) . unwrap ( ) ;
80
87
let problem = problem. split ( '/' ) . skip ( 2 ) . next ( ) . unwrap ( ) ;
81
- code_file . question_title = problem. to_string ( ) ;
88
+ question_title = problem. to_string ( ) ;
82
89
} else {
83
90
println ! ( "No leetcode problem found in the code file. Please add the problem link in the code file using comments." ) ;
84
91
// terminate with error
85
92
std:: process:: exit ( 1 ) ;
86
93
}
87
- code_file. code = code[ start..end] . to_string ( ) ;
88
- code_file
94
+ parsed_code = code[ start..end] . to_string ( ) ;
95
+
96
+ ( question_title, parsed_code)
89
97
}
90
98
91
99
pub fn from_file ( path : String ) -> Self {
92
- let extension = path . split ( '.' ) . last ( ) . unwrap ( ) ;
93
- let language = Language :: from_str ( extension ) . expect ( "File extension not supported" ) ;
100
+ let path = PathBuf :: from ( path ) ;
101
+ let ( _ , mut valid_file ) = Self :: is_valid_file ( & path ) . expect ( "Improper filename or the language is not supported" ) ;
94
102
let file = std:: fs:: File :: open ( & path) ;
95
- let Ok ( mut file) = file else {
96
- println ! ( "Error while opening file {}" , & path ) ;
103
+ let Ok ( mut file) = file else {
104
+ eprintln ! ( "Error while opening file {}" , path. display ( ) ) ;
97
105
std:: process:: exit ( 1 ) ;
98
106
} ;
99
107
let mut code = String :: new ( ) ;
100
108
file. read_to_string ( & mut code)
101
- . expect ( & format ! ( "Failed to read file {}" , & path) ) ;
102
- let start = code
103
- . find ( "#LCSTART" )
104
- . map ( |idx| idx +
105
- // This returning None the user
106
- // wants to submit a practically empty file,
107
- // but hey we don't judge!
108
- code[ idx..] . find ( '\n' ) . unwrap_or ( 0 ) )
109
- . unwrap_or ( 0 ) ;
110
-
111
- let end = code. find ( "#LCEND" ) . unwrap_or ( code. len ( ) ) ;
112
- if let Some ( problem) = code. find ( "leetcode.com/problems/" ) {
113
- let problem = ( & code[ problem..] ) . split_whitespace ( ) . next ( ) . unwrap ( ) ;
114
- let problem = problem. split ( '/' ) . into_iter ( ) . rev ( ) . skip ( 1 ) . next ( ) . unwrap ( ) ;
115
- let question_title = problem. to_string ( ) ;
116
- Self {
117
- language,
118
- path : std:: path:: PathBuf :: from ( path) ,
119
- question_title,
120
- code : code[ start..end] . to_string ( ) ,
121
- }
122
- } else {
123
- println ! ( "No leetcode problem found in the code file. Please add the problem link in the code file using comments." ) ;
124
- // terminate with error
125
- std:: process:: exit ( 1 ) ;
126
- }
109
+ . expect ( & format ! ( "Failed to read file {}" , path. display( ) ) ) ;
110
+ let ( question_title, parsed_code) = Self :: parse_code ( & code) ;
111
+ valid_file. question_title = question_title;
112
+ valid_file. code = parsed_code;
113
+ valid_file
127
114
}
128
- }
115
+ }
0 commit comments