From ebd8f45653cb72f343b21aa52ec57ca85f50f3d8 Mon Sep 17 00:00:00 2001 From: nozwock <57829219+nozwock@users.noreply.github.com> Date: Sun, 4 Jun 2023 01:47:57 +0530 Subject: [PATCH 1/2] Use `visible_alias` instead of hardcoding them in docstrings --- src/main.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index acff0aa..ff016ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,47 +20,47 @@ struct Cli { #[derive(Subcommand)] enum Commands { - /// Authenticate with LeetCode [ -a ] - #[command(alias = "-a")] + /// Authenticate with LeetCode + #[command(visible_alias = "-a")] Auth, - /// Executes code with testcases [ -r ] - #[command(alias = "-rt")] + /// Executes code with testcases + #[command(visible_alias = "-rt")] RunCustom { /// Testcases to run testcases: String, /// File to execute filename: Option, }, - #[command(alias = "-r")] + #[command(visible_alias = "-r")] Run { /// File to execute with default testcases filename: Option, }, - /// Submits code to LeetCode [ -s ] - #[command(alias = "-fs")] + /// Submits code to LeetCode + #[command(visible_alias = "-fs")] FastSubmit { /// File to submit filename: Option, }, - #[command(alias = "-s")] + #[command(visible_alias = "-s")] Submit { /// File to submit filename: Option, }, - /// Save a question as HTML [ -q ] - #[command(alias = "-q")] + /// Save a question as HTML + #[command(visible_alias = "-q")] Question { /// Question name question_name: String, }, - /// Save today's daily challenge as HTML [ -d ] - #[command(alias = "-d")] + /// Save today's daily challenge as HTML + #[command(visible_alias = "-d")] DailyChallenge, } #[derive(Subcommand)] enum Execute { - #[command(alias = "-t")] + #[command(visible_alias = "-t")] Testcases { /// File to run filename: Option, From 7478b9634ca0ecb58130bd15dd4e958421b5c6e6 Mon Sep 17 00:00:00 2001 From: nozwock <57829219+nozwock@users.noreply.github.com> Date: Sun, 4 Jun 2023 02:00:29 +0530 Subject: [PATCH 2/2] Seperate out args parser code from `main.rs` And replace manual help message with `arg_required_else_help`. --- src/args.rs | 60 +++++++++++++ src/main.rs | 250 +++++++++++++++++++--------------------------------- 2 files changed, 153 insertions(+), 157 deletions(-) create mode 100644 src/args.rs diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..eeeb82a --- /dev/null +++ b/src/args.rs @@ -0,0 +1,60 @@ +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +#[command(version, arg_required_else_help = true)] +#[command(propagate_version = true)] +pub struct Cli { + #[command(subcommand)] + pub command: Option, +} + +#[derive(Subcommand)] +pub enum Commands { + /// Authenticate with LeetCode + #[command(visible_alias = "-a")] + Auth, + /// Executes code with testcases + #[command(visible_alias = "-rt")] + RunCustom { + /// Testcases to run + testcases: String, + /// File to execute + filename: Option, + }, + #[command(visible_alias = "-r")] + Run { + /// File to execute with default testcases + filename: Option, + }, + /// Submits code to LeetCode + #[command(visible_alias = "-fs")] + FastSubmit { + /// File to submit + filename: Option, + }, + #[command(visible_alias = "-s")] + Submit { + /// File to submit + filename: Option, + }, + /// Save a question as HTML + #[command(visible_alias = "-q")] + Question { + /// Question name + question_name: String, + }, + /// Save today's daily challenge as HTML + #[command(visible_alias = "-d")] + DailyChallenge, +} + +#[derive(Subcommand)] +pub enum Execute { + #[command(visible_alias = "-t")] + Testcases { + /// File to run + filename: Option, + /// Testcases to run + testcases: Option, + }, +} diff --git a/src/main.rs b/src/main.rs index ff016ef..c0ede59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,74 +1,20 @@ +use crate::args::Cli; use crate::file_parser::codefile::CodeFile; use crate::handlers::html_opener::open_html; use crate::utils::{execute_testcases, submit}; -use clap::{Parser, Subcommand}; + +use args::Commands; +use clap::Parser; use colored::Colorize; use handlers::leetcode::LeetCode; + use std::process::ExitCode; +mod args; mod file_parser; mod handlers; mod utils; -#[derive(Parser)] -#[command(version)] -#[command(propagate_version = true)] -struct Cli { - #[command(subcommand)] - command: Option, -} - -#[derive(Subcommand)] -enum Commands { - /// Authenticate with LeetCode - #[command(visible_alias = "-a")] - Auth, - /// Executes code with testcases - #[command(visible_alias = "-rt")] - RunCustom { - /// Testcases to run - testcases: String, - /// File to execute - filename: Option, - }, - #[command(visible_alias = "-r")] - Run { - /// File to execute with default testcases - filename: Option, - }, - /// Submits code to LeetCode - #[command(visible_alias = "-fs")] - FastSubmit { - /// File to submit - filename: Option, - }, - #[command(visible_alias = "-s")] - Submit { - /// File to submit - filename: Option, - }, - /// Save a question as HTML - #[command(visible_alias = "-q")] - Question { - /// Question name - question_name: String, - }, - /// Save today's daily challenge as HTML - #[command(visible_alias = "-d")] - DailyChallenge, -} - -#[derive(Subcommand)] -enum Execute { - #[command(visible_alias = "-t")] - Testcases { - /// File to run - filename: Option, - /// Testcases to run - testcases: Option, - }, -} - fn main() -> ExitCode { let cli = Cli::parse(); @@ -85,77 +31,34 @@ fn main() -> ExitCode { let lc = LeetCode::new(); let lc = lc.authenticate(cookie).unwrap(); - if let None = cli.command { - println!( - "🪛 {}\nExecute and submit code on LeetCode directly from your terminal!\n\nUsage : {}", - "Leetcode Runner CLI Tool".bold().yellow(), - "leetcode-runner-cli -h".cyan().italic() - ); - ExitCode::SUCCESS - } else { - let cli = cli.command.unwrap(); - match cli { - Commands::Auth => { - let metadata = lc.get_metadata(); - if metadata.is_ok() { - println!("Authenticated successfully!\n"); - metadata.unwrap().display(); - ExitCode::SUCCESS - } else { - let error = metadata.unwrap_err(); - eprintln!("Authentication Error : {}", error); - ExitCode::FAILURE - } - } - Commands::DailyChallenge => { - let daily_challenge = lc.get_daily_challenge(); - if daily_challenge.is_ok() { - let daily_challenge = daily_challenge.unwrap(); - println!("Today's Daily Challenge :"); - println!("{}", &daily_challenge); - let title = daily_challenge.question.titleSlug; - let question = lc.question_content(&title); - if question.is_ok() { - let question = question.unwrap(); - // save to filename - let filename = "daily_challenge.html"; - if let Ok(_) = std::fs::write(filename, question.content) { - println!("Saved question as HTML to {}", filename.cyan()); - open_html(filename); - ExitCode::SUCCESS - } else { - eprintln!("Error saving question as HTML"); - ExitCode::FAILURE - } - } else { - eprintln!("Error getting question content : {}", question.unwrap_err()); - ExitCode::FAILURE - } - } else { - eprintln!( - "Error getting daily challenge : {}", - daily_challenge.unwrap_err() - ); - ExitCode::FAILURE - } + match cli.command { + Some(Commands::Auth) => { + let metadata = lc.get_metadata(); + if metadata.is_ok() { + println!("Authenticated successfully!\n"); + metadata.unwrap().display(); + ExitCode::SUCCESS + } else { + let error = metadata.unwrap_err(); + eprintln!("Authentication Error : {}", error); + ExitCode::FAILURE } - Commands::Question { question_name } => { - let question_name = if let Some(idx) = question_name.find("leetcode.com/problems/") - { - let problem = (&question_name[idx..]).split_whitespace().next().unwrap(); - let problem = problem.split('/').skip(2).next().unwrap(); - problem - } else { - &question_name - }; - let question = lc.question_content(question_name); + } + Some(Commands::DailyChallenge) => { + let daily_challenge = lc.get_daily_challenge(); + if daily_challenge.is_ok() { + let daily_challenge = daily_challenge.unwrap(); + println!("Today's Daily Challenge :"); + println!("{}", &daily_challenge); + let title = daily_challenge.question.titleSlug; + let question = lc.question_content(&title); if question.is_ok() { let question = question.unwrap(); - let filename = format!("{}.html", question_name); // save to filename - if let Ok(_) = std::fs::write(&filename, question.content) { + let filename = "daily_challenge.html"; + if let Ok(_) = std::fs::write(filename, question.content) { println!("Saved question as HTML to {}", filename.cyan()); - open_html(&filename); + open_html(filename); ExitCode::SUCCESS } else { eprintln!("Error saving question as HTML"); @@ -165,47 +68,80 @@ fn main() -> ExitCode { eprintln!("Error getting question content : {}", question.unwrap_err()); ExitCode::FAILURE } + } else { + eprintln!( + "Error getting daily challenge : {}", + daily_challenge.unwrap_err() + ); + ExitCode::FAILURE } - Commands::RunCustom { - testcases, - filename, - } => { - if execute_testcases(filename, Some(testcases), &lc).0 { + } + Some(Commands::Question { question_name }) => { + let question_name = if let Some(idx) = question_name.find("leetcode.com/problems/") { + let problem = (&question_name[idx..]).split_whitespace().next().unwrap(); + let problem = problem.split('/').skip(2).next().unwrap(); + problem + } else { + &question_name + }; + let question = lc.question_content(question_name); + if question.is_ok() { + let question = question.unwrap(); + let filename = format!("{}.html", question_name); + // save to filename + if let Ok(_) = std::fs::write(&filename, question.content) { + println!("Saved question as HTML to {}", filename.cyan()); + open_html(&filename); ExitCode::SUCCESS } else { + eprintln!("Error saving question as HTML"); ExitCode::FAILURE } + } else { + eprintln!("Error getting question content : {}", question.unwrap_err()); + ExitCode::FAILURE } - Commands::Run { filename } => { - if execute_testcases(filename, None, &lc).0 { - ExitCode::SUCCESS - } else { - ExitCode::FAILURE - } + } + Some(Commands::RunCustom { + testcases, + filename, + }) => { + if execute_testcases(filename, Some(testcases), &lc).0 { + ExitCode::SUCCESS + } else { + ExitCode::FAILURE } - Commands::FastSubmit { filename } => { - let code_file = if filename.is_some() { - CodeFile::from_file(&filename.unwrap()) - } else { - CodeFile::from_dir() - }; + } + Some(Commands::Run { filename }) => { + if execute_testcases(filename, None, &lc).0 { + ExitCode::SUCCESS + } else { + ExitCode::FAILURE + } + } + Some(Commands::FastSubmit { filename }) => { + let code_file = if filename.is_some() { + CodeFile::from_file(&filename.unwrap()) + } else { + CodeFile::from_dir() + }; + submit(&lc, code_file) + } + Some(Commands::Submit { filename }) => { + let (testcase_result, code_file) = execute_testcases(filename, None, &lc); + if !testcase_result { + println!( + "{}", + "Aborting submission due to failed testcase(s)!" + .red() + .bold() + ); + ExitCode::FAILURE + } else { submit(&lc, code_file) } - Commands::Submit { filename } => { - let (testcase_result, code_file) = execute_testcases(filename, None, &lc); - if !testcase_result { - println!( - "{}", - "Aborting submission due to failed testcase(s)!" - .red() - .bold() - ); - ExitCode::FAILURE - } else { - submit(&lc, code_file) - } - } } + None => ExitCode::SUCCESS, } }