Compare commits

..

No commits in common. "cd8ddc2177775c722a88c14e853cbe5bbb7f6495" and "927f6077b4b78cd112bc6932aab5287edc413ce8" have entirely different histories.

8 changed files with 51 additions and 76 deletions

2
Cargo.lock generated
View file

@ -105,7 +105,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "microfetch" name = "microfetch"
version = "0.3.5" version = "0.3.3"
dependencies = [ dependencies = [
"color-eyre", "color-eyre",
"nix", "nix",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "microfetch" name = "microfetch"
version = "0.3.5" version = "0.3.3"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View file

@ -35,35 +35,24 @@ than welcome to use it on your system: it's pretty [fast...](#benchmarks)
- Version - Version
- Architecture - Architecture
- Current shell (from $SHELL, trimmed if store path) - Current shell (from $SHELL, trimmed if store path)
- Current Desktop (DE/WM/Compositor and display backend) - WM/Compositor and display backend
- Memory Usage/Total Memory - Memory Usage/Total Memory
- Storage Usage/Total Storage (for `/` only) - Storage Usage/Total Storage (for `/` only)
- Shell Colors - Shell Colors
- Did I mention fast? - Did I mention fast?
## Installation
Microfetch is packaged in [nixpkgs](https://github.com/nixos/nixpkgs). You can
get it through the unstable channel for the time being. The Nix flake can also
be used for bleeding-edge builds.
Non-Nix users will have to build Microfetch with `cargo`.
Microfetch is _currently_ not available anywhere else. Though, does it _really_
have to be?
## Benchmarks ## Benchmarks
Microfetch's performance is mostly hardware-dependant, however, the overall Microfetch's performance is mostly hardware-dependant, however, the overall
trend seems to be < 2ms on any modern (2015 and after) CPU. Below are the trend seems to be < 2ms on any modern (2015 and after) CPU. Below are the
benchmarks with Hyperfine on my desktop system. benchmarks with Hyperfine on my desktop system.
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative | Written by raf? | | Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
| :----------- | ----------: | -------: | -------: | -------------: | --------------: | | :----------- | ----------: | -------: | -------: | -------------: |
| `microfetch` | 1.3 ± 0.0 | 1.3 | 1.4 | 1.00 | yes | | `microfetch` | 1.3 ± 0.0 | 1.3 | 1.4 | 1.00 |
| `pfetch` | 254.2 ± 4.8 | 246.7 | 264.9 | 191.97 ± 7.10 | no | | `pfetch` | 254.2 ± 4.8 | 246.7 | 264.9 | 191.97 ± 7.10 |
| `neofetch` | 735.4 ± 9.5 | 721.1 | 752.8 | 555.48 ± 19.08 | no | | `neofetch` | 735.4 ± 9.5 | 721.1 | 752.8 | 555.48 ± 19.08 |
| `fastfetch` | 31.9 ± 0.8 | 30.8 | 33.8 | 24.08 ± 0.98 | no | | `fastfetch` | 31.9 ± 0.8 | 30.8 | 33.8 | 24.08 ± 0.98 |
_As far as I'm concerned, Microfetch is faster than almost every fetch tool _As far as I'm concerned, Microfetch is faster than almost every fetch tool
there is. The only downside of using Rust is introducing more "bloated" there is. The only downside of using Rust is introducing more "bloated"

View file

@ -6,6 +6,8 @@ pub const YELLOW: &str = "\x1b[33m";
pub const RED: &str = "\x1b[31m"; pub const RED: &str = "\x1b[31m";
pub const MAGENTA: &str = "\x1b[35m"; pub const MAGENTA: &str = "\x1b[35m";
pub fn print_dots() -> String { pub fn print_dots() -> Result<String, std::io::Error> {
format!("{BLUE}{CYAN}{GREEN}{YELLOW}{RED}{MAGENTA}{RESET}") let colors = format!("{BLUE}{CYAN}{GREEN}{YELLOW}{RED}{MAGENTA}{RESET}");
Ok(colors)
} }

View file

@ -1,35 +1,20 @@
pub fn get_desktop_info() -> String { use color_eyre::Result;
fn capitalize_first_letter(s: &str) -> String { use std::{env, io};
if s.is_empty() {
return String::new();
}
let mut chars = s.chars(); pub fn get_desktop_info() -> Result<String, io::Error> {
let first_char = chars.next().unwrap().to_uppercase().to_string(); let desktop_env = env::var("XDG_CURRENT_DESKTOP");
let rest: String = chars.collect(); let display_backend = env::var("XDG_SESSION_TYPE");
first_char + &rest
}
// Retrieve the environment variables and handle Result types
let desktop_env = std::env::var("XDG_CURRENT_DESKTOP");
let display_backend_result = std::env::var("XDG_SESSION_TYPE");
// Capitalize the first letter of the display backend value
let display_backend = capitalize_first_letter(display_backend_result.as_deref().unwrap_or(""));
// Trim "none+" from the start of desktop_env if present // Trim "none+" from the start of desktop_env if present
// Use "Unknown" if desktop_env is empty or has an error // XXX: This is a workaround for NixOS modules that set XDG_CURRENT_DESKTOP to "none+foo"
// instead of just "foo"
// Use "Unknown" if desktop_env or display_backend is empty
let desktop_env = match desktop_env { let desktop_env = match desktop_env {
Err(_) => "Unknown".to_string(), Err(_) => String::from("Unknown"),
Ok(s) => s.trim_start_matches("none+").to_string(), Ok(s) => s.trim_start_matches("none+").to_owned(),
}; };
// Handle the case where display_backend might be empty after capitalization let display_backend = display_backend.unwrap_or_else(|_| String::from("Unknown"));
let display_backend = if display_backend.is_empty() {
"Unknown".to_string()
} else {
display_backend
};
format!("{desktop_env} ({display_backend})") Ok(format!("{desktop_env} ({display_backend})"))
} }

View file

@ -17,15 +17,15 @@ fn main() -> Result<(), Report> {
color_eyre::install()?; color_eyre::install()?;
let fields = Fields { let fields = Fields {
user_info: get_username_and_hostname(), user_info: get_username_and_hostname()?,
os_name: get_os_pretty_name()?, os_name: get_os_pretty_name()?,
kernel_version: get_system_info()?, kernel_version: get_system_info()?,
shell: get_shell(), shell: get_shell()?,
uptime: get_current()?, uptime: get_current()?,
desktop: get_desktop_info(), window_manager: get_desktop_info()?,
memory_usage: get_memory_usage(sysinfo()?), memory_usage: get_memory_usage(sysinfo()?),
storage: get_root_disk_usage()?, storage: get_root_disk_usage()?,
colors: print_dots(), colors: print_dots()?,
}; };
print_system_info(&fields); print_system_info(&fields);
@ -43,25 +43,13 @@ struct Fields {
kernel_version: String, kernel_version: String,
shell: String, shell: String,
uptime: String, uptime: String,
desktop: String, window_manager: String,
memory_usage: String, memory_usage: String,
storage: String, storage: String,
colors: String, colors: String,
} }
fn print_system_info(fields: &Fields) { fn print_system_info(fields: &Fields) {
let Fields {
user_info,
os_name,
kernel_version,
shell,
uptime,
desktop,
memory_usage,
storage,
colors,
} = fields;
println!( println!(
" "
{CYAN} {BLUE} {user_info} ~{RESET} {CYAN} {BLUE} {user_info} ~{RESET}
@ -69,8 +57,19 @@ fn print_system_info(fields: &Fields) {
{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}WM{RESET} {window_manager}
{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}"); {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,
);
} }

View file

@ -23,5 +23,5 @@ pub fn get_os_pretty_name() -> Result<String, io::Error> {
.to_string() .to_string()
}); });
Ok(pretty_name.unwrap_or("Unknown".to_string())) Ok(pretty_name.unwrap_or_else(|| "Unknown".to_string()))
} }

