diff --git a/src/args.rs b/src/args.rs index bc60216..e99c145 100644 --- a/src/args.rs +++ b/src/args.rs @@ -22,6 +22,8 @@ pub fn get_args() -> ArgsResult { } else if arg.starts_with("--interval-sec=") { let (_, back) = arg.split_at(15); map.insert("interval-sec".into(), back.into()); + } else if arg == "--acpi-builtin" { + map.insert("acpi-builtin".into(), String::new()); } else if arg.starts_with("--regex-cmd=") { let (_, back) = arg.split_at(12); regex_cmds.push(back.to_owned()); @@ -52,6 +54,11 @@ pub fn print_usage() { b" --interval-sec=\t\t\t\tOutput at intervals of (default 5)\n", ) .ok(); + stderr_handle + .write_all( + b" --acpi-builtin\t\t\t\tUse \"acpi -b\" built-in fetching (battery info, with color)\n", + ) + .ok(); stderr_handle .write_all( b" --regex-cmd=[SPLIT][SPLIT]\tUse an output of a command as a metric\n", diff --git a/src/builtin.rs b/src/builtin.rs new file mode 100644 index 0000000..8175425 --- /dev/null +++ b/src/builtin.rs @@ -0,0 +1,101 @@ +use std::process::Command; + +use crate::swaybar_object::SwaybarObject; +use regex::Regex; + +#[derive(Debug)] +pub struct BattInfo { + regex: Regex, + acpi_error: bool, +} + +impl Default for BattInfo { + fn default() -> Self { + Self { + regex: Regex::new("([0-9]+)%.*").expect("Should be able to compile regex"), + acpi_error: false, + } + } +} + +impl BattInfo { + pub fn is_error_state(&self) -> bool { + self.acpi_error + } + + pub fn update(&mut self, object: &mut SwaybarObject) -> Result<(), ()> { + if self.acpi_error { + return Err(()); + } + let output_string: String; + let output_percentage: u8; + if let Ok(string) = self.get_acpi_string() { + (output_string, output_percentage) = string; + + let percentage: f32 = output_percentage as f32 / 100.0f32; + let red: u8 = if percentage > 0.5f32 { + (255.0f32 * (1.0f32 - (percentage - 0.5f32) * 2.0f32)) as u8 + } else { + 255u8 + }; + let green: u8 = if percentage > 0.5f32 { + 255u8 + } else { + (255.0f32 * percentage * 2.0f32) as u8 + }; + let color: String = format!("#{:x}{:x}00ff", red, green); + + object.update_as_generic(output_string, Some(color)); + + Ok(()) + } else { + self.acpi_error = true; + Err(()) + } + } + + fn get_acpi_string(&mut self) -> Result<(String, u8), ()> { + if self.acpi_error { + return Err(()); + } + let mut cmd_builder = Command::new("acpi"); + cmd_builder.arg("-b"); + let output_result = cmd_builder.output(); + if let Ok(output_unwrapped) = output_result { + let string_result = String::from_utf8(output_unwrapped.stdout); + if let Ok(string) = string_result { + let regex_captures_result = self.regex.captures(&string); + if regex_captures_result.is_none() { + self.acpi_error = true; + return Err(()); + } + let regex_captures = regex_captures_result.unwrap(); + let full_result = regex_captures.get(0); + if full_result.is_none() { + self.acpi_error = true; + return Err(()); + } + let full_string = full_result.unwrap().as_str().to_owned(); + let percentage_result = regex_captures.get(1); + if percentage_result.is_none() { + self.acpi_error = true; + return Err(()); + } + let percentage_result = percentage_result.unwrap().as_str().parse::(); + if percentage_result.is_err() { + self.acpi_error = true; + return Err(()); + } + let percentage: u8 = percentage_result.unwrap(); + + Ok((full_string, percentage)) + } else { + self.acpi_error = true; + Err(()) + } + } else { + self.acpi_error = true; + Err(()) + } + } +} diff --git a/src/main.rs b/src/main.rs index ab008f6..25204b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod args; +mod builtin; mod external; mod proc; mod swaybar_object; @@ -72,6 +73,12 @@ fn main() { } } + let mut batt_info: builtin::BattInfo = Default::default(); + { + let mut temp_object = SwaybarObject::new("battinfo".to_owned()); + batt_info.update(&mut temp_object).ok(); + } + println!( "{}", serde_json::to_string(&swaybar_object::SwaybarHeader::new()) @@ -204,6 +211,20 @@ fn main() { } } + // batt_info + if !batt_info.is_error_state() { + if is_empty { + let mut new_object = SwaybarObject::new("battinfo".to_owned()); + if batt_info.update(&mut new_object).is_ok() { + array.push_object(new_object); + } + } else if let Some(obj) = array.get_by_name_mut("battinfo") { + if batt_info.update(obj).is_err() { + obj.update_as_error("BATTINFO ERROR".to_owned()); + } + } + } + // loadavg { let loadavg_result = proc::get_loadavg();