-
Notifications
You must be signed in to change notification settings - Fork 142
/
Copy pathproblem.rs
167 lines (150 loc) · 4.36 KB
/
problem.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
extern crate reqwest;
extern crate serde_json;
use std::fmt::{Display, Error, Formatter};
const PROBLEMS_URL: &str = "https://leetcode.com/api/problems/algorithms/";
const GRAPHQL_URL: &str = "https://leetcode.com/graphql";
const QUESTION_QUERY_STRING: &str = r#"
query questionData($titleSlug: String!) {
question(titleSlug: $titleSlug) {
content
stats
codeDefinition
sampleTestCase
metaData
}
}"#;
const QUESTION_QUERY_OPERATION: &str = "questionData";
pub fn get_problem(id: u32) -> Option<Problem> {
let problems = get_problems().unwrap();
for problem in problems.stat_status_pairs.iter() {
if problem.stat.question_id == id {
if problem.paid_only {
return None;
}
let client = reqwest::Client::new();
let resp: RawProblem = client
.post(GRAPHQL_URL)
.json(&Query::question_query(
problem.stat.question_title_slug.as_ref().unwrap(),
))
.send()
.unwrap()
.json()
.unwrap();
return Some(Problem {
title: problem.stat.question_title.clone().unwrap(),
title_slug: problem.stat.question_title_slug.clone().unwrap(),
code_definition: serde_json::from_str(&resp.data.question.code_definition).unwrap(),
content: resp.data.question.content,
sample_test_case: resp.data.question.sample_test_case,
difficulty: problem.difficulty.to_string(),
});
}
}
None
}
fn get_problems() -> Option<Problems> {
reqwest::get(PROBLEMS_URL).unwrap().json().unwrap()
}
#[derive(Serialize, Deserialize)]
pub struct Problem {
pub title: String,
pub title_slug: String,
pub content: String,
#[serde(rename = "codeDefinition")]
pub code_definition: Vec<CodeDefinition>,
#[serde(rename = "sampleTestCase")]
pub sample_test_case: String,
pub difficulty: String,
}
#[derive(Serialize, Deserialize)]
pub struct CodeDefinition {
pub value: String,
pub text: String,
#[serde(rename = "defaultCode")]
pub default_code: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct Query {
#[serde(rename = "operationName")]
operation_name: String,
variables: serde_json::Value,
query: String,
}
impl Query {
fn question_query(title_slug: &str) -> Query {
Query {
operation_name: QUESTION_QUERY_OPERATION.to_owned(),
variables: json!({ "titleSlug": title_slug }),
query: QUESTION_QUERY_STRING.to_owned(),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
struct RawProblem {
data: Data,
}
#[derive(Debug, Serialize, Deserialize)]
struct Data {
question: Question,
}
#[derive(Debug, Serialize, Deserialize)]
struct Question {
content: String,
stats: String,
#[serde(rename = "codeDefinition")]
code_definition: String,
#[serde(rename = "sampleTestCase")]
sample_test_case: String,
#[serde(rename = "metaData")]
meta_data: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct Problems {
user_name: String,
num_solved: u32,
num_total: u32,
ac_easy: u32,
ac_medium: u32,
ac_hard: u32,
stat_status_pairs: Vec<StatWithStatus>,
}
#[derive(Debug, Serialize, Deserialize)]
struct StatWithStatus {
stat: Stat,
difficulty: Difficulty,
paid_only: bool,
is_favor: bool,
frequency: u32,
progress: u32,
}
#[derive(Debug, Serialize, Deserialize)]
struct Stat {
question_id: u32,
#[serde(rename = "question__article__slug")]
question_article_slug: Option<String>,
#[serde(rename = "question__title")]
question_title: Option<String>,
#[serde(rename = "question__title_slug")]
question_title_slug: Option<String>,
#[serde(rename = "question__hide")]
question_hide: bool,
total_acs: u32,
total_submitted: u32,
frontend_question_id: u32,
is_new_question: bool,
}
#[derive(Debug, Serialize, Deserialize)]
struct Difficulty {
level: u32,
}
impl Display for Difficulty {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match self.level {
1 => f.write_str("Easy"),
2 => f.write_str("Medium"),
3 => f.write_str("Hard"),
_ => f.write_str("Unknown"),
}
}
}