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
use { crate::*, minimad::OwningTemplateExpander, termimad::*, }; static MD: &str = r#" |:-:|:-:|:-:|:- |**date**|**hits**|**bytes**|**${scale}** |:-|:-:|-:|:- ${bars |${date}|${hits}|${bytes}|*${bar}* } |-: "#; #[derive(Clone)] pub struct Bar { pub date: Date, pub hits: u64, pub bytes_sent: u64, } impl Bar { pub fn new(date: Date) -> Self { Self { date, hits: 0, bytes_sent: 0, } } } #[derive(Clone, Default)] pub struct Histogram { pub bars: Vec<Bar>, } impl Histogram { pub fn from(base: &LogBase) -> Self { let mut bars: Vec<Bar> = base.dates.iter() .map(|&date| Bar { date, bytes_sent: 0, hits: 0 }) .collect(); for line in &base.lines { bars[line.date_idx].hits += 1; bars[line.date_idx].bytes_sent += line.bytes_sent; } Self { bars } } pub fn print( &self, printer: &md::Printer, ) { let mut expander = OwningTemplateExpander::new(); let max_bar = self.bars .iter() .map(|b| if printer.key==Key::Hits { b.hits } else { b.bytes_sent }) .max().unwrap(); expander.set( "scale", format!("0 {:>4}", file_size::fit_4(max_bar)), ); let max_bar = max_bar as f32; for bar in &self.bars { if printer.date_filter.map_or(true, |f| f.contains(bar.date)) { let value = if printer.key == Key::Hits { bar.hits } else { bar.bytes_sent }; let part = (value as f32) / max_bar; expander.sub("bars") .set("date", bar.date) .set_md("hits", printer.md_hits(bar.hits as usize)) .set_md("bytes", printer.md_bytes(bar.bytes_sent)) .set("bar", ProgressBar::new(part, 20)); } } printer.print(expander, MD); } pub fn total_hits(&self) -> u64 { self.bars.iter().map(|b| b.hits).sum() } pub fn total_bytes_sent(&self) -> u64 { self.bars.iter().map(|b| b.bytes_sent).sum() } }