Skip to content

Commit 159139e

Browse files
authored
Merge pull request #1 from VivekYadav7272/main
Changed the project structure a little to reflect the code composition and also modified the file selection to be saner
2 parents 4f097e4 + 541d77b commit 159139e

File tree

6 files changed

+223
-164
lines changed

6 files changed

+223
-164
lines changed

src/codefile.rs

Lines changed: 0 additions & 160 deletions
This file was deleted.

src/file_parser/codefile.rs

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
use std::io::{Read, Write};
2+
use super::language::*;
3+
4+
pub struct CodeFile {
5+
pub language: Language,
6+
pub path: std::path::PathBuf,
7+
pub question_title: String,
8+
pub code: String,
9+
}
10+
11+
impl CodeFile {
12+
pub fn from_dir() -> Self {
13+
let mut code_file: Option<CodeFile> = None;
14+
let files = std::fs::read_dir("./").unwrap();
15+
for file in files {
16+
let Ok(file) = file else {
17+
// Bad path
18+
continue
19+
};
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+
};
33+
34+
code_file = Some(
35+
CodeFile {
36+
language, path: path.clone(), question_title: String::new(), code: String::new()
37+
}
38+
);
39+
40+
if file_name.starts_with("main") {
41+
break;
42+
}
43+
}
44+
let mut code_file = code_file.unwrap_or_else(|| {
45+
let default_code_file = CodeFile {
46+
language: Language::Rust,
47+
path: std::path::PathBuf::from("main.rs"),
48+
question_title: String::new(),
49+
code: String::new(),
50+
};
51+
println!(
52+
"No code file found. Creating a new file named {}",
53+
default_code_file.path.display()
54+
);
55+
let mut file =
56+
std::fs::File::create(&default_code_file.path).expect("Error during file creation");
57+
let two_sum_problem = b"struct Solution;\n\n// https://leetcode.com/problems/two-sum/ #LCSTART\n\nimpl Solution {\n\tpub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {\n\n\t}\n} // #LCEND\nfn main() {}";
58+
file.write_all(two_sum_problem).expect("File write failed");
59+
60+
default_code_file
61+
});
62+
let mut file = std::fs::File::open(&code_file.path).unwrap();
63+
let mut code = String::new();
64+
file.read_to_string(&mut code).expect(&format!(
65+
"Failed to read file {}",
66+
code_file.path.display()
67+
));
68+
let start = code
69+
.find("#LCSTART")
70+
.map(|idx| idx +
71+
// This returning None the user
72+
// wants to submit a practically empty file,
73+
// but hey we don't judge!
74+
code[idx..].find('\n').unwrap_or(0))
75+
.unwrap_or(0);
76+
77+
let end = code.find("#LCEND").unwrap_or(code.len());
78+
if let Some(problem) = code.find("leetcode.com/problems/") {
79+
let problem = (&code[problem..]).split_whitespace().next().unwrap();
80+
let problem = problem.split('/').skip(2).next().unwrap();
81+
code_file.question_title = problem.to_string();
82+
} else {
83+
println!("No leetcode problem found in the code file. Please add the problem link in the code file using comments.");
84+
// terminate with error
85+
std::process::exit(1);
86+
}
87+
code_file.code = code[start..end].to_string();
88+
code_file
89+
}
90+
91+
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");
94+
let file = std::fs::File::open(&path);
95+
let Ok(mut file) = file else{
96+
println!("Error while opening file {}", &path );
97+
std::process::exit(1);
98+
};
99+
let mut code = String::new();
100+
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+
}
127+
}
128+
}
129+
130+
131+
#[derive(Default)]
132+
struct CodeFileBuilder {
133+
language: Option<Language>,
134+
path: Option<std::path::PathBuf>,
135+
question_title: Option<String>,
136+
code: Option<String>,
137+
}
138+
139+
impl CodeFileBuilder {
140+
pub fn new() -> Self {
141+
Default::default()
142+
}
143+
144+
pub fn build(self) -> CodeFile {
145+
CodeFile {
146+
language: self.language.unwrap_or(Language::Rust),
147+
path: self.path.unwrap_or_else(|| std::path::PathBuf::from("main.rs")),
148+
question_title: self.question_title.unwrap_or_else(|| String::new()),
149+
code: self.code.unwrap_or_else(|| String::new()),
150+
}
151+
}
152+
153+
pub fn set_language(mut self, language: Language) -> Self {
154+
self.language = Some(language);
155+
self
156+
}
157+
158+
pub fn set_path(mut self, path: std::path::PathBuf) -> Self {
159+
self.path = Some(path);
160+
self
161+
}
162+
163+
pub fn set_question_title(mut self, question_title: String) -> Self {
164+
self.question_title = Some(question_title);
165+
self
166+
}
167+
168+
pub fn set_code(mut self, code: String) -> Self {
169+
self.code = Some(code);
170+
self
171+
}
172+
}

src/file_parser/language.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
pub enum Language {
2+
Rust,
3+
Python3,
4+
Cpp,
5+
Java,
6+
C,
7+
Javascript,
8+
Go,
9+
Kotlin,
10+
Swift,
11+
Typescript,
12+
}
13+
impl Language {
14+
pub fn from_str(input: &str) -> Option<Language> {
15+
match input {
16+
"rs" => Some(Language::Rust),
17+
"py" => Some(Language::Python3),
18+
"cpp" => Some(Language::Cpp),
19+
"java" => Some(Language::Java),
20+
"c" => Some(Language::C),
21+
"js" => Some(Language::Javascript),
22+
"go" => Some(Language::Go),
23+
"kt" => Some(Language::Kotlin),
24+
"swift" => Some(Language::Swift),
25+
"ts" => Some(Language::Typescript),
26+
_ => None,
27+
}
28+
}
29+
pub fn to_str(&self) -> &str {
30+
match self {
31+
Language::Rust => "rust",
32+
Language::Python3 => "python3",
33+
Language::Cpp => "cpp",
34+
Language::Java => "java",
35+
Language::C => "c",
36+
Language::Javascript => "javascript",
37+
Language::Go => "golang",
38+
Language::Kotlin => "kotlin",
39+
Language::Swift => "swift",
40+
Language::Typescript => "typescript",
41+
}
42+
}
43+
pub fn to_string(&self) -> String {
44+
self.to_str().to_string()
45+
}
46+
}

src/file_parser/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod codefile;
2+
mod language;

src/leetcode.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::codefile::CodeFile;
1+
use crate::file_parser::codefile::CodeFile;
22
use colored::Colorize;
33
use serde::{Deserialize, Serialize};
44

@@ -141,7 +141,6 @@ struct Variables {
141141
titleSlug: String,
142142
}
143143

144-
#[allow(dead_code)]
145144
#[derive(Debug, Deserialize)]
146145
pub struct LimitExceeded {
147146
status_code: u8,

0 commit comments

Comments
 (0)