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
//! status command
use super::Command;
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;

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
    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 = 8
        // 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(8 - (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(())
    }
}