diff --git a/src/main.rs b/src/main.rs index 85f26d3..912fc6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,8 +52,29 @@ fn main() { ); println!("["); + let mut array = SwaybarArray::new(); + let set_net_error = |is_empty: bool, array: &mut SwaybarArray| { + if is_empty { + let down_obj = SwaybarObject::from_string("net_down".to_owned(), "Net ERROR".into()); + array.push_object(down_obj); + + let up_obj = SwaybarObject::from_string("net_up".to_owned(), "Net ERROR".into()); + array.push_object(up_obj); + } else { + let down_ref_opt = array.get_by_name_mut("net_down"); + if let Some(down_ref) = down_ref_opt { + down_ref.update_as_error("Net ERROR".to_owned()); + } + + let up_ref_opt = array.get_by_name_mut("net_up"); + if let Some(up_ref) = up_ref_opt { + up_ref.update_as_error("Net ERROR".to_owned()); + } + } + }; + loop { - let mut array = SwaybarArray::new(); + let is_empty = array.is_empty(); // network traffic if let Some(net) = &mut net_obj { @@ -61,31 +82,51 @@ fn main() { let mut stderr_handle = io::stderr().lock(); stderr_handle.write_all(e.to_string().as_bytes()).ok(); net_obj = None; + set_net_error(is_empty, &mut array); } else { let netinfo_result = net.get_netstring(); if let Err(e) = netinfo_result { - let mut stderr_handle = io::stderr().lock(); - stderr_handle.write_all(e.to_string().as_bytes()).ok(); + { + let mut stderr_handle = io::stderr().lock(); + stderr_handle.write_all(e.to_string().as_bytes()).ok(); + } + set_net_error(is_empty, &mut array); } else { let netinfo_string = netinfo_result.unwrap(); let netinfo_parts: Vec<&str> = netinfo_string.split_whitespace().collect(); - { - let mut down_object = SwaybarObject::from_string(format!( - "{} {}", - netinfo_parts[0], netinfo_parts[1] - )); - down_object.color = Some("#ff8888ff".into()); - array.push_object(down_object); - } + if is_empty { + { + let mut down_object = SwaybarObject::from_string( + "net_down".to_owned(), + format!("{} {}", netinfo_parts[0], netinfo_parts[1]), + ); + down_object.color = Some("#ff8888ff".into()); + array.push_object(down_object); + } - { - let mut up_object = SwaybarObject::from_string(format!( - "{} {}", - netinfo_parts[2], netinfo_parts[3] - )); - up_object.color = Some("#88ff88ff".into()); - array.push_object(up_object); + { + let mut up_object = SwaybarObject::from_string( + "net_up".to_owned(), + format!("{} {}", netinfo_parts[2], netinfo_parts[3]), + ); + up_object.color = Some("#88ff88ff".into()); + array.push_object(up_object); + } + } else { + if let Some(down_object) = array.get_by_name_mut("net_down") { + down_object.update_as_net_down(format!( + "{} {}", + netinfo_parts[0], netinfo_parts[1] + )); + } + + if let Some(up_object) = array.get_by_name_mut("net_up") { + up_object.update_as_net_up(format!( + "{} {}", + netinfo_parts[2], netinfo_parts[3] + )); + } } } } @@ -101,8 +142,14 @@ fn main() { } else { meminfo_result.unwrap() }; - let meminfo_obj = SwaybarObject::from_string(meminfo_string); - array.push_object(meminfo_obj); + if is_empty { + let meminfo_obj = SwaybarObject::from_string("meminfo".to_owned(), meminfo_string); + array.push_object(meminfo_obj); + } else { + if let Some(meminfo_obj) = array.get_by_name_mut("meminfo") { + meminfo_obj.update_as_generic(meminfo_string, None); + } + } } // loadavg @@ -115,13 +162,21 @@ fn main() { } else { loadavg_result.unwrap() }; - let loadavg_obj = SwaybarObject::from_string(loadavg_string); - array.push_object(loadavg_obj); + if is_empty { + let loadavg_obj = SwaybarObject::from_string("loadavg".to_owned(), loadavg_string); + array.push_object(loadavg_obj); + } else { + if let Some(loadavg_obj) = array.get_by_name_mut("loadavg") { + loadavg_obj.update_as_generic(loadavg_string, None); + } + } } // time - { + if is_empty { array.push_object(SwaybarObject::default()); + } else if let Some(time_obj) = array.get_by_name_mut("current_time") { + time_obj.update_as_date(); } println!("{}", array); diff --git a/src/swaybar_object.rs b/src/swaybar_object.rs index cedeae1..d0ac887 100644 --- a/src/swaybar_object.rs +++ b/src/swaybar_object.rs @@ -1,4 +1,7 @@ -use std::fmt::Display; +use std::{ + fmt::Display, + ops::{Index, IndexMut}, +}; use chrono::prelude::*; use serde::{Deserialize, Serialize}; @@ -68,7 +71,7 @@ impl SwaybarHeader { } impl SwaybarObject { - pub fn new() -> Self { + pub fn new(name: String) -> Self { Self { full_text: String::new(), short_text: None, @@ -81,7 +84,7 @@ impl SwaybarObject { border_right: None, min_width: None, align: None, - name: None, + name: Some(name), instance: None, urgent: None, separator: None, @@ -90,7 +93,7 @@ impl SwaybarObject { } } - pub fn from_string(string: String) -> Self { + pub fn from_string(name: String, string: String) -> Self { Self { full_text: string, short_text: None, @@ -103,7 +106,7 @@ impl SwaybarObject { border_right: None, min_width: None, align: None, - name: None, + name: Some(name), instance: None, urgent: None, separator: None, @@ -111,6 +114,41 @@ impl SwaybarObject { markup: None, } } + + pub fn update_as_net_down(&mut self, metric: String) { + self.full_text = metric; + self.color = Some("#ff8888ff".to_owned()); + } + + pub fn update_as_net_up(&mut self, metric: String) { + self.full_text = metric; + self.color = Some("#88ff88ff".to_owned()); + } + + pub fn update_as_date(&mut self) { + let current_time: DateTime = Local::now(); + let current_time = current_time.format("%F %r"); + self.full_text = current_time.to_string(); + self.color = None; + } + + pub fn update_as_generic(&mut self, metric: String, color: Option) { + self.full_text = metric; + self.color = color; + } + + pub fn update_as_error(&mut self, msg: String) { + self.full_text = msg; + self.color = Some("#ff2222ff".to_owned()); + } + + pub fn set_name(&mut self, name: Option) { + self.name = name; + } + + pub fn get_name(&self) -> Option<&str> { + self.name.as_deref() + } } impl Default for SwaybarObject { @@ -129,7 +167,7 @@ impl Default for SwaybarObject { border_right: None, min_width: None, align: None, - name: None, + name: Some("current_time".to_owned()), instance: None, urgent: None, separator: None, @@ -149,6 +187,50 @@ impl SwaybarArray { pub fn push_object(&mut self, object: SwaybarObject) { self.objects.push(object); } + + pub fn is_empty(&self) -> bool { + self.objects.is_empty() + } + + // TODO this is linear, and it probably is possible to improve this + pub fn get_by_name(&self, name: &str) -> Option<&SwaybarObject> { + for object in &self.objects { + if let Some(object_name) = object.get_name() { + if object_name == name { + return Some(object); + } + } + } + + None + } + + // TODO this is linear, and it probably is possible to improve this + pub fn get_by_name_mut(&mut self, name: &str) -> Option<&mut SwaybarObject> { + for object in &mut self.objects { + if let Some(object_name) = object.get_name() { + if object_name == name { + return Some(object); + } + } + } + + None + } +} + +impl Index for SwaybarArray { + type Output = SwaybarObject; + + fn index(&self, index: usize) -> &Self::Output { + self.objects.index(index) + } +} + +impl IndexMut for SwaybarArray { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + self.objects.index_mut(index) + } } impl Display for SwaybarArray {