Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
24 changes: 20 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,17 @@ 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}  {colors}\n\n"
)?;

Ok(stdout().write_all(system_info.as_bytes())?)
let len = cursor.position() as usize;
// 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());
}
if written as usize != len {
return Err(io::Error::new(io::ErrorKind::WriteZero, "partial write to stdout").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