1+ use crate :: args:: Cli ;
12use crate :: file_parser:: codefile:: CodeFile ;
23use crate :: handlers:: html_opener:: open_html;
34use crate :: utils:: { execute_testcases, submit} ;
4- use clap:: { Parser , Subcommand } ;
5+
6+ use args:: Commands ;
7+ use clap:: Parser ;
58use colored:: Colorize ;
69use handlers:: leetcode:: LeetCode ;
10+
711use std:: process:: ExitCode ;
812
13+ mod args;
914mod file_parser;
1015mod handlers;
1116mod utils;
1217
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-
7218fn main ( ) -> ExitCode {
7319 let cli = Cli :: parse ( ) ;
7420
@@ -85,77 +31,34 @@ fn main() -> ExitCode {
8531 let lc = LeetCode :: new ( ) ;
8632 let lc = lc. authenticate ( cookie) . unwrap ( ) ;
8733
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
14145 }
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) ;
15255 if question. is_ok ( ) {
15356 let question = question. unwrap ( ) ;
154- let filename = format ! ( "{}.html" , question_name) ;
15557 // 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 ) {
15760 println ! ( "Saved question as HTML to {}" , filename. cyan( ) ) ;
158- open_html ( & filename) ;
61+ open_html ( filename) ;
15962 ExitCode :: SUCCESS
16063 } else {
16164 eprintln ! ( "Error saving question as HTML" ) ;
@@ -165,47 +68,80 @@ fn main() -> ExitCode {
16568 eprintln ! ( "Error getting question content : {}" , question. unwrap_err( ) ) ;
16669 ExitCode :: FAILURE
16770 }
71+ } else {
72+ eprintln ! (
73+ "Error getting daily challenge : {}" ,
74+ daily_challenge. unwrap_err( )
75+ ) ;
76+ ExitCode :: FAILURE
16877 }
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) ;
17495 ExitCode :: SUCCESS
17596 } else {
97+ eprintln ! ( "Error saving question as HTML" ) ;
17698 ExitCode :: FAILURE
17799 }
100+ } else {
101+ eprintln ! ( "Error getting question content : {}" , question. unwrap_err( ) ) ;
102+ ExitCode :: FAILURE
178103 }
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
185113 }
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+ } ;
192128
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 {
193142 submit ( & lc, code_file)
194143 }
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- }
209144 }
145+ None => ExitCode :: SUCCESS ,
210146 }
211147}
0 commit comments