// src/print.rs use crate::state::State; use crate::stats::Stats; struct SymbolTableElement { fg: &'static str, bg: &'static str, character: &'static str, } const GREEN_FG: &str = "\x1b[32m"; const ORANGE_FG: &str = "\x1b[38;5;208m"; const RED_FG: &str = "\x1b[31m"; const BLACK_BG: &str = "\x1b[40m"; const GREEN_BG: &str = "\x1b[42m"; const ORANGE_BG: &str = "\x1b[48;5;208m"; const ERASE_LINE_END: &str = "\x1b[0K"; const RESET: &str = "\x1b[0m"; const CHARS_TABLE: [SymbolTableElement; 25] = [ SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "▁", }, SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "▂", }, SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "▃", }, SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "▄", }, SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "▅", }, SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "▆", }, SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "▇", }, SymbolTableElement { fg: GREEN_FG, bg: BLACK_BG, character: "█", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "▁", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "▂", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "▃", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "▄", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "▅", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "▆", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "▇", }, SymbolTableElement { fg: ORANGE_FG, bg: GREEN_BG, character: "█", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "▁", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "▂", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "▃", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "▄", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "▅", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "▆", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "▇", }, SymbolTableElement { fg: RED_FG, bg: ORANGE_BG, character: "█", }, SymbolTableElement { fg: RED_FG, bg: BLACK_BG, character: "?", }, ]; pub fn print_legende_line() { for (index, element) in CHARS_TABLE.iter().enumerate() { print!( "{} {}{}{}\x1b[0m ", 10 * index, element.fg, element.bg, element.character ); } println!("{}", ERASE_LINE_END); } // TODO: Simplify this function pub fn print_ping_line(states: &Vec) { for state in states { match state { State::Received { rtt, .. } => { let (fg, bg, symbol) = get_symbol_and_colors_for_rrt(*rtt); print!("{}{}{}{}", fg, bg, symbol, RESET); } State::Lost => { let (fg, bg, symbol) = get_symbol_and_colors_for_rrt(250); print!("{}{}{}{}", fg, bg, symbol, RESET); } State::NotYetReceived { .. } => { // fg grey, bg black print!("\x1b[35;40m?\x1b[0m"); } State::SendError => { print!("!"); } } } println!("{}", ERASE_LINE_END); } fn get_symbol_and_colors_for_rrt(rrt: u64) -> (&'static str, &'static str, &'static str) { let index: usize = if rrt >= 240 { 24 } else { rrt / 10 } as usize; let SymbolTableElement { fg, bg, character } = CHARS_TABLE[index]; (fg, bg, character) } pub fn print_stats(stats: &Stats) { let total = stats.lost + stats.received; let percent_lost = if total > 0 { (stats.lost as f64 / total as f64) * 100.0 } else { 0.0 }; let mad_rtt_rounded = stats.mad_rtt.round() as u64; let mean_rtt_round = stats.avg_rtt.round() as u32; println!( "{}/{} ({:.1}%) | ⌊{}⌋ ⌈{}⌉ [{}] [Δ{}]ms{}", stats.lost, total, percent_lost, stats.min_rtt, stats.max_rtt, mean_rtt_round, mad_rtt_rounded, ERASE_LINE_END ); }