1
+ use crate :: args:: Cli ;
1
2
use crate :: file_parser:: codefile:: CodeFile ;
2
3
use crate :: handlers:: html_opener:: open_html;
3
4
use crate :: utils:: { execute_testcases, submit} ;
4
- use clap:: { Parser , Subcommand } ;
5
+
6
+ use args:: Commands ;
7
+ use clap:: Parser ;
5
8
use colored:: Colorize ;
6
9
use handlers:: leetcode:: LeetCode ;
10
+
7
11
use std:: process:: ExitCode ;
8
12
13
+ mod args;
9
14
mod file_parser;
10
15
mod handlers;
11
16
mod utils;
12
17
13
- #[ derive( Parser ) ]
14
- #[ command( version) ]
15
- #[ command( propagate_version = true ) ]
16
- struct Cli {
17
- #[ command( subcommand) ]
18
- command : Option < Commands > ,
19
- }
20
-
21
- #[ derive( Subcommand ) ]
22
- enum Commands {
23
- /// Authenticate with LeetCode
24
- #[ command( visible_alias = "-a" ) ]
25
- Auth ,
26
- /// Executes code with testcases
27
- #[ command( visible_alias = "-rt" ) ]
28
- RunCustom {
29
- /// Testcases to run
30
- testcases : String ,
31
- /// File to execute
32
- filename : Option < String > ,
33
- } ,
34
- #[ command( visible_alias = "-r" ) ]
35
- Run {
36
- /// File to execute with default testcases
37
- filename : Option < String > ,
38
- } ,
39
- /// Submits code to LeetCode
40
- #[ command( visible_alias = "-fs" ) ]
41
- FastSubmit {
42
- /// File to submit
43
- filename : Option < String > ,
44
- } ,
45
- #[ command( visible_alias = "-s" ) ]
46
- Submit {
47
- /// File to submit
48
- filename : Option < String > ,
49
- } ,
50
- /// Save a question as HTML
51
- #[ command( visible_alias = "-q" ) ]
52
- Question {
53
- /// Question name
54
- question_name : String ,
55
- } ,
56
- /// Save today's daily challenge as HTML
57
- #[ command( visible_alias = "-d" ) ]
58
- DailyChallenge ,
59
- }
60
-
61
- #[ derive( Subcommand ) ]
62
- enum Execute {
63
- #[ command( visible_alias = "-t" ) ]
64
- Testcases {
65
- /// File to run
66
- filename : Option < String > ,
67
- /// Testcases to run
68
- testcases : Option < String > ,
69
- } ,
70
- }
71
-
72
18
fn main ( ) -> ExitCode {
73
19
let cli = Cli :: parse ( ) ;
74
20
@@ -85,77 +31,34 @@ fn main() -> ExitCode {
85
31
let lc = LeetCode :: new ( ) ;
86
32
let lc = lc. authenticate ( cookie) . unwrap ( ) ;
87
33
88
- if let None = cli. command {
89
- println ! (
90
- "🪛 {}\n Execute and submit code on LeetCode directly from your terminal!\n \n Usage : {}" ,
91
- "Leetcode Runner CLI Tool" . bold( ) . yellow( ) ,
92
- "leetcode-runner-cli -h" . cyan( ) . italic( )
93
- ) ;
94
- ExitCode :: SUCCESS
95
- } else {
96
- let cli = cli. command . unwrap ( ) ;
97
- match cli {
98
- Commands :: Auth => {
99
- let metadata = lc. get_metadata ( ) ;
100
- if metadata. is_ok ( ) {
101
- println ! ( "Authenticated successfully!\n " ) ;
102
- metadata. unwrap ( ) . display ( ) ;
103
- ExitCode :: SUCCESS
104
- } else {
105
- let error = metadata. unwrap_err ( ) ;
106
- eprintln ! ( "Authentication Error : {}" , error) ;
107
- ExitCode :: FAILURE
108
- }
109
- }
110
- Commands :: DailyChallenge => {
111
- let daily_challenge = lc. get_daily_challenge ( ) ;
112
- if daily_challenge. is_ok ( ) {
113
- let daily_challenge = daily_challenge. unwrap ( ) ;
114
- println ! ( "Today's Daily Challenge :" ) ;
115
- println ! ( "{}" , & daily_challenge) ;
116
- let title = daily_challenge. question . titleSlug ;
117
- let question = lc. question_content ( & title) ;
118
- if question. is_ok ( ) {
119
- let question = question. unwrap ( ) ;
120
- // save to filename
121
- let filename = "daily_challenge.html" ;
122
- if let Ok ( _) = std:: fs:: write ( filename, question. content ) {
123
- println ! ( "Saved question as HTML to {}" , filename. cyan( ) ) ;
124
- open_html ( filename) ;
125
- ExitCode :: SUCCESS
126
- } else {
127
- eprintln ! ( "Error saving question as HTML" ) ;
128
- ExitCode :: FAILURE
129
- }
130
- } else {
131
- eprintln ! ( "Error getting question content : {}" , question. unwrap_err( ) ) ;
132
- ExitCode :: FAILURE
133
- }
134
- } else {
135
- eprintln ! (
136
- "Error getting daily challenge : {}" ,
137
- daily_challenge. unwrap_err( )
138
- ) ;
139
- ExitCode :: FAILURE
140
- }
34
+ match cli. command {
35
+ Some ( Commands :: Auth ) => {
36
+ let metadata = lc. get_metadata ( ) ;
37
+ if metadata. is_ok ( ) {
38
+ println ! ( "Authenticated successfully!\n " ) ;
39
+ metadata. unwrap ( ) . display ( ) ;
40
+ ExitCode :: SUCCESS
41
+ } else {
42
+ let error = metadata. unwrap_err ( ) ;
43
+ eprintln ! ( "Authentication Error : {}" , error) ;
44
+ ExitCode :: FAILURE
141
45
}
142
- Commands :: Question { question_name } => {
143
- let question_name = if let Some ( idx) = question_name. find ( "leetcode.com/problems/" )
144
- {
145
- let problem = ( & question_name[ idx..] ) . split_whitespace ( ) . next ( ) . unwrap ( ) ;
146
- let problem = problem. split ( '/' ) . skip ( 2 ) . next ( ) . unwrap ( ) ;
147
- problem
148
- } else {
149
- & question_name
150
- } ;
151
- let question = lc. question_content ( question_name) ;
46
+ }
47
+ Some ( Commands :: DailyChallenge ) => {
48
+ let daily_challenge = lc. get_daily_challenge ( ) ;
49
+ if daily_challenge. is_ok ( ) {
50
+ let daily_challenge = daily_challenge. unwrap ( ) ;
51
+ println ! ( "Today's Daily Challenge :" ) ;
52
+ println ! ( "{}" , & daily_challenge) ;
53
+ let title = daily_challenge. question . titleSlug ;
54
+ let question = lc. question_content ( & title) ;
152
55
if question. is_ok ( ) {
153
56
let question = question. unwrap ( ) ;
154
- let filename = format ! ( "{}.html" , question_name) ;
155
57
// save to filename
156
- if let Ok ( _) = std:: fs:: write ( & filename, question. content ) {
58
+ let filename = "daily_challenge.html" ;
59
+ if let Ok ( _) = std:: fs:: write ( filename, question. content ) {
157
60
println ! ( "Saved question as HTML to {}" , filename. cyan( ) ) ;
158
- open_html ( & filename) ;
61
+ open_html ( filename) ;
159
62
ExitCode :: SUCCESS
160
63
} else {
161
64
eprintln ! ( "Error saving question as HTML" ) ;
@@ -165,47 +68,80 @@ fn main() -> ExitCode {
165
68
eprintln ! ( "Error getting question content : {}" , question. unwrap_err( ) ) ;
166
69
ExitCode :: FAILURE
167
70
}
71
+ } else {
72
+ eprintln ! (
73
+ "Error getting daily challenge : {}" ,
74
+ daily_challenge. unwrap_err( )
75
+ ) ;
76
+ ExitCode :: FAILURE
168
77
}
169
- Commands :: RunCustom {
170
- testcases,
171
- filename,
172
- } => {
173
- if execute_testcases ( filename, Some ( testcases) , & lc) . 0 {
78
+ }
79
+ Some ( Commands :: Question { question_name } ) => {
80
+ let question_name = if let Some ( idx) = question_name. find ( "leetcode.com/problems/" ) {
81
+ let problem = ( & question_name[ idx..] ) . split_whitespace ( ) . next ( ) . unwrap ( ) ;
82
+ let problem = problem. split ( '/' ) . skip ( 2 ) . next ( ) . unwrap ( ) ;
83
+ problem
84
+ } else {
85
+ & question_name
86
+ } ;
87
+ let question = lc. question_content ( question_name) ;
88
+ if question. is_ok ( ) {
89
+ let question = question. unwrap ( ) ;
90
+ let filename = format ! ( "{}.html" , question_name) ;
91
+ // save to filename
92
+ if let Ok ( _) = std:: fs:: write ( & filename, question. content ) {
93
+ println ! ( "Saved question as HTML to {}" , filename. cyan( ) ) ;
94
+ open_html ( & filename) ;
174
95
ExitCode :: SUCCESS
175
96
} else {
97
+ eprintln ! ( "Error saving question as HTML" ) ;
176
98
ExitCode :: FAILURE
177
99
}
100
+ } else {
101
+ eprintln ! ( "Error getting question content : {}" , question. unwrap_err( ) ) ;
102
+ ExitCode :: FAILURE
178
103
}
179
- Commands :: Run { filename } => {
180
- if execute_testcases ( filename, None , & lc) . 0 {
181
- ExitCode :: SUCCESS
182
- } else {
183
- ExitCode :: FAILURE
184
- }
104
+ }
105
+ Some ( Commands :: RunCustom {
106
+ testcases,
107
+ filename,
108
+ } ) => {
109
+ if execute_testcases ( filename, Some ( testcases) , & lc) . 0 {
110
+ ExitCode :: SUCCESS
111
+ } else {
112
+ ExitCode :: FAILURE
185
113
}
186
- Commands :: FastSubmit { filename } => {
187
- let code_file = if filename. is_some ( ) {
188
- CodeFile :: from_file ( & filename. unwrap ( ) )
189
- } else {
190
- CodeFile :: from_dir ( )
191
- } ;
114
+ }
115
+ Some ( Commands :: Run { filename } ) => {
116
+ if execute_testcases ( filename, None , & lc) . 0 {
117
+ ExitCode :: SUCCESS
118
+ } else {
119
+ ExitCode :: FAILURE
120
+ }
121
+ }
122
+ Some ( Commands :: FastSubmit { filename } ) => {
123
+ let code_file = if filename. is_some ( ) {
124
+ CodeFile :: from_file ( & filename. unwrap ( ) )
125
+ } else {
126
+ CodeFile :: from_dir ( )
127
+ } ;
192
128
129
+ submit ( & lc, code_file)
130
+ }
131
+ Some ( Commands :: Submit { filename } ) => {
132
+ let ( testcase_result, code_file) = execute_testcases ( filename, None , & lc) ;
133
+ if !testcase_result {
134
+ println ! (
135
+ "{}" ,
136
+ "Aborting submission due to failed testcase(s)!"
137
+ . red( )
138
+ . bold( )
139
+ ) ;
140
+ ExitCode :: FAILURE
141
+ } else {
193
142
submit ( & lc, code_file)
194
143
}
195
- Commands :: Submit { filename } => {
196
- let ( testcase_result, code_file) = execute_testcases ( filename, None , & lc) ;
197
- if !testcase_result {
198
- println ! (
199
- "{}" ,
200
- "Aborting submission due to failed testcase(s)!"
201
- . red( )
202
- . bold( )
203
- ) ;
204
- ExitCode :: FAILURE
205
- } else {
206
- submit ( & lc, code_file)
207
- }
208
- }
209
144
}
145
+ None => ExitCode :: SUCCESS ,
210
146
}
211
147
}
0 commit comments