9 changed files with 347 additions and 138 deletions
|
After Width: | Height: | Size: 9.9 KiB |
@ -0,0 +1,107 @@ |
|||||||
|
use std::fmt; |
||||||
|
|
||||||
|
use yansi::Color::{Blue, Green, Red}; |
||||||
|
|
||||||
|
#[derive(Debug)] |
||||||
|
pub struct MatchBarRow { |
||||||
|
pub label: String, |
||||||
|
pub count: usize, |
||||||
|
} |
||||||
|
|
||||||
|
impl MatchBarRow { |
||||||
|
pub fn new(string: &str) -> MatchBarRow { |
||||||
|
MatchBarRow { |
||||||
|
label: string.to_string(), |
||||||
|
count: 0, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn inc_if_matches(&mut self, line: &str) { |
||||||
|
if line.contains(&self.label) { |
||||||
|
self.count += 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Debug)] |
||||||
|
pub struct MatchBar { |
||||||
|
pub vec: Vec<MatchBarRow>, |
||||||
|
top_values: usize, |
||||||
|
top_lenght: usize, |
||||||
|
} |
||||||
|
|
||||||
|
impl MatchBar { |
||||||
|
pub fn new(vec: Vec<MatchBarRow>) -> MatchBar { |
||||||
|
let mut top_lenght: usize = 0; |
||||||
|
let mut top_values: usize = 0; |
||||||
|
for row in vec.iter() { |
||||||
|
top_lenght = top_lenght.max(row.label.len()); |
||||||
|
top_values = top_values.max(row.count); |
||||||
|
} |
||||||
|
MatchBar { |
||||||
|
vec, |
||||||
|
top_lenght, |
||||||
|
top_values, |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl fmt::Display for MatchBar { |
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||||
|
let width = f.width().unwrap_or(100); |
||||||
|
let divisor = 1.max(self.top_values / width); |
||||||
|
let width_count = format!("{}", self.top_values).len(); |
||||||
|
writeln!( |
||||||
|
f, |
||||||
|
"Matches: {}.", |
||||||
|
Blue.paint(format!( |
||||||
|
"{}", |
||||||
|
self.vec.iter().map(|r| r.count).sum::<usize>() |
||||||
|
)), |
||||||
|
)?; |
||||||
|
writeln!( |
||||||
|
f, |
||||||
|
"Each {} represents a count of {}", |
||||||
|
Red.paint("∎"), |
||||||
|
Blue.paint(divisor.to_string()), |
||||||
|
)?; |
||||||
|
for row in self.vec.iter() { |
||||||
|
writeln!( |
||||||
|
f, |
||||||
|
"[{label}] [{count}] {bar}", |
||||||
|
label = Blue.paint(format!("{:width$}", row.label, width = self.top_lenght)), |
||||||
|
count = Green.paint(format!("{:width$}", row.count, width = width_count)), |
||||||
|
bar = Red.paint(format!("{:∎<width$}", "", width = row.count / divisor)) |
||||||
|
)?; |
||||||
|
} |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[cfg(test)] |
||||||
|
mod tests { |
||||||
|
use super::*; |
||||||
|
use yansi::Paint; |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn test_matchbar() { |
||||||
|
let mut row0 = MatchBarRow::new("label1"); |
||||||
|
row0.inc_if_matches("labelN"); |
||||||
|
row0.inc_if_matches("label1"); |
||||||
|
row0.inc_if_matches("label1"); |
||||||
|
row0.inc_if_matches("label11"); |
||||||
|
let mut row1 = MatchBarRow::new("label2"); |
||||||
|
row1.inc_if_matches("label2"); |
||||||
|
let mb = MatchBar::new(vec![row0, row1, MatchBarRow::new("label333")]); |
||||||
|
assert_eq!(mb.top_lenght, 8); |
||||||
|
assert_eq!(mb.top_values, 3); |
||||||
|
Paint::disable(); |
||||||
|
let display = format!("{}", mb); |
||||||
|
|
||||||
|
assert!(display.contains("[label1 ] [3] ∎∎∎\n")); |
||||||
|
assert!(display.contains("[label2 ] [1] ∎\n")); |
||||||
|
assert!(display.contains("[label333] [0] \n")); |
||||||
|
assert!(display.contains("represents a count of 1")); |
||||||
|
assert!(display.contains("Matches: 4")); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue