tmux_applets/
ping.rs

1use std::fmt;
2use std::process::Command;
3
4use colorsys::Rgb;
5
6use crate::common::{parse_colour_param, pct_value_hsl};
7
8#[derive(Debug, PartialEq)]
9pub enum PingAppletError {
10    PingMissingHost,
11    PingError,
12}
13
14impl std::error::Error for PingAppletError {}
15
16impl fmt::Display for PingAppletError {
17    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18        write!(f, "PingAppletError: {:?}", self)
19    }
20}
21
22type Result<T> = std::result::Result<T, PingAppletError>;
23
24fn ping_host(host: &str) -> Result<()> {
25    match Command::new("ping").arg("-q").arg("-c").arg("1").arg("-w").arg("1").arg(host).output() {
26        Ok(output) if output.status.success() => Ok(()),
27        _ => Err(PingAppletError::PingError),
28    }
29}
30
31pub fn applet(args: &[String]) -> Result<()> {
32    let mut host: &str = "";
33    let mut colour_s: Option<f32> = None;
34    let mut colour_l: Option<f32> = None;
35
36    for arg in args {
37        if let Some(s) = parse_colour_param(arg, "s") {
38            if (0.0..=100.0).contains(&s) {
39                colour_s = Some(s);
40            } else {
41                eprintln!("Saturation {s} out of range [0, 100.0]");
42            }
43            continue;
44        };
45        if let Some(l) = parse_colour_param(arg, "l") {
46            if (0.0..=100.0).contains(&l) {
47                colour_l = Some(l);
48            } else {
49                eprintln!("Lightness {l} out of range [0, 100.0]");
50            }
51            continue;
52        }
53
54        if !host.is_empty() {
55            eprintln!("Ignoring extra argument: {arg}");
56            continue;
57        }
58
59        host = arg;
60    }
61
62    if host.is_empty() {
63        return Err(PingAppletError::PingMissingHost);
64    }
65
66    eprintln!("Saturation: {:?} Lightness: {:?}", colour_s, colour_l);
67    eprintln!("Pinging host: {host}");
68
69    let value = match ping_host(host) {
70        // NOTE: These are inverted from what you might expect, as pct_value_hsl grades along a line from green -> red
71        Ok(_) => 0.0,
72        Err(_) => 1.0,
73    };
74
75    let c = pct_value_hsl(value, colour_s, colour_l);
76    let rgb = Rgb::from(&c);
77
78    print!("#[bg={}]  #[default]", rgb.to_hex_string());
79
80    Ok(())
81}