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
use std::{cell::RefCell, rc::Rc};

use crate::entities::QuestionModel;
use std::hash::Hash;

#[derive(PartialEq, Eq, Debug, Ord, PartialOrd)]
pub struct QuestionModelContainer {
    pub question: RefCell<QuestionModel>,
}

// RefCell keys are mutable and should not be used in types where hashing
// is required. This implementation is valid until question_frontend_id change.
// For more refer https://rust-lang.github.io/rust-clippy/master/index.html#/mutable_key_type
impl Hash for QuestionModelContainer {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.question.borrow().hash(state)
    }
}

pub struct Stats<'a> {
    pub qm: &'a Vec<Rc<QuestionModelContainer>>,
}

impl<'a> Stats<'a> {
    pub(crate) fn get_total_question(&self) -> usize {
        self.qm.len()
    }

    pub(crate) fn get_accepted(&self) -> usize {
        self.get_status("ac")
    }

    pub(crate) fn get_not_accepted(&self) -> usize {
        self.get_status("notac")
    }

    pub(crate) fn get_not_attempted(&self) -> usize {
        self.get_total_question() - (self.get_accepted() + self.get_not_accepted())
    }

    pub(crate) fn get_easy_count(&self) -> usize {
        self.get_diff_count("Easy")
    }

    pub(crate) fn get_medium_count(&self) -> usize {
        self.get_diff_count("Medium")
    }

    pub(crate) fn get_hard_count(&self) -> usize {
        self.get_diff_count("Hard")
    }

    pub(crate) fn get_easy_accepted(&self) -> usize {
        self.get_diff_accepted("ac", "Easy")
    }

    pub(crate) fn get_medium_accepted(&self) -> usize {
        self.get_diff_accepted("ac", "Medium")
    }

    pub(crate) fn get_hard_accepted(&self) -> usize {
        self.get_diff_accepted("ac", "Hard")
    }

    pub(crate) fn get_diff_accepted(&self, status: &str, difficulty: &str) -> usize {
        self.qm
            .iter()
            .filter(|q| {
                if let Some(st) = &q.question.borrow().status {
                    if let Some(at) = &q.question.borrow().difficulty {
                        st.as_str() == status && difficulty == at.as_str()
                    } else {
                        false
                    }
                } else {
                    false
                }
            })
            .count()
    }

    fn get_status(&self, status: &str) -> usize {
        self.qm
            .iter()
            .filter(|q| {
                if let Some(st) = &q.question.borrow().status {
                    st.as_str() == status
                } else {
                    false
                }
            })
            .count()
    }

    fn get_diff_count(&self, difficulty: &str) -> usize {
        self.qm
            .iter()
            .filter(|q| {
                if let Some(diff) = &q.question.borrow().difficulty {
                    diff.as_str() == difficulty
                } else {
                    false
                }
            })
            .count()
    }
}