From 1515d65d102687633e64edf670afd272d502a608 Mon Sep 17 00:00:00 2001 From: Quixaq Date: Wed, 10 Jun 2026 21:18:41 +0200 Subject: [PATCH] feat: configurable colors --- crates/lib/build.rs | 94 ++++++++++++++++++++++++++++++++++++++++ crates/lib/src/colors.rs | 16 +++++++ crates/lib/src/lib.rs | 26 +++++------ crates/lib/src/system.rs | 11 ++++- 4 files changed, 132 insertions(+), 15 deletions(-) create mode 100644 crates/lib/build.rs diff --git a/crates/lib/build.rs b/crates/lib/build.rs new file mode 100644 index 0000000..d2a8f46 --- /dev/null +++ b/crates/lib/build.rs @@ -0,0 +1,94 @@ +use std::{env, fs, path::Path}; + +fn main() { + let mut constants: Vec = Vec::new(); + + constants.push(format!( + "pub const COLOR_LOGO1: &'static str = \"{}\";", + match env::var("COLOR_LOGO1") { + Ok(color) => { + let r = + u32::from_str_radix(&color[1..3], 16).expect("Invalid COLOR_LOGO1"); + let g = + u32::from_str_radix(&color[3..5], 16).expect("Invalid COLOR_LOGO1"); + let b = + u32::from_str_radix(&color[5..7], 16).expect("Invalid COLOR_LOGO1"); + format!("\\x1b[38;2;{r};{g};{b};m") + }, + Err(_) => "\x1b[34m".to_string(), + } + )); + + constants.push(format!( + "pub const COLOR_LOGO2: &'static str = \"{}\";", + match env::var("COLOR_LOGO2") { + Ok(color) => { + let r = + u32::from_str_radix(&color[1..3], 16).expect("Invalid COLOR_LOGO2"); + let g = + u32::from_str_radix(&color[3..5], 16).expect("Invalid COLOR_LOGO2"); + let b = + u32::from_str_radix(&color[5..7], 16).expect("Invalid COLOR_LOGO2"); + format!("\\x1b[38;2;{r};{g};{b};m") + }, + Err(_) => "\x1b[36m".to_string(), + } + )); + + constants.push(format!( + "pub const COLOR_ICON: &'static str = \"{}\";", + match env::var("COLOR_ICON") { + Ok(color) => { + let r = + u32::from_str_radix(&color[1..3], 16).expect("Invalid COLOR_ICON"); + let g = + u32::from_str_radix(&color[3..5], 16).expect("Invalid COLOR_ICON"); + let b = + u32::from_str_radix(&color[5..7], 16).expect("Invalid COLOR_ICON"); + format!("\\x1b[38;2;{r};{g};{b};m") + }, + Err(_) => "\x1b[36m".to_string(), + } + )); + + constants.push(format!( + "pub const COLOR_KEY: &'static str = \"{}\";", + match env::var("COLOR_KEY") { + Ok(color) => { + let r = + u32::from_str_radix(&color[1..3], 16).expect("Invalid COLOR_KEY"); + let g = + u32::from_str_radix(&color[3..5], 16).expect("Invalid COLOR_KEY"); + let b = + u32::from_str_radix(&color[5..7], 16).expect("Invalid COLOR_KEY"); + format!("\\x1b[38;2;{r};{g};{b};m") + }, + Err(_) => "\x1b[34m".to_string(), + } + )); + + let val = match env::var("COLOR_VALUE") { + Ok(color) => { + let r = + u32::from_str_radix(&color[1..3], 16).expect("Invalid COLOR_VALUE"); + let g = + u32::from_str_radix(&color[3..5], 16).expect("Invalid COLOR_VALUE"); + let b = + u32::from_str_radix(&color[5..7], 16).expect("Invalid COLOR_VALUE"); + format!("\\x1b[38;2;{r};{g};{b};m") + }, + Err(_) => "".to_string(), + }; + constants.push(format!("pub const COLOR_VAL: &'static str = \"{}\";", val)); + + let out_dir = env::var("OUT_DIR").unwrap(); + let path1 = Path::new(&out_dir).join("colors_config.rs"); + let code = constants.join("\n"); + fs::write(path1, code).unwrap(); + let path2 = Path::new(&out_dir).join("color_helpers.rs"); + fs::write( + path2, + format!("pub const RPAREN: &'static str = \"{})\";\n", val), + ) + .unwrap(); +} diff --git a/crates/lib/src/colors.rs b/crates/lib/src/colors.rs index 8373b3d..0ee8973 100644 --- a/crates/lib/src/colors.rs +++ b/crates/lib/src/colors.rs @@ -1,3 +1,4 @@ +include!(concat!(env!("OUT_DIR"), "/colors_config.rs")); use crate::StackWriter; /// Color codes for terminal output. @@ -9,6 +10,11 @@ pub struct Colors { pub yellow: &'static str, pub red: &'static str, pub magenta: &'static str, + pub l1: &'static str, + pub l2: &'static str, + pub icon: &'static str, + pub key: &'static str, + pub value: &'static str, } impl Colors { @@ -23,6 +29,11 @@ impl Colors { yellow: "", red: "", magenta: "", + l1: "", + l2: "", + icon: "", + key: "", + value: "", } } else { Self { @@ -33,6 +44,11 @@ impl Colors { yellow: "\x1b[33m", red: "\x1b[31m", magenta: "\x1b[35m", + l1: COLOR_LOGO1, + l2: COLOR_LOGO2, + icon: COLOR_ICON, + key: COLOR_KEY, + value: COLOR_VAL, } } } diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index 1e0efc8..2be5b90 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -289,7 +289,7 @@ fn write_styled_row( colors: &colors::Colors, stream: &mut &[u8], ) { - let palette = [colors.blue, colors.cyan, colors.reset]; + let palette = [colors.l1, colors.l2, colors.icon, colors.key, colors.value, colors.reset]; let data = *stream; let row_end = data .iter() @@ -300,12 +300,12 @@ fn write_styled_row( let mut pos = 0; while pos < row_data.len() { - if let marker @ 1..=3 = row_data[pos] { + if let marker @ 1..=6 = row_data[pos] { writer.push_str(palette[usize::from(marker - 1)]); pos += 1; } else { let chunk_start = pos; - while pos < row_data.len() && row_data[pos] > 3 { + while pos < row_data.len() && row_data[pos] > 6 { pos += 1; } writer.push_bytes(&row_data[chunk_start..pos]); @@ -315,16 +315,16 @@ fn write_styled_row( const ROW_COUNT: usize = 11; const ROW_LABELS: &[u8] = concat!( - "\x02\u{F313} \x01System\x03 \u{E621} \0", - "\x02\u{E712} \x01Kernel\x03 \u{E621} \0", - "\x02\u{F2DB} \x01CPU\x03 \u{E621} \0", - "\x02\u{F4BC} \x01Topology\x03 \u{E621} \0", - "\x02\u{E795} \x01Shell\x03 \u{E621} \0", - "\x02\u{F017} \x01Uptime\x03 \u{E621} \0", - "\x02\u{F2D2} \x01Desktop\x03 \u{E621} \0", - "\x02\u{F035B} \x01Memory\x03 \u{E621} \0", - "\x02\u{F194E} \x01Storage (/)\x03 \u{E621} \0", - "\x02\u{E22B} \x01Colors\x03 \u{E621} \0", + "\x03\u{F313} \x04System\x05 \u{E621} \0", + "\x03\u{E712} \x04Kernel\x05 \u{E621} \0", + "\x03\u{F2DB} \x04CPU\x05 \u{E621} \0", + "\x03\u{F4BC} \x04Topology\x05 \u{E621} \0", + "\x03\u{E795} \x04Shell\x05 \u{E621} \0", + "\x03\u{F017} \x04Uptime\x05 \u{E621} \0", + "\x03\u{F2D2} \x04Desktop\x05 \u{E621} \0", + "\x03\u{F035B} \x04Memory\x05 \u{E621} \0", + "\x03\u{F194E} \x04Storage (/)\x05 \u{E621} \0", + "\x03\u{E22B} \x04Colors\x05 \u{E621} \0", ) .as_bytes(); diff --git a/crates/lib/src/system.rs b/crates/lib/src/system.rs index 19c2e13..76670b0 100644 --- a/crates/lib/src/system.rs +++ b/crates/lib/src/system.rs @@ -1,3 +1,4 @@ +include!(concat!(env!("OUT_DIR"), "/color_helpers.rs")); use core::mem::MaybeUninit; #[cfg(target_os = "linux")] @@ -112,11 +113,14 @@ pub fn write_memory_usage(writer: &mut StackWriter, colors: &Colors) { .checked_div(total_bytes) .unwrap_or(0); + let no_color = crate::colors::is_no_color(); + let colors = Colors::new(no_color); + write_gib(writer, used_bytes); writer.push_str(" GiB / "); write_gib(writer, total_bytes); writer.push_str(" GiB ("); - writer.push_str(colors.cyan); + writer.push_str(colors.icon); writer.push_u64(percentage_used); writer.push_byte(b'%'); writer.push_str(colors.reset); @@ -175,11 +179,14 @@ pub fn write_memory_usage(writer: &mut StackWriter, colors: &Colors) { .checked_div(total_kb) .unwrap_or(0); + let no_color = crate::colors::is_no_color(); + let colors = Colors::new(no_color); + write_kb_as_gib(writer, used_kb); writer.push_str(" GiB / "); write_kb_as_gib(writer, total_kb); writer.push_str(" GiB ("); - writer.push_str(colors.cyan); + writer.push_str(colors.icon); writer.push_u64(percentage_used); writer.push_byte(b'%'); writer.push_str(colors.reset);