mirror of
https://github.com/NotAShelf/microfetch.git
synced 2026-03-08 09:06:01 +00:00
Compare commits
8 commits
c751e74bdf
...
6640fdd559
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6640fdd559 |
||
|
cf3321b17a |
|||
|
7b8e736ff7 |
|||
|
927dce4127 |
|||
|
|
f883723608 |
||
|
|
f0cf18dba7 |
||
|
|
9da87b933d |
||
|
|
8376e9d323 |
6 changed files with 76 additions and 46 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
|
@ -280,9 +280,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "criterion"
|
name = "criterion"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0dfe5e9e71bdcf4e4954f7d14da74d1cdb92a3a07686452d1509652684b1aab"
|
checksum = "4d883447757bb0ee46f233e9dc22eb84d93a9508c9b868687b274fc431d886bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloca",
|
"alloca",
|
||||||
"anes",
|
"anes",
|
||||||
|
|
@ -305,9 +305,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "criterion-plot"
|
name = "criterion-plot"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5de36c2bee19fba779808f92bf5d9b0fa5a40095c277aba10c458a12b35d21d6"
|
checksum = "ed943f81ea2faa8dcecbbfa50164acf95d555afec96a27871663b300e387b2e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cast",
|
"cast",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
|
@ -557,9 +557,9 @@ checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hotpath"
|
name = "hotpath"
|
||||||
version = "0.7.5"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08382b985a19a79d95d35e2e201b02cc4b99efe2f47d82f3fd4301bb0005bb68"
|
checksum = "4b0a2c66c081fe3684a54a7e5d059c9d9ad6b3ee5ccea14f6e4f056dbd77becf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"base64",
|
"base64",
|
||||||
|
|
@ -586,9 +586,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hotpath-macros"
|
name = "hotpath-macros"
|
||||||
version = "0.7.5"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d618063f89423ebe079a69f5435a13d4909219d4e359757118b75fd05ae65d0"
|
checksum = "a38fa43ca80cf906cd05127e490d740a51abb38316db7bce9d95e89724a81761"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -786,9 +786,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.177"
|
version = "0.2.178"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ name = "microfetch"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hotpath = { optional = true, version = "0.7.5" }
|
hotpath = { optional = true, version = "0.8.0" }
|
||||||
libc = "0.2.177"
|
libc = "0.2.178"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.8.0"
|
criterion = "0.8.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
hotpath = [ "dep:hotpath", "hotpath/hotpath" ]
|
hotpath = [ "dep:hotpath", "hotpath/hotpath" ]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{env, sync::LazyLock};
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
pub struct Colors {
|
pub struct Colors {
|
||||||
pub reset: &'static str,
|
pub reset: &'static str,
|
||||||
|
|
@ -37,8 +37,8 @@ impl Colors {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COLORS: LazyLock<Colors> = LazyLock::new(|| {
|
pub static COLORS: LazyLock<Colors> = 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 = env::var("NO_COLOR").is_ok();
|
let is_no_color = unsafe { !libc::getenv(NO_COLOR).is_null() };
|
||||||
Colors::new(is_no_color)
|
Colors::new(is_no_color)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,27 @@
|
||||||
use std::fmt::Write;
|
use std::{ffi::CStr, fmt::Write};
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||||
pub fn get_desktop_info() -> String {
|
pub fn get_desktop_info() -> String {
|
||||||
// Retrieve the environment variables and handle Result types
|
// Retrieve the environment variables and handle Result types
|
||||||
let desktop_env = std::env::var("XDG_CURRENT_DESKTOP");
|
let desktop_str = unsafe {
|
||||||
let display_backend = std::env::var("XDG_SESSION_TYPE");
|
let ptr = libc::getenv(c"XDG_CURRENT_DESKTOP".as_ptr());
|
||||||
|
if ptr.is_null() {
|
||||||
let desktop_str = match desktop_env {
|
"Unknown"
|
||||||
Err(_) => "Unknown",
|
} else {
|
||||||
Ok(ref s) if s.starts_with("none+") => &s[5..],
|
let s = CStr::from_ptr(ptr).to_str().unwrap_or("Unknown");
|
||||||
Ok(ref s) => s.as_str(),
|
s.strip_prefix("none+").unwrap_or(s)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let backend_str = match display_backend {
|
let backend_str = unsafe {
|
||||||
Err(_) => "Unknown",
|
let ptr = libc::getenv(c"XDG_SESSION_TYPE".as_ptr());
|
||||||
Ok(ref s) if s.is_empty() => "Unknown",
|
if ptr.is_null() {
|
||||||
Ok(ref s) => s.as_str(),
|
"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 + ")"
|
// Pre-calculate capacity: desktop_len + " (" + backend_len + ")"
|
||||||
|
|
|
||||||
26
src/main.rs
26
src/main.rs
|
|
@ -5,7 +5,7 @@ mod syscall;
|
||||||
mod system;
|
mod system;
|
||||||
mod uptime;
|
mod uptime;
|
||||||
|
|
||||||
use std::io::{Write, stdout};
|
use std::io::{self, Cursor, Write};
|
||||||
|
|
||||||
pub use microfetch_lib::UtsName;
|
pub use microfetch_lib::UtsName;
|
||||||
|
|
||||||
|
|
@ -81,16 +81,32 @@ fn print_system_info(
|
||||||
let cyan = COLORS.cyan;
|
let cyan = COLORS.cyan;
|
||||||
let blue = COLORS.blue;
|
let blue = COLORS.blue;
|
||||||
let reset = COLORS.reset;
|
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}▝█▙ ▗█▛ {user_info} ~{reset}
|
||||||
{cyan} ▗▄▄▟██▄▄▄▄▄{blue}▝█▙█▛ {cyan}▖ {cyan} {blue}System{reset} {os_name}
|
{cyan} ▗▄▄▟██▄▄▄▄▄{blue}▝█▙█▛ {cyan}▖ {cyan} {blue}System{reset} {os_name}
|
||||||
{cyan} ▀▀▀▀▀▀▀▀▀▀▀▘{blue}▝██ {cyan}▟█▖ {cyan} {blue}Kernel{reset} {kernel_version}
|
{cyan} ▀▀▀▀▀▀▀▀▀▀▀▘{blue}▝██ {cyan}▟█▖ {cyan} {blue}Kernel{reset} {kernel_version}
|
||||||
{blue} ▟█▛ {blue}▝█▘{cyan}▟█▛ {cyan} {blue}Shell{reset} {shell}
|
{blue} ▟█▛ {blue}▝█▘{cyan}▟█▛ {cyan} {blue}Shell{reset} {shell}
|
||||||
{blue}▟█████▛ {cyan}▟█████▛ {cyan} {blue}Uptime{reset} {uptime}
|
{blue}▟█████▛ {cyan}▟█████▛ {cyan} {blue}Uptime{reset} {uptime}
|
||||||
{blue} ▟█▛{cyan}▗█▖ {cyan}▟█▛ {cyan} {blue}Desktop{reset} {desktop}
|
{blue} ▟█▛{cyan}▗█▖ {cyan}▟█▛ {cyan} {blue}Desktop{reset} {desktop}
|
||||||
{blue} ▝█▛ {cyan}██▖{blue}▗▄▄▄▄▄▄▄▄▄▄▄ {cyan} {blue}Memory{reset} {memory_usage}
|
{blue} ▝█▛ {cyan}██▖{blue}▗▄▄▄▄▄▄▄▄▄▄▄ {cyan} {blue}Memory{reset} {memory_usage}
|
||||||
{blue} ▝ {cyan}▟█▜█▖{blue}▀▀▀▀▀██▛▀▀▘ {cyan} {blue}Storage (/){reset} {storage}
|
{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(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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};
|
use crate::{UtsName, colors::COLORS, syscall::read_file_fast};
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||||
pub fn get_username_and_hostname(utsname: &UtsName) -> String {
|
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 hostname = utsname.nodename().to_str().unwrap_or("unknown_host");
|
||||||
|
|
||||||
let capacity = COLORS.yellow.len()
|
let capacity = COLORS.yellow.len()
|
||||||
|
|
@ -18,7 +25,7 @@ pub fn get_username_and_hostname(utsname: &UtsName) -> String {
|
||||||
let mut result = String::with_capacity(capacity);
|
let mut result = String::with_capacity(capacity);
|
||||||
|
|
||||||
result.push_str(COLORS.yellow);
|
result.push_str(COLORS.yellow);
|
||||||
result.push_str(&username);
|
result.push_str(username);
|
||||||
result.push_str(COLORS.red);
|
result.push_str(COLORS.red);
|
||||||
result.push('@');
|
result.push('@');
|
||||||
result.push_str(COLORS.green);
|
result.push_str(COLORS.green);
|
||||||
|
|
@ -31,15 +38,17 @@ pub fn get_username_and_hostname(utsname: &UtsName) -> String {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||||
pub fn get_shell() -> String {
|
pub fn get_shell() -> String {
|
||||||
let shell_path =
|
unsafe {
|
||||||
env::var("SHELL").unwrap_or_else(|_| "unknown_shell".to_owned());
|
let ptr = libc::getenv(c"SHELL".as_ptr());
|
||||||
|
if ptr.is_null() {
|
||||||
|
return "unknown_shell".into();
|
||||||
|
}
|
||||||
|
|
||||||
// Find last '/' and get the part after it, avoiding allocation
|
let bytes = CStr::from_ptr(ptr).to_bytes();
|
||||||
shell_path
|
let start = bytes.iter().rposition(|&b| b == b'/').map_or(0, |i| i + 1);
|
||||||
.rsplit('/')
|
let name = std::str::from_utf8_unchecked(&bytes[start..]);
|
||||||
.next()
|
name.into()
|
||||||
.unwrap_or("unknown_shell")
|
}
|
||||||
.to_owned()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the root disk usage information.
|
/// Gets the root disk usage information.
|
||||||
|
|
@ -106,7 +115,7 @@ pub fn get_memory_usage() -> Result<String, io::Error> {
|
||||||
fn parse_memory_info() -> Result<(f64, f64), io::Error> {
|
fn parse_memory_info() -> Result<(f64, f64), io::Error> {
|
||||||
let mut total_memory_kb = 0u64;
|
let mut total_memory_kb = 0u64;
|
||||||
let mut available_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
|
// Use fast syscall-based file reading
|
||||||
let bytes_read = read_file_fast("/proc/meminfo", &mut buffer)?;
|
let bytes_read = read_file_fast("/proc/meminfo", &mut buffer)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue