Skip to content

Commit e6e4e41

Browse files
author
Antonio Bennett
committed
Add per-problem Cargo.toml and subdir structure for Rust LSP support
• For lang='rust', generate code at code/{fid}-{slug}/src/lib.rs and tests.dat. • Create Cargo.toml with basic config on first edit. • Preserves flat structure for other languages. • Enables rust-analyzer integration without breaking API submissions.
1 parent 9bb6380 commit e6e4e41

File tree

2 files changed

+70
-20
lines changed

2 files changed

+70
-20
lines changed

src/cmds/edit.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ impl Command for EditCommand {
6262
/// `edit` handler
6363
async fn handler(m: &ArgMatches) -> Result<()> {
6464
use crate::{cache::models::Question, Cache};
65-
use std::fs::File;
66-
use std::io::Write;
67-
use std::path::Path;
65+
use std::fs::{self, File};
66+
use std::io::Write;
67+
use std::path::Path;
6868

6969
let cache = Cache::new()?;
7070

@@ -105,9 +105,41 @@ impl Command for EditCommand {
105105
qr = Ok(cache.get_question(id).await?);
106106
}
107107

108-
let question: Question = qr?;
108+
let question: Question = qr?;
109109

110-
let mut file_code = File::create(&path)?;
110+
if *lang == "rust" {
111+
let sanitized_slug = problem.slug.replace(|c: char| !c.is_alphanumeric(), "_");
112+
let code_dir_str = format!("{}/{}-{}", conf.storage.code()?, problem.fid, sanitized_slug);
113+
let code_dir = Path::new(&code_dir_str);
114+
fs::create_dir_all(code_dir)?;
115+
116+
let src_dir_str = format!("{}/src", code_dir_str);
117+
let src_dir = Path::new(&src_dir_str);
118+
fs::create_dir_all(src_dir)?;
119+
120+
let cargo_path_str = format!("{}/Cargo.toml", code_dir_str);
121+
let cargo_path = Path::new(&cargo_path_str);
122+
if !cargo_path.exists() {
123+
let package_name = format!("leetcode-{}-{}", problem.fid, sanitized_slug);
124+
let cargo_content = format!(
125+
r#"[package]
126+
name = "{}"
127+
version = "0.1.0"
128+
edition = "2021"
129+
130+
[lib]
131+
path = "src/lib.rs"
132+
133+
[dependencies]
134+
"#,
135+
package_name
136+
);
137+
let mut cargo_file = File::create(&cargo_path_str)?;
138+
cargo_file.write_all(cargo_content.as_bytes())?;
139+
}
140+
}
141+
142+
let mut file_code = File::create(&path)?;
111143
let question_desc = question.desc_comment(&conf) + "\n";
112144

113145
let test_path = crate::helper::test_cases_path(&problem)?;

src/helper.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,35 +194,53 @@ mod file {
194194
use crate::{cache::models::Problem, Error};
195195

196196
/// Generate test cases path by fid
197-
pub fn test_cases_path(problem: &Problem) -> crate::Result<String> {
198-
let conf = crate::config::Config::locate()?;
199-
let mut path = format!("{}/{}.tests.dat", conf.storage.code()?, conf.code.pick);
197+
pub fn test_cases_path(problem: &Problem) -> crate::Result<String> {
198+
let conf = crate::config::Config::locate()?;
199+
let lang = conf.code.lang.clone();
200+
let code_base = conf.storage.code()?;
200201

202+
let path = if lang == "rust" {
203+
let sanitized_slug = problem.slug.replace(|c: char| !c.is_alphanumeric(), "_");
204+
let subdir = format!("{}-{}/tests.dat", problem.fid, sanitized_slug);
205+
format!("{}/{}", code_base, subdir)
206+
} else {
207+
let mut path = format!("{}/{}.tests.dat", code_base, conf.code.pick);
201208
path = path.replace("${fid}", &problem.fid.to_string());
202209
path = path.replace("${slug}", &problem.slug.to_string());
203-
Ok(path)
204-
}
210+
path
211+
};
212+
213+
Ok(path)
214+
}
205215

206216
/// Generate code path by fid
207-
pub fn code_path(problem: &Problem, l: Option<String>) -> crate::Result<String> {
208-
let conf = crate::config::Config::locate()?;
209-
let mut lang = conf.code.lang;
210-
if l.is_some() {
211-
lang = l.ok_or(Error::NoneError)?;
212-
}
217+
pub fn code_path(problem: &Problem, l: Option<String>) -> crate::Result<String> {
218+
let conf = crate::config::Config::locate()?;
219+
let mut lang = conf.code.lang.clone();
220+
if let Some(lang_opt) = l {
221+
lang = lang_opt;
222+
}
223+
224+
let code_base = conf.storage.code()?;
213225

226+
let path = if lang == "rust" {
227+
let sanitized_slug = problem.slug.replace(|c: char| !c.is_alphanumeric(), "_");
228+
let subdir = format!("{}-{}/src/lib.rs", problem.fid, sanitized_slug);
229+
format!("{}/{}", code_base, subdir)
230+
} else {
214231
let mut path = format!(
215232
"{}/{}.{}",
216-
conf.storage.code()?,
233+
code_base,
217234
conf.code.pick,
218235
suffix(&lang)?,
219236
);
220-
221237
path = path.replace("${fid}", &problem.fid.to_string());
222238
path = path.replace("${slug}", &problem.slug.to_string());
239+
path
240+
};
223241

224-
Ok(path)
225-
}
242+
Ok(path)
243+
}
226244

227245
/// Load python scripts
228246
pub fn load_script(module: &str) -> crate::Result<String> {

0 commit comments

Comments
 (0)