counter_cli/
basic_counters.rs1use std::io::{self, Write};
2
3use crossterm::cursor;
4
5use crate::loading_bar::LoadingBar;
6
7pub struct BasicCounter {
8 total: Option<u32>,
9 current: u32,
10 avg: Option<f32>,
11 buffer: String,
12}
13
14impl BasicCounter {
15 pub fn new(total: Option<u32>) -> Self {
16 Self {
17 total,
18 current: 0,
19 avg: None,
20 buffer: " ".repeat(crossterm::terminal::size().unwrap_or((2, 0)).0 as usize -2),
21 }
22 }
23}
24
25
26impl BasicCounter {
27 pub fn update(&mut self, s_elapsed: f32, increment: u32) -> bool {
29 let clamped = increment.clamp(0, self.total.unwrap_or(u32::MAX) - self.current);
30 self.current += clamped;
31 self.avg = match self.avg {
32 Some(avg) => Some((avg + clamped as f32 / s_elapsed) / 2.0),
33 None => Some(clamped as f32 / s_elapsed),
34 }; self.current == self.total.unwrap_or(u32::MAX)
35 }
36
37 pub fn draw_data(&self, description: &str) {
39 let mut stdout = io::stdout();
40
41 let percent = self.total.map(|total| self.current as f32 * 100.0 / total as f32);
42 let eta = self.total.map(|total| (total - self.current) as f32 / self.avg.unwrap_or(1.0));
43
44 print!("{}{}{}{}", cursor::MoveToColumn(0), self.buffer, cursor::MoveToColumn(0), cursor::Hide);
46
47 write!(
48 stdout,
49 "\x1b[36;1minfo: \x1b[0m{description}... \x1b[34m( \x1b[33m{}{}{}\x1b[34m )",
50 match self.total {
51 Some(total) => format!("{}\x1b[34m/\x1b[33m{total}", self.current),
52 None => self.current.to_string(),
53 },
54 match self.avg {
55 Some(avg) => format!("\x1b[34m, \x1b[33m{}", LoadingBar::right_avg_unit(avg)),
56 None => String::new(),
57 },
58 match self.total {
59 Some(_) => format!("\x1b[34m, \x1b[33m{:.2}%{}", percent.unwrap(), match eta {
60 Some(eta) => format!("\x1b[34m, \x1b[36;1meta: \x1b[0m\x1b[33m{}", LoadingBar::right_time_unit(eta)),
61 None => String::new(),
62 }),
63 None => String::new(),
64 },
65 ).unwrap();
66
67 stdout.flush().unwrap();
68 }
69
70 pub fn draw_tally(&self, description: &str) {
72 self.draw_data(description);
73
74 print!("\n{}{}{}", cursor::MoveToColumn(0), self.buffer, cursor::MoveToColumn(0));
76
77 print!(
78 " > \x1b[33;1m{}{}{}\x1b[0m",
79 "πΈβ".repeat(self.current as usize / 5),
80 "π·".repeat(self.current as usize % 5),
81 cursor::MoveUp(1),
82 ); io::stdout().flush().unwrap();
83 }
84}