leetcode-tui-core 0.5.2

Leetcode tui related core modules
Documentation
use leetcode_tui_config::CONFIG;
use leetcode_tui_db::DbQuestion;
use ratatui::style::Style;
use std::{fmt::Display, rc::Rc};

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

impl<'a> Stats<'a> {
    pub(super) fn new(questions: &'a Vec<Rc<DbQuestion>>) -> Self {
        Self { qm: questions }
    }
}

#[derive(Debug)]
pub enum QuestionStatus {
    Accepted,
    Attempted,
    EasyAccepted,
    MediumAccepted,
    HardAccepted,
}

use QuestionStatus::*;

impl Display for QuestionStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let string = match self {
            Accepted => "Accepted",
            Attempted => "Attempted",
            EasyAccepted => "Easy Accepted",
            MediumAccepted => "Medium Accepted",
            HardAccepted => "Hard Accepted",
        };
        write!(f, "{}", string)
    }
}

impl Into<Style> for QuestionStatus {
    fn into(self) -> Style {
        match self {
            Accepted => CONFIG.as_ref().theme.question.normal.easy,
            Attempted => CONFIG.as_ref().theme.question.normal.easy,
            EasyAccepted => CONFIG.as_ref().theme.question.normal.easy,
            MediumAccepted => CONFIG.as_ref().theme.question.normal.medium,
            HardAccepted => CONFIG.as_ref().theme.question.normal.hard,
        }
        .into()
    }
}

impl<'a> Stats<'a> {
    pub fn get_ratios(&self) -> Vec<(QuestionStatus, usize, usize)> {
        use QuestionStatus::*;
        vec![
            (Accepted, self.get_accepted(), self.get_total_question()),
            (
                Attempted,
                self.get_total_question() - self.get_not_attempted(),
                self.get_total_question(),
            ),
            (
                EasyAccepted,
                self.get_easy_accepted(),
                self.get_easy_count(),
            ),
            (
                MediumAccepted,
                self.get_medium_accepted(),
                self.get_medium_count(),
            ),
            (
                HardAccepted,
                self.get_hard_accepted(),
                self.get_hard_count(),
            ),
        ]
    }
}

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

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

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

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

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

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

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

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

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

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

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

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

    fn get_diff_count(&self, difficulty: &str) -> usize {
        self.qm
            .iter()
            .filter(|q| q.difficulty.as_str() == difficulty)
            .count()
    }
}