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
use serde::Deserialize;
use serde::{self, Serialize};

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TopicTag {
    pub name: Option<String>,
    pub id: String,
    pub slug: Option<String>,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Question {
    pub ac_rate: Option<f64>,
    pub difficulty: Option<String>,
    pub freq_bar: Option<f64>,
    pub frontend_question_id: String,
    pub is_favor: Option<bool>,
    pub paid_only: Option<bool>,
    pub status: Option<String>,
    pub title: Option<String>,
    pub title_slug: Option<String>,
    pub has_solution: Option<bool>,
    pub has_video_solution: Option<bool>,
    pub topic_tags: Option<Vec<TopicTag>>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProblemSetQuestionList {
    pub total: i32,
    pub questions: Vec<Question>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Data {
    pub problemset_question_list: ProblemSetQuestionList,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Root {
    data: Data,
}

impl Root {
    pub fn get_questions(self) -> Vec<Question> {
        self.data.problemset_question_list.questions
    }

    pub fn get_total_questions(&self) -> i32 {
        self.data.problemset_question_list.total
    }
}

#[cfg(test)]
mod tests {

    use super::Root;
    use serde_json;

    #[test]
    fn test_json_deserialization() {
        let json = r#"{
            "data": {
                "problemsetQuestionList": {
                    "total": 2777,
                    "questions": [
                        {
                            "acRate": 45.35065222510613,
                            "difficulty": "Medium",
                            "freqBar": null,
                            "frontendQuestionId": "6",
                            "isFavor": false,
                            "paidOnly": false,
                            "status": "ac",
                            "title": "Zigzag Conversion",
                            "titleSlug": "zigzag-conversion",
                            "topicTags": [
                                {
                                    "name": "String",
                                    "id": "VG9waWNUYWdOb2RlOjEw",
                                    "slug": "string"
                                }
                            ],
                            "hasSolution": true,
                            "hasVideoSolution": false
                        }
                    ]
                }
            }
        }"#;

        let root: Root = serde_json::from_str(json).unwrap();

        // Validate the deserialized struct fields
        assert_eq!(root.data.problemset_question_list.total, 2777);
        assert_eq!(root.data.problemset_question_list.questions.len(), 1);

        let question = &root.data.problemset_question_list.questions[0];
        assert_eq!(question.ac_rate, Some(45.35065222510613));
        assert_eq!(question.difficulty, Some("Medium".to_string()));
        assert_eq!(question.freq_bar, None);
        assert_eq!(question.frontend_question_id, "6".to_string());
        assert_eq!(question.is_favor, Some(false));
        assert_eq!(question.paid_only, Some(false));
        assert_eq!(question.status, Some("ac".to_string()));
        assert_eq!(question.title, Some("Zigzag Conversion".to_string()));
        assert_eq!(question.title_slug, Some("zigzag-conversion".into()));

        if let Some(topic_tags) = &question.topic_tags {
            assert_eq!(topic_tags.len(), 1);
            let topic_tag = &topic_tags[0];
            assert_eq!(topic_tag.name, Some("String".into()));
            assert_eq!(topic_tag.id, "VG9waWNUYWdOb2RlOjEw");
            assert_eq!(topic_tag.slug, Some("string".into()));
        }

        assert_eq!(question.has_solution, Some(true));
        assert_eq!(question.has_video_solution, Some(false));
    }
}