From 13903539b7249f2e6a8bff1ebe24924a08d566ec Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 5 Aug 2024 16:08:25 +0800 Subject: [PATCH 1/2] perf: use nix::sys::utsname::uname for less syscalls (#2) Instead of reading multiple files to get the `sysname`, `release`, and `machine` name, use the `nix::sys::utsname::uname` function which sends a single uname syscall instead. This increases performance and portability. From my observations, there are ~10 less syscalls. --- Cargo.toml | 2 +- src/release.rs | 33 +++++++++------------------------ 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9682a7d..b551c5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.3.3" edition = "2021" [dependencies] -nix = {version = "0.29", features = ["fs", "hostname"]} +nix = { version = "0.29", features = ["fs", "hostname", "feature"] } color-eyre = { version = "0.6", default-features = false } [profile.dev] diff --git a/src/release.rs b/src/release.rs index 25f5640..8a33844 100644 --- a/src/release.rs +++ b/src/release.rs @@ -1,30 +1,15 @@ use color_eyre::Result; -use std::fs::{self, read_to_string}; +use std::fs::read_to_string; use std::io; -// Try to detect OS type as accurately as possible and without depending on uname. -// /etc/os-release should generally imply Linux, and /etc/bsd-release would imply BSD system. -fn detect_os() -> Result<&'static str, io::Error> { - if fs::metadata("/etc/os-release").is_ok() || fs::metadata("/usr/lib/os-release").is_ok() { - Ok("Linux") - } else if fs::metadata("/etc/rc.conf").is_ok() || fs::metadata("/etc/bsd-release").is_ok() { - Ok("BSD") - } else { - Ok("Unknown") - } -} - -pub fn get_system_info() -> Result { - let system = detect_os()?; - - let kernel_release = read_to_string("/proc/sys/kernel/osrelease")?; - let kernel_release = kernel_release.trim(); - - let architecture = read_to_string("/proc/sys/kernel/arch")?; - let architecture = architecture.trim(); - - let result = format!("{system} {kernel_release} ({architecture})"); - Ok(result) +pub fn get_system_info() -> nix::Result { + let utsname = nix::sys::utsname::uname()?; + Ok(format!( + "{} {} ({})", + utsname.sysname().to_str().unwrap_or("Unknown"), + utsname.release().to_str().unwrap_or("Unknown"), + utsname.machine().to_str().unwrap_or("Unknown") + )) } pub fn get_os_pretty_name() -> Result { From 927f6077b4b78cd112bc6932aab5287edc413ce8 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Mon, 5 Aug 2024 11:33:42 +0300 Subject: [PATCH 2/2] store printed fields in a struct Shut up, clippy. --- src/main.rs | 72 +++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/src/main.rs b/src/main.rs index 30fa78a..f725d29 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,43 +16,40 @@ use nix::sys::sysinfo::sysinfo; fn main() -> Result<(), Report> { color_eyre::install()?; - let user_info = get_username_and_hostname()?; - let os_name = get_os_pretty_name()?; - let kernel_version = get_system_info()?; - let shell = get_shell()?; - let uptime = get_current()?; - let window_manager = get_desktop_info()?; - let sys_info = sysinfo()?; - let memory_usage = get_memory_usage(sys_info); - let storage = get_root_disk_usage()?; - let colors = print_dots()?; + let fields = Fields { + user_info: get_username_and_hostname()?, + os_name: get_os_pretty_name()?, + kernel_version: get_system_info()?, + shell: get_shell()?, + uptime: get_current()?, + window_manager: get_desktop_info()?, + memory_usage: get_memory_usage(sysinfo()?), + storage: get_root_disk_usage()?, + colors: print_dots()?, + }; - print_system_info( - &user_info, - &os_name, - &kernel_version, - &shell, - &uptime, - &window_manager, - &memory_usage, - &storage, - &colors, - ); + print_system_info(&fields); Ok(()) } -fn print_system_info( - user_info: &str, - os_name: &str, - kernel_version: &str, - shell: &str, - uptime: &str, - window_manager: &str, - memory_usage: &str, - storage: &str, - colors: &str, -) { +// Struct to hold all the fields we need to print +// helps avoid clippy warnings about argument count +// and makes it easier to pass around, though its +// not like we need to +struct Fields { + user_info: String, + os_name: String, + kernel_version: String, + shell: String, + uptime: String, + window_manager: String, + memory_usage: String, + storage: String, + colors: String, +} + +fn print_system_info(fields: &Fields) { println!( " {CYAN} ▟█▖ {BLUE}▝█▙ ▗█▛ {user_info} ~{RESET} @@ -64,6 +61,15 @@ fn print_system_info( {BLUE} ▝█▛ {CYAN}██▖{BLUE}▗▄▄▄▄▄▄▄▄▄▄▄ {CYAN}󰍛 {BLUE}Memory{RESET}  {memory_usage} {BLUE} ▝ {CYAN}▟█▜█▖{BLUE}▀▀▀▀▀██▛▀▀▘ {CYAN}󱥎 {BLUE}Storage (/){RESET}  {storage} {CYAN} ▟█▘ ▜█▖ {BLUE}▝█▛ {CYAN} {BLUE}Colors{RESET}  {colors} - " +", + user_info = fields.user_info, + os_name = fields.os_name, + kernel_version = fields.kernel_version, + shell = fields.shell, + uptime = fields.uptime, + window_manager = fields.window_manager, + memory_usage = fields.memory_usage, + storage = fields.storage, + colors = fields.colors, ); }