corsairctl/src/output.rs
nevaforget c5f8625345 feat: initiale Implementierung von corsairctl
Rust CLI-Tool für Corsair Bragi-Geräte (HS80 RGB Wireless, etc.).
Implementiert Protokoll-Kern, HID-Kommunikation, BragiDevice mit
RAII-Lifecycle, CLI-Subcommands (battery, sidetone, led, info, json,
udev), ALSA-Sidetone-Steuerung und Waybar-JSON-Output.

24 Unit-Tests für Packet-Bau, Response-Parsing und Property-Enums.
2026-03-27 17:34:37 +01:00

58 lines
2.0 KiB
Rust

// ABOUTME: Formatierung für Plain-Text und Waybar-JSON Output.
// ABOUTME: Konvertiert Gerätedaten in lesbaren Text oder Waybar-kompatibles JSON.
use crate::bragi::properties::BatteryStatus;
/// Formatiert Batterie-Informationen als Plain-Text.
pub fn format_battery(level: f32, status: &BatteryStatus) -> String {
format!("Battery: {level:.0}% ({status})", status = status.label())
}
/// Formatiert LED-Helligkeit als Plain-Text.
pub fn format_brightness(value: u16) -> String {
let percent = value as f32 / 10.0;
format!("LED Brightness: {value}/1000 ({percent:.0}%)")
}
/// Formatiert Geräteinformationen als Plain-Text.
pub fn format_info(vid: u16, pid: u16, fw_app: u16, fw_build: u16) -> String {
format!(
"Vendor ID: 0x{vid:04X}\n\
Product ID: 0x{pid:04X}\n\
Firmware: {fw_app}.{fw_build}"
)
}
/// Formatiert Waybar-kompatibles JSON.
///
/// Waybar erwartet: {"text": "...", "tooltip": "...", "class": "...", "percentage": N}
pub fn format_waybar_json(level: f32, status: &BatteryStatus) -> String {
let icon = status.icon();
let label = status.label();
let percentage = level.round() as u32;
let class = match status {
BatteryStatus::Charging | BatteryStatus::FullyCharged => "charging",
BatteryStatus::Low => "low",
BatteryStatus::Discharging if level <= 15.0 => "critical",
BatteryStatus::Discharging if level <= 30.0 => "warning",
BatteryStatus::Discharging => "normal",
BatteryStatus::Offline => "offline",
BatteryStatus::Unknown(_) => "unknown",
};
let json = serde_json::json!({
"text": format!("{icon} {percentage}%"),
"tooltip": format!("HS80: {percentage}% — {label}"),
"class": class,
"percentage": percentage,
});
serde_json::to_string(&json).expect("JSON-Serialisierung sollte nicht fehlschlagen")
}
/// Formatiert Sidetone-Level als Plain-Text.
pub fn format_sidetone(level: i64) -> String {
format!("Sidetone: {level}/23")
}