Skip to content

Commit 7b772dd

Browse files
authored
Merge pull request #24 from coding-kelps/16-add-default_language-re-prompt-if-not-found-for-a-given-problem
16 add default language re prompt if not found for a given problem
2 parents b084d31 + 96a34c5 commit 7b772dd

3 files changed

Lines changed: 88 additions & 12 deletions

File tree

src/leetcode_api_runner.rs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,22 @@ pub struct LeetcodeApiRunner {
2323
}
2424

2525
impl LeetcodeApiRunner {
26-
pub async fn new(rcs: &RuntimeConfigSetup) -> Self {
27-
let api = UserApi::new(&rcs.config.leetcode_token).await.unwrap();
28-
LeetcodeApiRunner {
26+
pub async fn new(rcs: &RuntimeConfigSetup) -> Result<Self, io::Error> {
27+
Ok(LeetcodeApiRunner {
2928
rcs: rcs.clone(),
30-
api,
31-
}
29+
api: UserApi::new(&rcs.config.leetcode_token).await.map_err(
30+
|_| {
31+
io::Error::new(
32+
io::ErrorKind::NotConnected,
33+
format!(
34+
"An error occurred while creating the API client. \
35+
Check your token in your configuration file: {}",
36+
rcs.config_file.display()
37+
),
38+
)
39+
},
40+
)?,
41+
})
3242
}
3343

3444
pub async fn get_problem_info(&self, id: u32) -> io::Result<String> {
@@ -46,6 +56,26 @@ impl LeetcodeApiRunner {
4656
Ok(format!("{} {}: {}\n{}", id, difficulty, title, description))
4757
}
4858

59+
/// Fetches the problem name by its ID.
60+
pub async fn get_problem_name(&self, id: u32) -> io::Result<String> {
61+
let pb = self.api.set_problem_by_id(id).await.unwrap();
62+
Ok(pb.description().unwrap().name.clone())
63+
}
64+
65+
/// Fetches the available languages for a given problem ID.
66+
pub async fn get_available_languages(
67+
&self, id: &u32,
68+
) -> io::Result<Vec<String>> {
69+
let problem = self.api.set_problem_by_id(*id).await?;
70+
71+
Ok(problem
72+
.code_snippets()
73+
.expect("No code snippets found.")
74+
.iter()
75+
.map(|snippet| snippet.langSlug.clone())
76+
.collect::<Vec<_>>())
77+
}
78+
4979
pub async fn start_problem(
5080
&self, id: u32, language: ProgrammingLanguage,
5181
) -> io::Result<String> {

src/main.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use clap::Parser;
22
use leetcode_cli::{
33
utils::{
44
parse_programming_language,
5+
prompt_for_language,
56
spin_the_spinner,
67
},
78
Cli,
@@ -15,7 +16,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
1516
let cli = Cli::parse();
1617
let mut rcs = RuntimeConfigSetup::new();
1718
rcs.status()?;
18-
let api_runner = LeetcodeApiRunner::new(&rcs).await;
19+
let api_runner = LeetcodeApiRunner::new(&rcs).await?;
1920

2021
match &cli.command {
2122
Commands::Info {
@@ -33,11 +34,29 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
3334
id,
3435
language,
3536
} => {
36-
let default = &rcs.config.default_language.unwrap();
37-
let lang = match language {
38-
Some(lang) => parse_programming_language(lang)?,
39-
None => parse_programming_language(default)?,
37+
let default_lang = rcs
38+
.config
39+
.default_language
40+
.clone()
41+
.unwrap_or_else(|| "not found".to_string());
42+
let mut lang = match language {
43+
Some(lang) => parse_programming_language(lang),
44+
None => parse_programming_language(&default_lang),
4045
};
46+
let mut spin = spin_the_spinner("Gathering problem info...");
47+
let problem_name = api_runner.get_problem_name(*id).await?;
48+
let available_languages =
49+
api_runner.get_available_languages(&id).await?;
50+
spin.stop();
51+
while lang.is_err() {
52+
lang = prompt_for_language(
53+
id,
54+
&problem_name,
55+
&available_languages,
56+
)
57+
.and_then(|lang| parse_programming_language(&lang));
58+
}
59+
let lang = lang.unwrap();
4160
let mut spin = spin_the_spinner("Starting problem setup...");
4261
let start_problem = api_runner.start_problem(*id, lang).await;
4362
spin.stop();

src/utils.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn write_to_file(
3434

3535
pub fn parse_programming_language(
3636
lang: &str,
37-
) -> Result<leetcoderustapi::ProgrammingLanguage, String> {
37+
) -> Result<leetcoderustapi::ProgrammingLanguage, std::io::Error> {
3838
match lang.to_ascii_lowercase().as_str() {
3939
"cpp" | "c++" => Ok(leetcoderustapi::ProgrammingLanguage::CPP),
4040
"java" => Ok(leetcoderustapi::ProgrammingLanguage::Java),
@@ -62,7 +62,10 @@ pub fn parse_programming_language(
6262
"dart" => Ok(leetcoderustapi::ProgrammingLanguage::Dart),
6363
"pandas" => Ok(leetcoderustapi::ProgrammingLanguage::Pandas),
6464
"react" => Ok(leetcoderustapi::ProgrammingLanguage::React),
65-
_ => Err(format!("Unsupported language: {}", lang)),
65+
_ => Err(io::Error::new(
66+
io::ErrorKind::InvalidInput,
67+
format!("Unsupported language: {}", lang),
68+
)),
6669
}
6770
}
6871

@@ -159,3 +162,27 @@ pub fn extension_programming_language(
159162
pub fn spin_the_spinner(message: &str) -> spinners::Spinner {
160163
spinners::Spinner::new(spinners::Spinners::Dots12, message.to_string())
161164
}
165+
166+
pub fn prompt_for_language(
167+
id: &u32, problem_name: &str, available_languages: &[String],
168+
) -> Result<String, io::Error> {
169+
println!(
170+
"\nPlease enter a valid Leetcode programming language.\nHere is a \
171+
list of available languages for the problem {} - {}\n{}",
172+
id,
173+
problem_name,
174+
available_languages
175+
.iter()
176+
.map(|l| l.to_string())
177+
.collect::<Vec<_>>()
178+
.join(", ")
179+
);
180+
let mut input = String::new();
181+
io::stdin().read_line(&mut input)?;
182+
let trimmed = input.trim().to_string();
183+
if trimmed.is_empty() {
184+
Err(io::Error::new(io::ErrorKind::InvalidInput, "No language entered"))
185+
} else {
186+
Ok(trimmed)
187+
}
188+
}

0 commit comments

Comments
 (0)