View file

@ -7,19 +7,19 @@ use std::io::{self};
use crate::colors::{CYAN, GREEN, RED, RESET, YELLOW}; use crate::colors::{CYAN, GREEN, RED, RESET, YELLOW};
pub fn get_username_and_hostname() -> String { pub fn get_username_and_hostname() -> Result<String, io::Error> {
let username = env::var("USER").unwrap_or("unknown_user".to_string()); let username = env::var("USER").unwrap_or_else(|_| "unknown_user".to_string());
let hostname = nix::unistd::gethostname().unwrap_or("unknown_host".to_string().into()); let hostname = nix::unistd::gethostname()?;
let hostname = hostname.to_string_lossy(); let hostname = hostname.to_string_lossy();
format!("{YELLOW}{username}{RED}@{GREEN}{hostname}") Ok(format!("{YELLOW}{username}{RED}@{GREEN}{hostname}"))
} }
pub fn get_shell() -> String { pub fn get_shell() -> Result<String, io::Error> {
let shell_path = env::var("SHELL").unwrap_or("unknown_shell".to_string()); let shell_path = env::var("SHELL").unwrap_or_else(|_| "unknown_shell".to_string());
let shell_name = shell_path.rsplit('/').next().unwrap_or("unknown_shell"); let shell_name = shell_path.rsplit('/').next().unwrap_or("unknown_shell");
shell_name.to_string() Ok(shell_name.to_string())
} }
pub fn get_root_disk_usage() -> Result<String, io::Error> { pub fn get_root_disk_usage() -> Result<String, io::Error> {