// 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_FG :&str = "\x1b[31m"; const BLACK_BG :&str = "\x1b[40m"; const GREEN_BG :&str = "\x1b[40m"; const ORANGE_BG :&str = "\x1b[48;5;208m"; const ERASE_LINE_END:&str = "\x1b[0K"; 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() { let val = 10 * index as u64; print!("{} {}{}{}\x1b[0m ", val, element.fg, element.bg, element.character); } println!(""); } 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, "\x1b[0m"); } State::Lost => { let (fg, bg, symbol) = get_symbol_and_colors_for_rrt(250); print!("{}{}{}{}", fg, bg, symbol, "\x1b[0m"); } State::NotYetReceived { .. } => { // fg grey, bg black print!("\x1b[35;40m?\x1b[0m"); } State::SendError => { print!("!"); } } } println!(""); } 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; let mean_ttl_round = stats.avg_ttl.round() as u32; println!( "{}/{} ({:.1}%) | ⌊{}⌋ ⌈{}⌉ [{}] [Δ{}]ms / ⌊{}⌋ ⌈{}⌉ [{}]{}", stats.lost, total, percent_lost, stats.min_rtt, stats.max_rtt, mean_rtt_round, mad_rtt_rounded, stats.min_ttl, stats.max_ttl, mean_ttl_round, ERASE_LINE_END ); }