use std::os::fd::AsRawFd as _; use crate::args; use crate::colors; use crate::power; use crate::vcs; pub struct PromptData { pub shell: colors::ShellType, pub error_code: u8, pub hostname: Option, pub terminal_cols: Option, pub pwd: Option, pub home: Option, pub user: Option, pub is_root: bool, pub time: time::OffsetDateTime, pub power_info: power::PowerInfo, pub vcs_info: Option>, } pub fn collect(opts: args::CommandLineOptions) -> PromptData { start_talking_about_time!("collecting data"); let hostname = hostname(); talk_about_time!("hostname"); let terminal_cols = terminal_cols(); talk_about_time!("terminal_cols"); let pwd = pwd(); talk_about_time!("pwd"); let home = home(); talk_about_time!("home"); let user = user(); talk_about_time!("user"); let is_root = is_root(); talk_about_time!("is_root"); let time = time(); talk_about_time!("time"); let power_info = power_info(); talk_about_time!("power_info"); let vcs_info = vcs_info(); talk_about_time!("vcs_info"); stop_talking_about_time!(); PromptData { shell: opts.shell, error_code: opts.error_code, hostname, terminal_cols, pwd, home, user, is_root, time, power_info, vcs_info, } } fn hostname() -> Option { if let Ok(name) = hostname::get() { let mut name = name.into_string().unwrap(); if let Some(idx) = name.find('.') { name.truncate(idx); } Some(name) } else { None } } fn terminal_cols() -> Option { for fd in [ std::io::stdout().as_raw_fd(), std::io::stderr().as_raw_fd(), std::io::stdin().as_raw_fd(), ] { if let Some((w, _h)) = terminal_size::terminal_size_using_fd(fd) { return Some(usize::from(w.0)); } } None } fn pwd() -> Option { std::env::var("PWD").map(std::path::PathBuf::from).ok() } fn home() -> Option { std::env::var("HOME").map(std::path::PathBuf::from).ok() } fn user() -> Option { users::get_current_username().map(|s| s.into_string().unwrap()) } fn is_root() -> bool { users::get_current_uid() == 0 } fn time() -> time::OffsetDateTime { time::OffsetDateTime::now_local().unwrap() } fn power_info() -> power::PowerInfo { power::PowerInfo::new() } fn vcs_info() -> Option> { vcs::detect() }