diff --git a/src/main.rs b/src/main.rs index ebcaa97..113b2cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,6 +46,7 @@ fn main() { let mut net_obj: Option = None; let mut net_width: Option = Some(10); let mut net_graph_max: Option = None; + let mut net_graph_is_dynamic: bool = false; let mut interval: Duration = Duration::from_secs(5); if args_result.map.contains_key("netdev") { net_obj = Some(proc::NetInfo::new( @@ -67,19 +68,23 @@ fn main() { } } if args_result.map.contains_key("netgraph") { - let graph_max_result: Result = args_result.map.get("netgraph").unwrap().parse(); - if let Ok(graph_max) = graph_max_result { - net_graph_max = Some(graph_max); + if args_result.map.get("netgraph").as_ref().unwrap() == &"dynamic" { + net_graph_is_dynamic = true; } else { - let mut stderr_handle = io::stderr().lock(); - stderr_handle - .write_all( - format!( - "WARNING: Invalid value passed to --netgraph_max_bytes=..., ignoring...\n" + let graph_max_result: Result = args_result.map.get("netgraph").unwrap().parse(); + if let Ok(graph_max) = graph_max_result { + net_graph_max = Some(graph_max); + } else { + let mut stderr_handle = io::stderr().lock(); + stderr_handle + .write_all( + format!( + "WARNING: Invalid value passed to --netgraph_max_bytes=..., ignoring...\n" + ) + .as_bytes(), ) - .as_bytes(), - ) - .ok(); + .ok(); + } } } if args_result.map.contains_key("interval-sec") { @@ -126,7 +131,7 @@ fn main() { let mut array = SwaybarArray::new(); let set_net_error = |is_empty: bool, array: &mut SwaybarArray, graph_max_opt: &Option| { if is_empty { - if graph_max_opt.is_some() { + if graph_max_opt.is_some() || net_graph_is_dynamic { array.push_object(SwaybarObject::from_error_string( "net_graph".to_owned(), "net ERROR".into(), @@ -140,7 +145,7 @@ fn main() { let up_obj = SwaybarObject::from_error_string("net_up".to_owned(), "Net ERROR".into()); array.push_object(up_obj); } else { - if graph_max_opt.is_some() { + if graph_max_opt.is_some() || net_graph_is_dynamic { if let Some(graph_ref) = array.get_by_name_mut("net_graph") { graph_ref.update_as_error("Net ERROR".to_owned()); } @@ -167,7 +172,7 @@ fn main() { let netinfo_parts: Vec<&str> = netinfo_string.split_whitespace().collect(); if is_empty { - if net_graph_max.is_some() { + if net_graph_max.is_some() || net_graph_is_dynamic { let mut graph_obj = SwaybarObject::from_string("net_graph".to_owned(), graph_string); graph_obj.color = Some("#ffff88".into()); @@ -205,7 +210,7 @@ fn main() { array.push_object(up_object); } } else { - if net_graph_max.is_some() { + if net_graph_max.is_some() || net_graph_is_dynamic { if let Some(graph_obj) = array.get_by_name_mut("net_graph") { graph_obj.full_text = graph_string; } diff --git a/src/proc.rs b/src/proc.rs index 69bb6e3..d5a4dfb 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -59,10 +59,12 @@ impl std::error::Error for Error { pub struct NetInfo { dev_name: String, graph: String, + graph_history: [f64; 10], down: u64, prev_down: u64, up: u64, prev_up: u64, + first_iteration: bool, } impl NetInfo { @@ -70,10 +72,12 @@ impl NetInfo { Self { dev_name, graph: String::from(" "), + graph_history: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], down: 0, prev_down: 0, up: 0, prev_up: 0, + first_iteration: true, } } @@ -98,8 +102,13 @@ impl NetInfo { return Err(format!("NetInfo::update: Failed to parse /proc/net/dev, \"{}\" device line is too short", self.dev_name).into()); } - self.down = entries[1].parse()?; - self.up = entries[9].parse()?; + if !self.first_iteration { + self.down = entries[1].parse()?; + self.up = entries[9].parse()?; + } else { + self.prev_down = entries[1].parse()?; + self.prev_up = entries[9].parse()?; + } } else { return Err(format!( "NetInfo::update: Failed to parse /proc/net/dev, can't find net device \"{}\"", @@ -108,14 +117,26 @@ impl NetInfo { .into()); } + self.first_iteration = false; + Ok(()) } - pub fn get_netstring(&mut self, graph_max: Option) -> Result<(String, String), Error> { - let down_diff: f64 = (self.down - self.prev_down) as f64; - self.prev_down = self.down; - let up_diff: f64 = (self.up - self.prev_up) as f64; - self.prev_up = self.up; + pub fn get_netstring(&mut self, graph_max_opt: Option) -> Result<(String, String), Error> { + let down_diff: f64 = if self.down > self.prev_down { + let value = (self.down - self.prev_down) as f64; + self.prev_down = self.down; + value + } else { + 0.0 + }; + let up_diff: f64 = if self.up > self.prev_up { + let value = (self.up - self.prev_up) as f64; + self.prev_up = self.up; + value + } else { + 0.0 + }; let mut output = String::new(); if down_diff > 1024.0 * 1024.0 { @@ -134,12 +155,13 @@ impl NetInfo { write!(&mut output, "{:.0} B", up_diff)?; } - if let Some(graph_max) = graph_max { - let diff_max = if down_diff > up_diff { - down_diff - } else { - up_diff - }; + let diff_max = if down_diff > up_diff { + down_diff + } else { + up_diff + }; + + if let Some(graph_max) = graph_max_opt { let graph_value: u8 = if diff_max > graph_max { 8 } else { @@ -158,6 +180,36 @@ impl NetInfo { 7 => self.graph.push('▇'), _ => self.graph.push('█'), } + } else { + self.graph_history.rotate_left(1); + self.graph_history[9] = diff_max; + + let mut history_max: f64 = 0.0; + for value in &self.graph_history { + if history_max < *value { + history_max = *value; + } + } + + self.graph.clear(); + if history_max == 0.0 { + self.graph = String::from(" "); + } else { + for value in &self.graph_history { + match (8.0 * value / history_max).round() as u8 { + 0 => self.graph.push(' '), + 1 => self.graph.push('▁'), + 2 => self.graph.push('▂'), + 3 => self.graph.push('▃'), + 4 => self.graph.push('▄'), + 5 => self.graph.push('▅'), + 6 => self.graph.push('▆'), + 7 => self.graph.push('▇'), + _ => self.graph.push('█'), + } + } + } + assert_eq!(self.graph_history.len(), 10); } Ok((output, self.graph.clone()))