use crate::logging;
use ratatui::{prelude::Stylize, style::Color, text::Span};
use regex::Regex;
use std::process::Command;
static BRIGHTNESS_REGEX: std::sync::LazyLock<Regex> =
std::sync::LazyLock::new(|| Regex::new(r"\d+%").unwrap());
#[derive(Debug)]
pub struct Brightness {
pub level: String,
cached_span_content: String,
}
impl Default for Brightness {
fn default() -> Self {
Self::new()
}
}
impl Brightness {
pub fn new() -> Self {
let level = get_system_brightness().unwrap_or_default();
let cached_span_content = format!(" {}", level);
Self {
level,
cached_span_content,
}
}
pub fn update(&mut self) {
self.level = get_system_brightness().unwrap_or_default();
self.cached_span_content = format!(" {}", self.level);
}
pub fn render_as_spans(&self, colorize: bool) -> Vec<Span<'_>> {
let span = Span::raw(&self.cached_span_content);
if colorize {
vec![span.fg(Color::White)]
} else {
vec![span]
}
}
}
fn get_system_brightness() -> Option<String> {
let output = Command::new("brightnessctl")
.output()
.expect("failed to get brightness");
if output.status.success() {
let brightness_str = str::from_utf8(&output.stdout).unwrap();
let re = &BRIGHTNESS_REGEX;
if let Some(brightness) = re.find(brightness_str).map(|m| m.as_str()) {
return Some(brightness.to_string());
}
logging::log_component_error(
"BRIGHTNESS",
&format!("Failed to parse brightness from output: {}", brightness_str),
);
} else {
logging::log_component_error(
"BRIGHTNESS",
str::from_utf8(&output.stderr).unwrap_or("unknown error"),
);
}
None
}