|
1 | 1 | //! Sub-Module for parsing resp data
|
2 | 2 | use super::models::*;
|
3 | | -use serde_json::Value; |
| 3 | +use serde_json::{Value,from_value}; |
| 4 | + |
4 | 5 |
|
5 | 6 | /// contest parser
|
6 | 7 | pub fn contest(v: Value) -> Option<Contest> {
|
7 | 8 | let o = v.as_object()?;
|
8 | | - let contest = o.get("contest")?.as_object()?; |
9 | | - let questions: Vec<ContestQuestionStub> = o |
10 | | - .get("questions")?.as_array()? |
11 | | - .iter().map(|q| { |
12 | | - let stub: Result<ContestQuestionStub, _> = serde_json::from_value(q.clone()); |
13 | | - stub.unwrap() |
14 | | - }).collect(); |
15 | | - Some(Contest { |
16 | | - id: contest.get("id")?.as_i64()? as i32, |
17 | | - duration: contest.get("duration")?.as_i64()? as i32, |
18 | | - start_time: contest.get("start_time")?.as_i64()?, |
19 | | - title: contest.get("title")?.as_str()?.to_string(), |
20 | | - title_slug: contest.get("title_slug")?.as_str()?.to_owned(), |
21 | | - description: "".to_owned(), // TODO: display description. contest.get("description")?.as_str()?.to_owned(), |
22 | | - is_virtual: contest.get("is_virtual")?.as_bool()?, |
23 | | - contains_premium: o.get("containsPremium")?.as_bool()?, |
24 | | - registered: o.get("registered")?.as_bool()?, |
25 | | - questions |
26 | | - }) |
| 9 | + let mut contest: Contest = from_value( |
| 10 | + o.get("contest")?.clone() |
| 11 | + ).ok()?; |
| 12 | + contest.questions = from_value( |
| 13 | + o.get("questions")?.clone() |
| 14 | + ).ok()?; |
| 15 | + contest.contains_premium = o.get("containsPremium")?.as_bool()?; |
| 16 | + contest.registered = o.get("registered")?.as_bool()?; |
| 17 | + Some(contest) |
27 | 18 | }
|
28 | 19 |
|
29 | 20 | /// problem parser
|
@@ -55,31 +46,29 @@ pub fn problem(problems: &mut Vec<Problem>, v: Value) -> Option<()> {
|
55 | 46 | // TODO: implement test for this
|
56 | 47 | /// graphql problem && question parser
|
57 | 48 | pub fn graphql_problem_and_question(v: Value) -> Option<(Problem,Question)> {
|
| 49 | + // parse top-level data from API |
58 | 50 | let mut qn = Question::default();
|
59 | 51 | assert_eq!(Some(true), desc(&mut qn, v.clone()));
|
60 | 52 | let percent = &qn.stats.rate;
|
61 | 53 | let percent = percent[..percent.len()-1].parse::<f32>().ok()?;
|
| 54 | + |
| 55 | + // parse v.question specifically |
62 | 56 | let v = v.as_object()?.get("data")?
|
63 | | - .as_object()?.get("question")? |
64 | | - .as_object()?; |
65 | | - Some((Problem { |
66 | | - category: v.get("categoryTitle")?.as_str()?.to_ascii_lowercase(), // dangerous, since this is not actually the slug. But currently (May 2022) ok |
67 | | - fid: v.get("questionFrontendId")?.as_str()?.parse().ok()?, |
68 | | - id: v.get("questionId")?.as_str()?.parse().ok()?, |
69 | | - level: match v.get("difficulty")?.as_str()?.chars().next()? { |
70 | | - 'E' => 1, |
71 | | - 'M' => 2, |
72 | | - 'H' => 3, |
73 | | - _ => 0, |
74 | | - }, |
75 | | - locked: false, // lazy |
76 | | - name: v.get("title")?.as_str()?.to_string(), |
77 | | - percent, |
78 | | - slug: v.get("titleSlug")?.as_str()?.to_string(), |
79 | | - starred: v.get("isFavor")?.as_bool()?, |
80 | | - status: v.get("status")?.as_str().unwrap_or("Null").to_owned(), |
81 | | - desc: serde_json::to_string(&qn).ok()?, |
82 | | - }, qn)) |
| 57 | + .as_object()?.get("question")?; |
| 58 | + let mut p: Problem = from_value(v.clone()).unwrap(); |
| 59 | + p.percent = percent; |
| 60 | + p.level = match v.as_object()?.get("difficulty")?.as_str()?.chars().next()? { |
| 61 | + 'E' => 1, |
| 62 | + 'M' => 2, |
| 63 | + 'H' => 3, |
| 64 | + _ => 0, |
| 65 | + }; |
| 66 | + p.status = v.get("status")?.as_str().unwrap_or("Null").to_owned(); |
| 67 | + p.desc = serde_json::to_string(&qn).ok()?; |
| 68 | + /* The graphql API doesn't return the category slug, only the printed category title. */ |
| 69 | + p.category = p.category.to_ascii_lowercase(); // Currently working (June 2022) |
| 70 | + /* But lowercasing is stupid. This will break if a category with whitespaces appears. */ |
| 71 | + Some((p,qn)) |
83 | 72 | }
|
84 | 73 |
|
85 | 74 | /// desc parser
|
|
0 commit comments