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
//! status command
use super::Command;
use async_trait::async_trait;
use clap::{App, ArgMatches, SubCommand};
use colored::Colorize;

/// Abstract statues command
///
/// ```sh
/// leetcode-stat
/// Show simple chart about submissions
///
/// USAGE:
///     leetcode stat
///
/// FLAGS:
///     -h, --help       Prints help information
///     -V, --version    Prints version information
/// ```
pub struct StatCommand;

#[async_trait]
impl Command for StatCommand {
    /// `stat` usage
    fn usage<'a, 'stat>() -> App<'a, 'stat> {
        SubCommand::with_name("stat")
            .about("Show simple chart about submissions")
            .visible_alias("s")
    }

    /// `stat` handler
    async fn handler(_m: &ArgMatches<'_>) -> Result<(), crate::err::Error> {
        use crate::{helper::Digit, Cache};

        let cache = Cache::new()?;
        let res = cache.get_problems()?;

        let mut easy: f64 = 0.00;
        let mut easy_ac: f64 = 0.00;
        let mut medium: f64 = 0.00;
        let mut medium_ac: f64 = 0.00;
        let mut hard: f64 = 0.00;
        let mut hard_ac: f64 = 0.00;

        for i in res.into_iter() {
            match i.level {
                1 => {
                    easy += 1.00;
                    if i.status == "ac" {
                        easy_ac += 1.00;
                    }
                }
                2 => {
                    medium += 1.00;
                    if i.status == "ac" {
                        medium_ac += 1.00;
                    }
                }
                3 => {
                    hard += 1.00;
                    if i.status == "ac" {
                        hard_ac += 1.00;
                    }
                }
                _ => {}
            }
        }

        // level: len = 8
        // count: len = 10
        // percent: len = 16
        // chart: len = 32
        // title
        println!(
            "\n{}",
            "  Level      Count     Percent                                Chart".bright_black()
        );
        println!(
            "{}",
            "  -----------------------------------------------------------------".bright_black()
        );

        // lines
        for (i, l) in vec![(easy, easy_ac), (medium, medium_ac), (hard, hard_ac)]
            .iter()
            .enumerate()
        {
            match i {
                0 => {
                    print!("  {}", "Easy".bright_green());
                    print!("{}", " ".digit(4));
                }
                1 => {
                    print!("  {}", "Medium".bright_yellow());
                    print!("{}", " ".digit(2));
                }
                2 => {
                    print!("  {}", "Hard".bright_red());
                    print!("{}", " ".digit(4));
                }
                _ => continue,
            }

            let checked_div = |lhs: f64, rhs: f64| if rhs == 0. { 0. } else { lhs / rhs };
            let count = format!("{}/{}", l.1, l.0);
            let pct = format!("( {:.2} %)", checked_div(100.0 * l.1, l.0));
            let mut line = "".to_string();
            line.push_str(&" ".digit(10 - (count.len() as i32)));
            line.push_str(&count);
            line.push_str(&" ".digit(12 - (pct.len() as i32)));
            line.push_str(&pct);
            print!("{}", line);
            print!("     ");

            let done = "░"
                .repeat(checked_div(32.00 * l.1, l.0) as usize)
                .bright_green();
            let udone = "░"
                .repeat(32 - checked_div(32.00 * l.1, l.0) as usize)
                .red();
            print!("{}", done);
            println!("{}", udone);
        }
        println!();
        Ok(())
    }
}