refactored cli, extracted menu to cli, removed deprecated
Release / Build and Release (push) Has been cancelled

This commit is contained in:
2026-04-07 11:42:57 +02:00
parent ffdb689ef9
commit eaeba84092
7 changed files with 773 additions and 158 deletions
+76 -1
View File
@@ -1,7 +1,16 @@
//! JSON payload returned to Waybar custom modules.
//! JSON payload returned to Waybar custom modules, plus client-side
//! output formatting utilities.
use serde::{Deserialize, Serialize};
/// Waybar renders in a proportional font — replacing normal spaces with
/// figure-spaces (U+2007) keeps column widths stable across updates.
pub const FIGURE_SPACE: char = '\u{2007}';
/// Zero-width space used as cosmetic padding around module text so Waybar
/// doesn't clip leading/trailing glyphs.
pub const ZERO_WIDTH_SPACE: char = '\u{200B}';
/// A Waybar custom module return value.
///
/// Serialises to the schema Waybar's `return-type: json` expects — the
@@ -21,6 +30,72 @@ pub struct WaybarOutput {
pub percentage: Option<u8>,
}
impl WaybarOutput {
/// A blank output for disabled modules.
pub fn disabled() -> Self {
Self {
text: String::new(),
tooltip: Some("Module disabled".to_string()),
class: Some("disabled".to_string()),
percentage: None,
}
}
/// A user-visible error with tooltip detail.
pub fn error(message: &str) -> Self {
Self {
text: format!("{}Error{}", ZERO_WIDTH_SPACE, ZERO_WIDTH_SPACE),
tooltip: Some(message.to_string()),
class: Some("error".to_string()),
percentage: None,
}
}
}
/// Apply Waybar font-stabilisation to a text string.
///
/// Replaces normal spaces with figure-spaces (unless the string contains
/// markup), and wraps in zero-width spaces for cosmetic padding.
pub fn stabilize_text(text: &str) -> String {
let processed = if text.contains('<') {
text.to_string()
} else {
text.replace(' ', &FIGURE_SPACE.to_string())
};
format!("{}{}{}", ZERO_WIDTH_SPACE, processed, ZERO_WIDTH_SPACE)
}
/// Process an IPC response and print Waybar-compatible JSON to stdout.
///
/// On IPC failure, prints a "Daemon offline" error output and exits
/// non-zero so Waybar surfaces the problem visually.
pub fn print_waybar_response(response: anyhow::Result<String>) {
match response {
Ok(json_str) => match serde_json::from_str::<serde_json::Value>(&json_str) {
Ok(mut val) => {
if let Some(text) = val.get("text").and_then(|t| t.as_str()) {
val["text"] = serde_json::Value::String(stabilize_text(text));
}
println!("{}", serde_json::to_string(&val).unwrap());
}
Err(_) => println!("{}", json_str),
},
Err(e) => {
let err_out = WaybarOutput {
text: format!(
"{}Daemon offline ({}){}",
ZERO_WIDTH_SPACE, e, ZERO_WIDTH_SPACE
),
tooltip: Some(e.to_string()),
class: Some("error".to_string()),
percentage: None,
};
println!("{}", serde_json::to_string(&err_out).unwrap());
std::process::exit(1);
}
}
}
#[cfg(test)]
mod tests {
use super::*;