leetcode_cli/cmds/
stat.rs

1//! status command
2use super::Command;
3use async_trait::async_trait;
4use clap::{ArgMatches, Command as ClapCommand};
5use colored::Colorize;
6
7/// Abstract statues command
8///
9/// ```sh
10/// leetcode-stat
11/// Show simple chart about submissions
12///
13/// USAGE:
14///     leetcode stat
15///
16/// FLAGS:
17///     -h, --help       Prints help information
18///     -V, --version    Prints version information
19/// ```
20pub struct StatCommand;
21
22#[async_trait]
23impl Command for StatCommand {
24    /// `stat` usage
25    fn usage() -> ClapCommand {
26        ClapCommand::new("stat")
27            .about("Show simple chart about submissions")
28            .visible_alias("s")
29    }
30
31    /// `stat` handler
32    async fn handler(_m: &ArgMatches) -> Result<(), crate::err::Error> {
33        use crate::{helper::Digit, Cache};
34
35        let cache = Cache::new()?;
36        let res = cache.get_problems()?;
37
38        let mut easy: f64 = 0.00;
39        let mut easy_ac: f64 = 0.00;
40        let mut medium: f64 = 0.00;
41        let mut medium_ac: f64 = 0.00;
42        let mut hard: f64 = 0.00;
43        let mut hard_ac: f64 = 0.00;
44
45        for i in res.into_iter() {
46            match i.level {
47                1 => {
48                    easy += 1.00;
49                    if i.status == "ac" {
50                        easy_ac += 1.00;
51                    }
52                }
53                2 => {
54                    medium += 1.00;
55                    if i.status == "ac" {
56                        medium_ac += 1.00;
57                    }
58                }
59                3 => {
60                    hard += 1.00;
61                    if i.status == "ac" {
62                        hard_ac += 1.00;
63                    }
64                }
65                _ => {}
66            }
67        }
68
69        // level: len = 8
70        // count: len = 10
71        // percent: len = 16
72        // chart: len = 32
73        // title
74        println!(
75            "\n{}",
76            "  Level      Count     Percent                                Chart".bright_black()
77        );
78        println!(
79            "{}",
80            "  -----------------------------------------------------------------".bright_black()
81        );
82
83        // lines
84        for (i, l) in [(easy, easy_ac), (medium, medium_ac), (hard, hard_ac)]
85            .iter()
86            .enumerate()
87        {
88            match i {
89                0 => {
90                    print!("  {}", "Easy".bright_green());
91                    print!("{}", " ".digit(4));
92                }
93                1 => {
94                    print!("  {}", "Medium".bright_yellow());
95                    print!("{}", " ".digit(2));
96                }
97                2 => {
98                    print!("  {}", "Hard".bright_red());
99                    print!("{}", " ".digit(4));
100                }
101                _ => continue,
102            }
103
104            let checked_div = |lhs: f64, rhs: f64| if rhs == 0. { 0. } else { lhs / rhs };
105            let count = format!("{}/{}", l.1, l.0);
106            let pct = format!("( {:.2} %)", checked_div(100.0 * l.1, l.0));
107            let mut line = "".to_string();
108            line.push_str(&" ".digit(10 - (count.len() as i32)));
109            line.push_str(&count);
110            line.push_str(&" ".digit(12 - (pct.len() as i32)));
111            line.push_str(&pct);
112            print!("{}", line);
113            print!("     ");
114
115            let done = "░"
116                .repeat(checked_div(32.00 * l.1, l.0) as usize)
117                .bright_green();
118            let udone = "░"
119                .repeat(32 - checked_div(32.00 * l.1, l.0) as usize)
120                .red();
121            print!("{}", done);
122            println!("{}", udone);
123        }
124        println!();
125        Ok(())
126    }
127}