diff options
| author | ache <ache@ache.one> | 2026-08-04 18:27:58 +0200 |
|---|---|---|
| committer | ache <ache@ache.one> | 2026-08-04 18:27:58 +0200 |
| commit | b6ce2ea9948cee959e31013221e483eceb9b4a47 (patch) | |
| tree | 727c6df94b340385664372e8cf8e8e80f62b459b | |
| parent | Remove dead code (diff) | |
Linting and format
| -rw-r--r-- | src/args.rs | 2 | ||||
| -rw-r--r-- | src/ip.rs | 32 | ||||
| -rw-r--r-- | src/main.rs | 45 | ||||
| -rw-r--r-- | src/print.rs | 189 | ||||
| -rw-r--r-- | src/stats.rs | 25 |
5 files changed, 203 insertions, 90 deletions
diff --git a/src/args.rs b/src/args.rs index 09de553..fb5d6c1 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,4 +1,4 @@ -use clap::{Parser, ArgAction}; +use clap::{ArgAction, Parser}; #[derive(Parser, Debug)] #[command(name = "ping")] @@ -29,7 +29,7 @@ pub fn parse_bsd_ipv4(s: &str) -> Result<Ipv4Addr, String> { let parts: Vec<&str> = s.split('.').collect(); let n = parts.len(); - if n < 1 || n > 4 { + if !(1..=4).contains(&n) { return Err("invalid number of parts".into()); } @@ -41,33 +41,31 @@ pub fn parse_bsd_ipv4(s: &str) -> Result<Ipv4Addr, String> { let addr: u32 = match n { 4 => { - if parsed_parts[0] > 0xFF || parsed_parts[1] > 0xFF || - parsed_parts[2] > 0xFF || parsed_parts[3] > 0xFF { + if parsed_parts[0] > 0xFF + || parsed_parts[1] > 0xFF + || parsed_parts[2] > 0xFF + || parsed_parts[3] > 0xFF + { return Err("invalid IP part out of range".into()); } - (parsed_parts[0] << 24) | - (parsed_parts[1] << 16) | - (parsed_parts[2] << 8) | - parsed_parts[3] + (parsed_parts[0] << 24) + | (parsed_parts[1] << 16) + | (parsed_parts[2] << 8) + | parsed_parts[3] } 3 => { if parsed_parts[0] > 0xFF || parsed_parts[1] > 0xFF || parsed_parts[2] > 0xFFFF { return Err("invalid IP part out of range".into()); } - (parsed_parts[0] << 24) | - (parsed_parts[1] << 16) | - parsed_parts[2] + (parsed_parts[0] << 24) | (parsed_parts[1] << 16) | parsed_parts[2] } 2 => { if parsed_parts[0] > 0xFF || parsed_parts[1] > 0xFFFFFF { return Err("invalid IP part out of range".into()); } - (parsed_parts[0] << 24) | - parsed_parts[1] - } - 1 => { - parsed_parts[0] + (parsed_parts[0] << 24) | parsed_parts[1] } + 1 => parsed_parts[0], _ => { return Err("invalid number of parts".into()); } @@ -81,11 +79,11 @@ pub fn parse_ip(s: &str) -> Result<IpAddr, String> { if let Ok(ip) = s.parse::<Ipv6Addr>() { return Ok(IpAddr::V6(ip)); } - + // Try to parse as BSD valid IPv4 if let Ok(ipv4) = parse_bsd_ipv4(s) { return Ok(IpAddr::V4(ipv4)); } - + Err(format!("invalid IP address: {}", s)) } diff --git a/src/main.rs b/src/main.rs index 5f4f1e0..d5e1588 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ mod state; mod stats; use args::Args; use ip::parse_ip; -use pinger::{spawn_ping, PingResult}; +use pinger::{PingResult, spawn_ping}; use print::{print_legende_line, print_ping_line, print_stats}; use state::State; use stats::compute_stats; @@ -36,31 +36,36 @@ async fn main() { let mut states: Vec<State> = Vec::new(); let mut packet_id: u32 = 0; - print_legende_line(); // Save the current cursor position - if !std::process::Command::new("tput").arg("sc").status().map(|s| s.success()).unwrap_or(false) { + if !std::process::Command::new("tput") + .arg("sc") + .status() + .map(|s| s.success()) + .unwrap_or(false) + { println!("Process failed"); std::process::exit(1); } - // Should be quit with Ctrl + C loop { - let current_time = State::current_time_ms(); for state in states.iter_mut() { if let State::NotYetReceived { time_sent } = state { // TODO: 2000ms Should be a configurable variable - if current_time - *time_sent > 2000 { // 2s = 2000ms + if current_time - *time_sent > 2000 { + // 2s = 2000ms *state = State::Lost; } } } // Send the ping - states.push(State::NotYetReceived { time_sent: current_time }); + states.push(State::NotYetReceived { + time_sent: current_time, + }); spawn_ping(target, tx.clone(), packet_id); packet_id += 1; @@ -68,18 +73,16 @@ async fn main() { loop { match rx.try_recv() { // Update the state of the received packet - Ok(result) => { - match result { - PingResult::Ping { rtt, ttl, id } => { - if (id as usize) < states.len() { - states[id as usize] = State::Received { rtt: rtt, ttl }; - } - } - PingResult::NoPingErr { id } => { - states[id as usize] = State::SendError; + Ok(result) => match result { + PingResult::Ping { rtt, ttl, id } => { + if (id as usize) < states.len() { + states[id as usize] = State::Received { rtt, ttl }; } } - } + PingResult::NoPingErr { id } => { + states[id as usize] = State::SendError; + } + }, Err(TryRecvError::Disconnected) => { eprintln!("Critical error, pinger thread killed"); std::process::exit(2); @@ -92,7 +95,12 @@ async fn main() { } // Put the cursor back up - if !std::process::Command::new("tput").arg("rc").status().map(|s| s.success()).unwrap_or(false) { + if !std::process::Command::new("tput") + .arg("rc") + .status() + .map(|s| s.success()) + .unwrap_or(false) + { println!("Process failed too"); std::process::exit(1); } @@ -116,7 +124,6 @@ async fn main() { } } - // Sleep for 1 second before the next ping // FEAT: Should be configurable via CLI sleep(tokio::time::Duration::from_millis(1000)).await; diff --git a/src/print.rs b/src/print.rs index 28e1b9e..421efa3 100644 --- a/src/print.rs +++ b/src/print.rs @@ -9,61 +9,166 @@ struct SymbolTableElement { character: &'static str, } -const GREEN_FG :&str = "\x1b[32m"; -const ORANGE_FG :&str = "\x1b[38;5;208m"; -const RED_FG :&str = "\x1b[31m"; +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 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 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: "?"} +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); + print!( + "{} {}{}{}\x1b[0m ", + val, element.fg, element.bg, element.character + ); } - println!(""); + println!(); } +// TODO: Simplify this function pub fn print_ping_line(states: &Vec<State>) { 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"); + print!("{}{}{}{}", fg, bg, symbol, RESET); } State::Lost => { let (fg, bg, symbol) = get_symbol_and_colors_for_rrt(250); - print!("{}{}{}{}", fg, bg, symbol, "\x1b[0m"); + print!("{}{}{}{}", fg, bg, symbol, RESET); } State::NotYetReceived { .. } => { // fg grey, bg black @@ -75,16 +180,12 @@ pub fn print_ping_line(states: &Vec<State>) { } } - println!(""); + 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]; + let index: usize = if rrt >= 240 { 24 } else { rrt / 10 } as usize; + let SymbolTableElement { fg, bg, character } = CHARS_TABLE[index]; (fg, bg, character) } diff --git a/src/stats.rs b/src/stats.rs index 1d2f451..db99fb4 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -21,7 +21,10 @@ pub fn compute_stats(states: &[crate::state::State]) -> Option<Stats> { let mut rtts: Vec<u64> = Vec::new(); let mut ttls: Vec<u32> = Vec::new(); - let received = states.iter().filter(|state| matches!(state, crate::state::State::Received { .. })).count(); + let received = states + .iter() + .filter(|state| matches!(state, crate::state::State::Received { .. })) + .count(); let lost = states.len() - received; if received == 0 { @@ -42,7 +45,11 @@ pub fn compute_stats(states: &[crate::state::State]) -> Option<Stats> { let sum_rtt: u64 = rtts.iter().sum(); let avg_rtt = sum_rtt as f64 / rtts.len() as f64; - let mad_rtt: f64 = rtts.iter().map(|&x| (x as f64 - avg_rtt).abs()).sum::<f64>() / rtts.len() as f64; + let mad_rtt: f64 = rtts + .iter() + .map(|&x| (x as f64 - avg_rtt).abs()) + .sum::<f64>() + / rtts.len() as f64; // TTL stats let min_ttl = ttls.iter().min().copied().unwrap(); @@ -51,15 +58,15 @@ pub fn compute_stats(states: &[crate::state::State]) -> Option<Stats> { let sum_ttl: u32 = ttls.iter().sum(); let avg_ttl = sum_ttl as f64 / ttls.len() as f64; - Some(Stats { + Some(Stats { received, lost, - min_rtt, - max_rtt, - avg_rtt, + min_rtt, + max_rtt, + avg_rtt, mad_rtt, - min_ttl, - max_ttl, - avg_ttl + min_ttl, + max_ttl, + avg_ttl, }) } |