mirror of
https://github.com/NotAShelf/microfetch.git
synced 2025-12-14 08:21:01 +00:00
Merge d27e8b36c4 into 8d863c64c9
This commit is contained in:
commit
2678a160e7
10 changed files with 139 additions and 83 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
use criterion::{Criterion, criterion_group, criterion_main};
|
use criterion::{Criterion, criterion_group, criterion_main};
|
||||||
use microfetch_lib::{
|
use microfetch_lib::{
|
||||||
UtsName,
|
UtsName,
|
||||||
colors::print_dots,
|
|
||||||
desktop::get_desktop_info,
|
desktop::get_desktop_info,
|
||||||
|
dots::print_dots,
|
||||||
release::{get_os_pretty_name, get_system_info},
|
release::{get_os_pretty_name, get_system_info},
|
||||||
system::{
|
system::{
|
||||||
get_memory_usage,
|
get_memory_usage,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,22 @@
|
||||||
use std::sync::LazyLock;
|
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 struct Colors {
|
||||||
pub reset: &'static str,
|
pub reset: &'static str,
|
||||||
pub blue: &'static str,
|
pub blue: &'static str,
|
||||||
|
|
@ -7,7 +24,6 @@ pub struct Colors {
|
||||||
pub green: &'static str,
|
pub green: &'static str,
|
||||||
pub yellow: &'static str,
|
pub yellow: &'static str,
|
||||||
pub red: &'static str,
|
pub red: &'static str,
|
||||||
pub magenta: &'static str,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Colors {
|
impl Colors {
|
||||||
|
|
@ -20,62 +36,26 @@ impl Colors {
|
||||||
green: "",
|
green: "",
|
||||||
yellow: "",
|
yellow: "",
|
||||||
red: "",
|
red: "",
|
||||||
magenta: "",
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Self {
|
Self {
|
||||||
reset: "\x1b[0m",
|
reset: RESET!(),
|
||||||
blue: "\x1b[34m",
|
blue: BLUE!(),
|
||||||
cyan: "\x1b[36m",
|
cyan: CYAN!(),
|
||||||
green: "\x1b[32m",
|
green: GREEN!(),
|
||||||
yellow: "\x1b[33m",
|
yellow: YELLOW!(),
|
||||||
red: "\x1b[31m",
|
red: RED!(),
|
||||||
magenta: "\x1b[35m",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COLORS: LazyLock<Colors> = LazyLock::new(|| {
|
pub static IS_NO_COLOR: LazyLock<bool> = LazyLock::new(|| {
|
||||||
|
// Check for NO_COLOR once at startup
|
||||||
const NO_COLOR: *const libc::c_char = c"NO_COLOR".as_ptr();
|
const NO_COLOR: *const libc::c_char = c"NO_COLOR".as_ptr();
|
||||||
let is_no_color = unsafe { !libc::getenv(NO_COLOR).is_null() };
|
unsafe { !libc::getenv(NO_COLOR).is_null() }
|
||||||
Colors::new(is_no_color)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#[must_use]
|
pub static COLORS: LazyLock<Colors> = LazyLock::new(|| {
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
Colors::new(*IS_NO_COLOR)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use std::{ffi::CStr, fmt::Write};
|
use std::ffi::CStr;
|
||||||
|
|
||||||
|
use crate::unknown;
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||||
|
|
@ -7,9 +9,9 @@ pub fn get_desktop_info() -> String {
|
||||||
let desktop_str = unsafe {
|
let desktop_str = unsafe {
|
||||||
let ptr = libc::getenv(c"XDG_CURRENT_DESKTOP".as_ptr());
|
let ptr = libc::getenv(c"XDG_CURRENT_DESKTOP".as_ptr());
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
"Unknown"
|
unknown()
|
||||||
} else {
|
} else {
|
||||||
let s = CStr::from_ptr(ptr).to_str().unwrap_or("Unknown");
|
let s = CStr::from_ptr(ptr).to_str().unwrap_or_else(|_| unknown());
|
||||||
s.strip_prefix("none+").unwrap_or(s)
|
s.strip_prefix("none+").unwrap_or(s)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -17,10 +19,10 @@ pub fn get_desktop_info() -> String {
|
||||||
let backend_str = unsafe {
|
let backend_str = unsafe {
|
||||||
let ptr = libc::getenv(c"XDG_SESSION_TYPE".as_ptr());
|
let ptr = libc::getenv(c"XDG_SESSION_TYPE".as_ptr());
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
"Unknown"
|
unknown()
|
||||||
} else {
|
} else {
|
||||||
let s = CStr::from_ptr(ptr).to_str().unwrap_or("Unknown");
|
let s = CStr::from_ptr(ptr).to_str().unwrap_or_else(|_| unknown());
|
||||||
if s.is_empty() { "Unknown" } else { s }
|
if s.is_empty() { unknown() } else { s }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -29,11 +31,12 @@ pub fn get_desktop_info() -> String {
|
||||||
let mut result =
|
let mut result =
|
||||||
String::with_capacity(desktop_str.len() + backend_str.len() + 3);
|
String::with_capacity(desktop_str.len() + backend_str.len() + 3);
|
||||||
result.push_str(desktop_str);
|
result.push_str(desktop_str);
|
||||||
result.push_str(" (");
|
result.push(' ');
|
||||||
|
result.push('(');
|
||||||
|
|
||||||
// Capitalize first character of backend
|
// Capitalize first character of backend
|
||||||
if let Some(first_char) = backend_str.chars().next() {
|
if let Some(first_char) = backend_str.chars().next() {
|
||||||
let _ = write!(result, "{}", first_char.to_ascii_uppercase());
|
result.push(first_char.to_ascii_uppercase());
|
||||||
result.push_str(&backend_str[first_char.len_utf8()..]);
|
result.push_str(&backend_str[first_char.len_utf8()..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
33
src/dots.rs
Normal file
33
src/dots.rs
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/lib.rs
15
src/lib.rs
|
|
@ -1,11 +1,22 @@
|
||||||
pub mod colors;
|
pub mod colors;
|
||||||
pub mod desktop;
|
pub mod desktop;
|
||||||
|
pub mod dots;
|
||||||
pub mod release;
|
pub mod release;
|
||||||
pub mod syscall;
|
pub mod syscall;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
pub mod uptime;
|
pub mod uptime;
|
||||||
|
|
||||||
use std::mem::MaybeUninit;
|
use std::{io, mem::MaybeUninit};
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cold]
|
||||||
|
pub const fn unknown() -> &'static str { "Unknown" }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cold]
|
||||||
|
pub fn last_os_error<T>() -> io::Result<T> {
|
||||||
|
Err(io::Error::last_os_error())
|
||||||
|
}
|
||||||
|
|
||||||
/// Wrapper for `libc::utsname` with safe accessor methods
|
/// Wrapper for `libc::utsname` with safe accessor methods
|
||||||
pub struct UtsName(libc::utsname);
|
pub struct UtsName(libc::utsname);
|
||||||
|
|
@ -19,7 +30,7 @@ impl UtsName {
|
||||||
pub fn uname() -> Result<Self, std::io::Error> {
|
pub fn uname() -> Result<Self, std::io::Error> {
|
||||||
let mut uts = MaybeUninit::uninit();
|
let mut uts = MaybeUninit::uninit();
|
||||||
if unsafe { libc::uname(uts.as_mut_ptr()) } != 0 {
|
if unsafe { libc::uname(uts.as_mut_ptr()) } != 0 {
|
||||||
return Err(std::io::Error::last_os_error());
|
return last_os_error();
|
||||||
}
|
}
|
||||||
Ok(Self(unsafe { uts.assume_init() }))
|
Ok(Self(unsafe { uts.assume_init() }))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
src/main.rs
13
src/main.rs
|
|
@ -1,5 +1,6 @@
|
||||||
mod colors;
|
mod colors;
|
||||||
mod desktop;
|
mod desktop;
|
||||||
|
mod dots;
|
||||||
mod release;
|
mod release;
|
||||||
mod syscall;
|
mod syscall;
|
||||||
mod system;
|
mod system;
|
||||||
|
|
@ -7,11 +8,11 @@ mod uptime;
|
||||||
|
|
||||||
use std::io::{self, Cursor, Write};
|
use std::io::{self, Cursor, Write};
|
||||||
|
|
||||||
pub use microfetch_lib::UtsName;
|
pub use microfetch_lib::{UtsName, last_os_error, unknown};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::print_dots,
|
|
||||||
desktop::get_desktop_info,
|
desktop::get_desktop_info,
|
||||||
|
dots::print_dots,
|
||||||
release::{get_os_pretty_name, get_system_info},
|
release::{get_os_pretty_name, get_system_info},
|
||||||
system::{
|
system::{
|
||||||
get_memory_usage,
|
get_memory_usage,
|
||||||
|
|
@ -37,7 +38,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
uptime: get_current()?,
|
uptime: get_current()?,
|
||||||
memory_usage: get_memory_usage()?,
|
memory_usage: get_memory_usage()?,
|
||||||
storage: get_root_disk_usage()?,
|
storage: get_root_disk_usage()?,
|
||||||
colors: print_dots(),
|
dots: print_dots(),
|
||||||
};
|
};
|
||||||
print_system_info(&fields)?;
|
print_system_info(&fields)?;
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +58,7 @@ struct Fields {
|
||||||
desktop: String,
|
desktop: String,
|
||||||
memory_usage: String,
|
memory_usage: String,
|
||||||
storage: String,
|
storage: String,
|
||||||
colors: String,
|
dots: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||||
|
|
@ -75,7 +76,7 @@ fn print_system_info(
|
||||||
desktop,
|
desktop,
|
||||||
memory_usage,
|
memory_usage,
|
||||||
storage,
|
storage,
|
||||||
colors,
|
dots,
|
||||||
} = fields;
|
} = fields;
|
||||||
|
|
||||||
let cyan = COLORS.cyan;
|
let cyan = COLORS.cyan;
|
||||||
|
|
@ -96,7 +97,7 @@ fn print_system_info(
|
||||||
{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} {dots}\n\n"
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let len = cursor.position() as usize;
|
let len = cursor.position() as usize;
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,25 @@
|
||||||
use std::{fmt::Write as _, io};
|
use std::io;
|
||||||
|
|
||||||
use crate::{UtsName, syscall::read_file_fast};
|
use crate::{syscall::read_file_fast, unknown, UtsName};
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||||
pub fn get_system_info(utsname: &UtsName) -> String {
|
pub fn get_system_info(utsname: &UtsName) -> String {
|
||||||
let sysname = utsname.sysname().to_str().unwrap_or("Unknown");
|
let sysname = utsname.sysname().to_str().unwrap_or_else(|_| unknown());
|
||||||
let release = utsname.release().to_str().unwrap_or("Unknown");
|
let release = utsname.release().to_str().unwrap_or_else(|_| unknown());
|
||||||
let machine = utsname.machine().to_str().unwrap_or("Unknown");
|
let machine = utsname.machine().to_str().unwrap_or_else(|_| unknown());
|
||||||
|
|
||||||
// Pre-allocate capacity: sysname + " " + release + " (" + machine + ")"
|
// Pre-allocate capacity: sysname + " " + release + " (" + machine + ")"
|
||||||
let capacity = sysname.len() + 1 + release.len() + 2 + machine.len() + 1;
|
let capacity = sysname.len() + 1 + release.len() + 2 + machine.len() + 1;
|
||||||
let mut result = String::with_capacity(capacity);
|
let mut result = String::with_capacity(capacity);
|
||||||
|
|
||||||
write!(result, "{sysname} {release} ({machine})").unwrap();
|
result.push_str(sysname);
|
||||||
|
result.push(' ');
|
||||||
|
result.push_str(release);
|
||||||
|
result.push(' ');
|
||||||
|
result.push('(');
|
||||||
|
result.push_str(machine);
|
||||||
|
result.push(')');
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,5 +71,5 @@ pub fn get_os_pretty_name() -> Result<String, io::Error> {
|
||||||
offset += line_end + 1;
|
offset += line_end + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok("Unknown".to_owned())
|
Ok(unknown().to_owned())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use crate::last_os_error;
|
||||||
|
|
||||||
/// Direct syscall to open a file
|
/// Direct syscall to open a file
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
|
|
@ -169,6 +171,12 @@ pub unsafe fn sys_close(fd: i32) -> i32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cold]
|
||||||
|
fn path_too_long() -> io::Result<usize> {
|
||||||
|
Err(io::Error::new(io::ErrorKind::InvalidInput, "Path too long"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Read entire file using direct syscalls. This avoids libc overhead and can be
|
/// Read entire file using direct syscalls. This avoids libc overhead and can be
|
||||||
/// significantly faster for small files.
|
/// significantly faster for small files.
|
||||||
///
|
///
|
||||||
|
|
@ -182,7 +190,7 @@ pub fn read_file_fast(path: &str, buffer: &mut [u8]) -> io::Result<usize> {
|
||||||
// Use stack-allocated buffer for null-terminated path (max 256 bytes)
|
// Use stack-allocated buffer for null-terminated path (max 256 bytes)
|
||||||
let path_bytes = path.as_bytes();
|
let path_bytes = path.as_bytes();
|
||||||
if path_bytes.len() >= 256 {
|
if path_bytes.len() >= 256 {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Path too long"));
|
return path_too_long();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut path_buf = [0u8; 256];
|
let mut path_buf = [0u8; 256];
|
||||||
|
|
@ -192,14 +200,14 @@ pub fn read_file_fast(path: &str, buffer: &mut [u8]) -> io::Result<usize> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fd = sys_open(path_buf.as_ptr(), O_RDONLY);
|
let fd = sys_open(path_buf.as_ptr(), O_RDONLY);
|
||||||
if fd < 0 {
|
if fd < 0 {
|
||||||
return Err(io::Error::last_os_error());
|
return last_os_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes_read = sys_read(fd, buffer.as_mut_ptr(), buffer.len());
|
let bytes_read = sys_read(fd, buffer.as_mut_ptr(), buffer.len());
|
||||||
let _ = sys_close(fd);
|
let _ = sys_close(fd);
|
||||||
|
|
||||||
if bytes_read < 0 {
|
if bytes_read < 0 {
|
||||||
return Err(io::Error::last_os_error());
|
return last_os_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_sign_loss)]
|
#[allow(clippy::cast_sign_loss)]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,14 @@
|
||||||
use std::{ffi::CStr, 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::{colors::COLORS, last_os_error, syscall::read_file_fast, UtsName};
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cold]
|
||||||
|
const fn unknown_user() -> &'static str { "unknown_user" }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cold]
|
||||||
|
const fn unknown_host() -> &'static str { "unknown_host" }
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
#[cfg_attr(feature = "hotpath", hotpath::measure)]
|
||||||
|
|
@ -8,12 +16,12 @@ pub fn get_username_and_hostname(utsname: &UtsName) -> String {
|
||||||
let username = unsafe {
|
let username = unsafe {
|
||||||
let ptr = libc::getenv(c"USER".as_ptr());
|
let ptr = libc::getenv(c"USER".as_ptr());
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
"unknown_user"
|
unknown_user()
|
||||||
} else {
|
} else {
|
||||||
CStr::from_ptr(ptr).to_str().unwrap_or("unknown_user")
|
CStr::from_ptr(ptr).to_str().unwrap_or_else(|_| unknown_user())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let hostname = utsname.nodename().to_str().unwrap_or("unknown_host");
|
let hostname = utsname.nodename().to_str().unwrap_or_else(|_| unknown_host());
|
||||||
|
|
||||||
let capacity = COLORS.yellow.len()
|
let capacity = COLORS.yellow.len()
|
||||||
+ username.len()
|
+ username.len()
|
||||||
|
|
@ -35,13 +43,17 @@ pub fn get_username_and_hostname(utsname: &UtsName) -> String {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cold]
|
||||||
|
const fn unknown_shell() -> &'static str { "unknown_shell" }
|
||||||
|
|
||||||
#[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 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = libc::getenv(c"SHELL".as_ptr());
|
let ptr = libc::getenv(c"SHELL".as_ptr());
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
return "unknown_shell".into();
|
return unknown_shell().into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let bytes = CStr::from_ptr(ptr).to_bytes();
|
let bytes = CStr::from_ptr(ptr).to_bytes();
|
||||||
|
|
@ -63,7 +75,7 @@ pub fn get_root_disk_usage() -> Result<String, io::Error> {
|
||||||
let path = b"/\0";
|
let path = b"/\0";
|
||||||
|
|
||||||
if unsafe { libc::statvfs(path.as_ptr().cast(), vfs.as_mut_ptr()) } != 0 {
|
if unsafe { libc::statvfs(path.as_ptr().cast(), vfs.as_mut_ptr()) } != 0 {
|
||||||
return Err(io::Error::last_os_error());
|
return last_os_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
let vfs = unsafe { vfs.assume_init() };
|
let vfs = unsafe { vfs.assume_init() };
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
use std::{io, mem::MaybeUninit};
|
use std::{io, mem::MaybeUninit};
|
||||||
|
|
||||||
|
use crate::last_os_error;
|
||||||
|
|
||||||
/// Faster integer to string conversion without the formatting overhead.
|
/// Faster integer to string conversion without the formatting overhead.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn itoa(mut n: u64, buf: &mut [u8]) -> &str {
|
fn itoa(mut n: u64, buf: &mut [u8]) -> &str {
|
||||||
|
|
@ -73,7 +75,7 @@ pub fn get_current() -> Result<String, io::Error> {
|
||||||
let uptime_seconds = {
|
let uptime_seconds = {
|
||||||
let mut info = MaybeUninit::uninit();
|
let mut info = MaybeUninit::uninit();
|
||||||
if unsafe { sys_sysinfo(info.as_mut_ptr()) } != 0 {
|
if unsafe { sys_sysinfo(info.as_mut_ptr()) } != 0 {
|
||||||
return Err(io::Error::last_os_error());
|
return last_os_error();
|
||||||
}
|
}
|
||||||
#[allow(clippy::cast_sign_loss)]
|
#[allow(clippy::cast_sign_loss)]
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue