From 91970655296806fb5c47103aab3c7b6cc9023c1d Mon Sep 17 00:00:00 2001 From: poz Date: Fri, 12 Dec 2025 22:00:47 +0100 Subject: [PATCH] push almost all of colors back to compile time using macros --- benches/benchmark.rs | 2 +- src/colors.rs | 78 ++++++++++++++++---------------------------- src/dots.rs | 33 +++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 11 ++++--- 5 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 src/dots.rs diff --git a/benches/benchmark.rs b/benches/benchmark.rs index 8d62082..da3250a 100644 --- a/benches/benchmark.rs +++ b/benches/benchmark.rs @@ -1,8 +1,8 @@ use criterion::{Criterion, criterion_group, criterion_main}; use microfetch_lib::{ UtsName, - colors::print_dots, desktop::get_desktop_info, + dots::print_dots, release::{get_os_pretty_name, get_system_info}, system::{ get_memory_usage, diff --git a/src/colors.rs b/src/colors.rs index 7c65944..0a7af23 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -1,5 +1,22 @@ use std::sync::LazyLock; +// All this because concat!() doesn't accept const parameters +// See https://github.com/rust-lang/rust/issues/31383 +#[macro_export] +macro_rules! RESET {() => {"\x1b[0m"}} +#[macro_export] +macro_rules! BLUE {() => {"\x1b[34m"}} +#[macro_export] +macro_rules! CYAN {() => {"\x1b[34m"}} +#[macro_export] +macro_rules! GREEN {() => {"\x1b[32m"}} +#[macro_export] +macro_rules! YELLOW {() => {"\x1b[33m"}} +#[macro_export] +macro_rules! RED {() => {"\x1b[31m"}} +#[macro_export] +macro_rules! MAGENTA {() => {"\x1b[35m"}} + pub struct Colors { pub reset: &'static str, pub blue: &'static str, @@ -7,7 +24,6 @@ pub struct Colors { pub green: &'static str, pub yellow: &'static str, pub red: &'static str, - pub magenta: &'static str, } impl Colors { @@ -20,62 +36,26 @@ impl Colors { green: "", yellow: "", red: "", - magenta: "", } } else { Self { - reset: "\x1b[0m", - blue: "\x1b[34m", - cyan: "\x1b[36m", - green: "\x1b[32m", - yellow: "\x1b[33m", - red: "\x1b[31m", - magenta: "\x1b[35m", + reset: RESET!(), + blue: BLUE!(), + cyan: CYAN!(), + green: GREEN!(), + yellow: YELLOW!(), + red: RED!(), } } } } -pub static COLORS: LazyLock = LazyLock::new(|| { +pub static IS_NO_COLOR: LazyLock = LazyLock::new(|| { + // Check for NO_COLOR once at startup const NO_COLOR: *const libc::c_char = c"NO_COLOR".as_ptr(); - let is_no_color = unsafe { !libc::getenv(NO_COLOR).is_null() }; - Colors::new(is_no_color) + unsafe { !libc::getenv(NO_COLOR).is_null() } }); -#[must_use] -#[cfg_attr(feature = "hotpath", hotpath::measure)] -pub fn print_dots() -> String { - // Pre-calculate capacity: 6 color codes + " " (glyph + 2 spaces) per color - const GLYPH: &str = ""; - let capacity = COLORS.blue.len() - + COLORS.cyan.len() - + COLORS.green.len() - + COLORS.yellow.len() - + COLORS.red.len() - + COLORS.magenta.len() - + COLORS.reset.len() - + (GLYPH.len() + 2) * 6; - - let mut result = String::with_capacity(capacity); - result.push_str(COLORS.blue); - result.push_str(GLYPH); - result.push_str(" "); - result.push_str(COLORS.cyan); - result.push_str(GLYPH); - result.push_str(" "); - result.push_str(COLORS.green); - result.push_str(GLYPH); - result.push_str(" "); - result.push_str(COLORS.yellow); - result.push_str(GLYPH); - result.push_str(" "); - result.push_str(COLORS.red); - result.push_str(GLYPH); - result.push_str(" "); - result.push_str(COLORS.magenta); - result.push_str(GLYPH); - result.push_str(" "); - result.push_str(COLORS.reset); - - result -} +pub static COLORS: LazyLock = LazyLock::new(|| { + Colors::new(*IS_NO_COLOR) +}); diff --git a/src/dots.rs b/src/dots.rs new file mode 100644 index 0000000..068bee2 --- /dev/null +++ b/src/dots.rs @@ -0,0 +1,33 @@ +use crate::{colors::IS_NO_COLOR, BLUE, CYAN, GREEN, MAGENTA, RED, RESET, YELLOW}; + +macro_rules! GLYPH {() => {""}} + +macro_rules! GAP {() => {" "}} + +const NO_COLORS_STR: &str = concat!( + GLYPH!(), GAP!(), + GLYPH!(), GAP!(), + GLYPH!(), GAP!(), + GLYPH!(), GAP!(), + GLYPH!(), GAP!(), + GLYPH!(), +); + +const COLORS_STR: &str = concat!( + BLUE!(), GLYPH!(), GAP!(), + CYAN!(), GLYPH!(), GAP!(), + GREEN!(), GLYPH!(), GAP!(), + YELLOW!(), GLYPH!(), GAP!(), + RED!(), GLYPH!(), GAP!(), + MAGENTA!(), GLYPH!(), RESET!(), +); + +#[must_use] +#[cfg_attr(feature = "hotpath", hotpath::measure)] +pub fn print_dots() -> &'static str { + if *IS_NO_COLOR { + NO_COLORS_STR + } else { + COLORS_STR + } +} diff --git a/src/lib.rs b/src/lib.rs index 1e0f9f3..18a992e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod colors; pub mod desktop; +pub mod dots; pub mod release; pub mod syscall; pub mod system; diff --git a/src/main.rs b/src/main.rs index e29d6d1..176e5c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod colors; mod desktop; +mod dots; mod release; mod syscall; mod system; @@ -10,8 +11,8 @@ use std::io::{self, Cursor, Write}; pub use microfetch_lib::UtsName; use crate::{ - colors::print_dots, desktop::get_desktop_info, + dots::print_dots, release::{get_os_pretty_name, get_system_info}, system::{ get_memory_usage, @@ -37,7 +38,7 @@ fn main() -> Result<(), Box> { uptime: get_current()?, memory_usage: get_memory_usage()?, storage: get_root_disk_usage()?, - colors: print_dots(), + dots: print_dots(), }; print_system_info(&fields)?; } @@ -57,7 +58,7 @@ struct Fields { desktop: String, memory_usage: String, storage: String, - colors: String, + dots: &'static str, } #[cfg_attr(feature = "hotpath", hotpath::measure)] @@ -75,7 +76,7 @@ fn print_system_info( desktop, memory_usage, storage, - colors, + dots, } = fields; let cyan = COLORS.cyan; @@ -96,7 +97,7 @@ fn print_system_info( {blue} ▟█▛{cyan}▗█▖ {cyan}▟█▛ {cyan} {blue}Desktop{reset}  {desktop} {blue} ▝█▛ {cyan}██▖{blue}▗▄▄▄▄▄▄▄▄▄▄▄ {cyan}󰍛 {blue}Memory{reset}  {memory_usage} {blue} ▝ {cyan}▟█▜█▖{blue}▀▀▀▀▀██▛▀▀▘ {cyan}󱥎 {blue}Storage (/){reset}  {storage} - {cyan} ▟█▘ ▜█▖ {blue}▝█▛ {cyan} {blue}Colors{reset}  {colors}\n\n" + {cyan} ▟█▘ ▜█▖ {blue}▝█▛ {cyan} {blue}Colors{reset}  {dots}\n\n" )?; let len = cursor.position() as usize;