Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/colors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{env, sync::LazyLock};
use std::sync::LazyLock;

pub struct Colors {
pub reset: &'static str,
Expand Down Expand Up @@ -37,8 +37,8 @@ impl Colors {
}

pub static COLORS: LazyLock<Colors> = LazyLock::new(|| {
// Check for NO_COLOR once at startup
let is_no_color = env::var("NO_COLOR").is_ok();
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)
});

Expand Down
29 changes: 17 additions & 12 deletions src/desktop.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
use std::fmt::Write;
use std::{ffi::CStr, fmt::Write};

#[must_use]
#[cfg_attr(feature = "hotpath", hotpath::measure)]
pub fn get_desktop_info() -> String {
// Retrieve the environment variables and handle Result types
let desktop_env = std::env::var("XDG_CURRENT_DESKTOP");
let display_backend = std::env::var("XDG_SESSION_TYPE");

let desktop_str = match desktop_env {
Err(_) => "Unknown",
Ok(ref s) if s.starts_with("none+") => &s[5..],
Ok(ref s) => s.as_str(),
let desktop_str = unsafe {
let ptr = libc::getenv(c"XDG_CURRENT_DESKTOP".as_ptr());
if ptr.is_null() {
"Unknown"
} else {
let s = CStr::from_ptr(ptr).to_str().unwrap_or("Unknown");
s.strip_prefix("none+").unwrap_or(s)
}
};

let backend_str = match display_backend {
Err(_) => "Unknown",
Ok(ref s) if s.is_empty() => "Unknown",
Ok(ref s) => s.as_str(),
let backend_str = unsafe {
let ptr = libc::getenv(c"XDG_SESSION_TYPE".as_ptr());
if ptr.is_null() {
"Unknown"
} else {
let s = CStr::from_ptr(ptr).to_str().unwrap_or("Unknown");
if s.is_empty() { "Unknown" } else { s }
}
};

// Pre-calculate capacity: desktop_len + " (" + backend_len + ")"
Expand Down
23 changes: 19 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod syscall;
mod system;
mod uptime;

use std::io::{Write, stdout};
use std::io::{self, Cursor, Write};

pub use microfetch_lib::UtsName;

Expand Down Expand Up @@ -81,7 +81,13 @@ fn print_system_info(
let cyan = COLORS.cyan;
let blue = COLORS.blue;
let reset = COLORS.reset;
let system_info = format!("

let mut buf = [0u8; 2048];
let mut cursor = Cursor::new(&mut buf[..]);

write!(
cursor,
"
{cyan} ▟█▖ {blue}▝█▙ ▗█▛ {user_info} ~{reset}
{cyan} ▗▄▄▟██▄▄▄▄▄{blue}▝█▙█▛ {cyan}▖ {cyan} {blue}System{reset}  {os_name}
{cyan} ▀▀▀▀▀▀▀▀▀▀▀▘{blue}▝██ {cyan}▟█▖ {cyan} {blue}Kernel{reset}  {kernel_version}
Expand All @@ -90,7 +96,16 @@ 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");
{cyan} ▟█▘ ▜█▖ {blue}▝█▛ {cyan} {blue}Colors{reset}  {colors}\n"
)?;

#[allow(clippy::cast_possible_truncation)]
let len = cursor.position() as usize;

Ok(stdout().write_all(system_info.as_bytes())?)
// Direct syscall to avoid stdout buffering allocation
let written = unsafe { libc::write(libc::STDOUT_FILENO, buf.as_ptr().cast(), len) };
if written < 0 {
return Err(io::Error::last_os_error().into());
}
Ok(())
}
35 changes: 22 additions & 13 deletions src/system.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
use std::{env, fmt::Write as _, io, mem::MaybeUninit};
use std::{ffi::CStr, fmt::Write as _, io, mem::MaybeUninit};

use crate::{UtsName, colors::COLORS, syscall::read_file_fast};

#[must_use]
#[cfg_attr(feature = "hotpath", hotpath::measure)]
pub fn get_username_and_hostname(utsname: &UtsName) -> String {
let username = env::var("USER").unwrap_or_else(|_| "unknown_user".to_owned());
let username = unsafe {
let ptr = libc::getenv(c"USER".as_ptr());
if ptr.is_null() {
"unknown_user"
} else {
CStr::from_ptr(ptr).to_str().unwrap_or("unknown_user")
}
};
let hostname = utsname.nodename().to_str().unwrap_or("unknown_host");

let capacity = COLORS.yellow.len()
Expand All @@ -18,7 +25,7 @@ pub fn get_username_and_hostname(utsname: &UtsName) -> String {
let mut result = String::with_capacity(capacity);

result.push_str(COLORS.yellow);
result.push_str(&username);
result.push_str(username);
result.push_str(COLORS.red);
result.push('@');
result.push_str(COLORS.green);
Expand All @@ -31,15 +38,17 @@ pub fn get_username_and_hostname(utsname: &UtsName) -> String {
#[must_use]
#[cfg_attr(feature = "hotpath", hotpath::measure)]
pub fn get_shell() -> String {
let shell_path =
env::var("SHELL").unwrap_or_else(|_| "unknown_shell".to_owned());

// Find last '/' and get the part after it, avoiding allocation
shell_path
.rsplit('/')
.next()
.unwrap_or("unknown_shell")
.to_owned()
unsafe {
let ptr = libc::getenv(c"SHELL".as_ptr());
if ptr.is_null() {
return "unknown_shell".into();
}

let bytes = CStr::from_ptr(ptr).to_bytes();
let start = bytes.iter().rposition(|&b| b == b'/').map_or(0, |i| i + 1);
let name = std::str::from_utf8_unchecked(&bytes[start..]);
name.into()
}
}

/// Gets the root disk usage information.
Expand Down Expand Up @@ -106,7 +115,7 @@ pub fn get_memory_usage() -> Result<String, io::Error> {
fn parse_memory_info() -> Result<(f64, f64), io::Error> {
let mut total_memory_kb = 0u64;
let mut available_memory_kb = 0u64;
let mut buffer = [0u8; 2048];
let mut buffer = [0u8; 1024];

// Use fast syscall-based file reading
let bytes_read = read_file_fast("/proc/meminfo", &mut buffer)?;
Expand Down