Skip to content
Prev Previous commit
Next Next commit
feat: like vsc-leetcode-cli edit file has extra problem desc
1. edit add file include extra information 2. remove test file, and use memory all_cases 3. use scraper crate parser the desc html fragment
  • Loading branch information
wendajiang committed Jul 8, 2022
commit 0558081e605c11bfcb7f38c9eee9ca57cb251e1e
15 changes: 12 additions & 3 deletions src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod sql;
use self::models::*;
use self::schemas::{problems::dsl::*, tags::dsl::*};
use self::sql::*;
use crate::cmds::{CODE_END, CODE_START};
use crate::{cfg, err::Error, plugins::LeetCode};
use colored::Colorize;
use diesel::prelude::*;
Expand All @@ -26,7 +27,7 @@ pub enum Run {
Submit,
}

impl std::default::Default for Run {
impl Default for Run {
fn default() -> Self {
Run::Submit
}
Expand All @@ -37,7 +38,7 @@ impl std::default::Default for Run {
pub struct Cache(pub LeetCode);

impl Cache {
/// Ref to sqliteconnection
/// Ref to sqlite connection
fn conn(&self) -> Result<SqliteConnection, Error> {
Ok(conn(self.0.conf.storage.cache()?))
}
Expand Down Expand Up @@ -269,6 +270,14 @@ impl Cache {

File::open(code_path(&p, None)?)?.read_to_string(&mut code)?;

let begin = code.find(CODE_START).unwrap_or(0);
let end = code.find(CODE_END).unwrap_or(code.len());
let code = if let Some(solution) = code.get(begin..end) {
solution.to_string()
} else {
code
};

json.insert("lang", conf.code.lang.to_string());
json.insert("question_id", p.id.to_string());
json.insert("typed_code", code);
Expand Down Expand Up @@ -311,7 +320,7 @@ impl Cache {
async fn recur_verify(&self, rid: String) -> Result<VerifyResult, Error> {
use std::time::Duration;

trace!("Run veriy recursion...");
trace!("Run verify recursion...");
std::thread::sleep(Duration::from_micros(3000));

let json: VerifyResult = self
Expand Down
36 changes: 33 additions & 3 deletions src/cache/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ pub struct Problem {
pub desc: String,
}

impl Problem {
fn display_level(&self) -> &str {
match self.level {
1 => "Easy",
2 => "Medium",
3 => "Hard",
_ => "Unknown",
}
}
pub fn desc_comment(&self) -> String {
let mut res = String::new();
res += format!("// Category: {}\n", self.category).as_str();
res += format!("// Level: {}\n", self.display_level(),).as_str();
res += format!("// Percent: {}%\n\n", self.percent).as_str();

res + "\n"
}
}

static DONE: &str = " ✔";
static ETC: &str = "...";
static LOCK: &str = "🔒";
Expand Down Expand Up @@ -124,9 +143,20 @@ pub struct Question {
pub t_content: String,
}

impl std::fmt::Display for Question {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self.content.render())
impl Question {
pub fn desc(&self) -> String {
self.content.render()
}

pub fn desc_comment(&self) -> String {
let desc = self.content.render();

let mut res = desc
.lines()
.fold("/*\n".to_string(), |acc, e| acc + " * " + e + "\n");
res += " */\n";

res
}
}

Expand Down
17 changes: 13 additions & 4 deletions src/cmds/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use clap::{Arg, ArgMatches, Command as ClapCommand};
/// ```
pub struct EditCommand;

pub const CODE_START: &str = r#"// @lc code=start"#;
pub const CODE_END: &str = r#"// @lc code=end"#;
Comment on lines +25 to +26
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shoud configure these in the config, the // can not be recognized by every programming languages

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you are right, // maybe wrong!


#[async_trait]
impl Command for EditCommand {
/// `edit` usage
Expand Down Expand Up @@ -53,33 +56,39 @@ impl Command for EditCommand {

let id: i32 = m.value_of("id").ok_or(Error::NoneError)?.parse()?;
let cache = Cache::new()?;
let target = cache.get_problem(id)?;
let problem = cache.get_problem(id)?;
let mut conf = cache.to_owned().0.conf;

let p_desc_comment = problem.desc_comment();
// condition language
if m.contains_id("lang") {
conf.code.lang = m.value_of("lang").ok_or(Error::NoneError)?.to_string();
conf.sync()?;
}

let lang = conf.code.lang;
let path = crate::helper::code_path(&target, Some(lang.to_owned()))?;
let path = crate::helper::code_path(&problem, Some(lang.to_owned()))?;

if !Path::new(&path).exists() {
let mut qr = serde_json::from_str(&target.desc);
let mut qr = serde_json::from_str(&problem.desc);
if qr.is_err() {
qr = Ok(cache.get_question(id).await?);
}

let question: Question = qr?;

let mut file_code = File::create(&path)?;
let question_desc = question.desc_comment() + "\n";

let mut flag = false;
for d in question.defs.0 {
if d.value == lang {
flag = true;
file_code.write_all(d.code.to_string().as_bytes())?;
file_code.write_all(p_desc_comment.as_bytes())?;
file_code.write_all(question_desc.as_bytes())?;
file_code.write_all((CODE_START.to_string() + "\n").as_bytes())?;
file_code.write_all((d.code.to_string() + "\n").as_bytes())?;
file_code.write_all((CODE_END.to_string() + "\n").as_bytes())?;
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/cmds/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! ```
use crate::err::Error;
use async_trait::async_trait;
use clap::{Command as ClapCommand, ArgMatches};
use clap::{ArgMatches, Command as ClapCommand};

/// Abstract commands' trait.
#[async_trait]
Expand All @@ -38,3 +38,5 @@ pub use list::ListCommand;
pub use pick::PickCommand;
pub use stat::StatCommand;
pub use test::TestCommand;

pub use edit::{CODE_END, CODE_START};
2 changes: 1 addition & 1 deletion src/cmds/pick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl Command for PickCommand {
let r = cache.get_question(fid).await;

match r {
Ok(r) => println!("{}", r),
Ok(q) => println!("{}", q.desc()),
Err(e) => {
eprintln!("{:?}", e);
if let Error::FeatureError(_) | Error::NetworkError(_) = e {
Expand Down
6 changes: 3 additions & 3 deletions src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ mod file {
use crate::{cache::models::Problem, Error};

/// Generate code path by fid
pub fn code_path(target: &Problem, l: Option<String>) -> Result<String, crate::Error> {
pub fn code_path(problem: &Problem, l: Option<String>) -> Result<String, crate::Error> {
let conf = crate::cfg::locate()?;
let mut lang = conf.code.lang;
if l.is_some() {
Expand All @@ -158,8 +158,8 @@ mod file {
suffix(&lang)?,
);

path = path.replace("${fid}", &target.fid.to_string());
path = path.replace("${slug}", &target.slug.to_string());
path = path.replace("${fid}", &problem.fid.to_string());
path = path.replace("${slug}", &problem.slug.to_string());

Ok(path)
}
Expand Down