use crate::core::str::cstr_to_str;
use crate::error::Error;
#[derive(Debug)]
pub struct Options {
pub all: bool,
pub kernel_name: bool,
pub node_name: bool,
pub kernel_release: bool,
pub kernel_version: bool,
pub machine: bool,
pub processor: bool,
pub hardware_platform: bool,
pub operating_system: bool,
}
impl Default for Options {
fn default() -> Self {
Self {
all: false,
kernel_name: false,
node_name: false,
kernel_release: false,
kernel_version: false,
machine: true,
processor: false,
hardware_platform: false,
operating_system: false,
}
}
}
impl Options {
pub fn with_all() -> Self {
Self {
all: true,
..Self::default()
}
}
}
#[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "")))]
const HOST_OS: &str = "GNU/Linux";
#[cfg(all(target_os = "linux", not(any(target_env = "gnu", target_env = ""))))]
const HOST_OS: &str = "Linux";
#[cfg(target_os = "windows")]
const HOST_OS: &str = "Windows NT";
#[cfg(target_os = "freebsd")]
const HOST_OS: &str = "FreeBSD";
#[cfg(target_os = "netbsd")]
const HOST_OS: &str = "NetBSD";
#[cfg(target_os = "openbsd")]
const HOST_OS: &str = "OpenBSD";
#[cfg(target_vendor = "apple")]
const HOST_OS: &str = "Darwin";
#[cfg(target_os = "fuchsia")]
const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";
pub fn uname(options: &Options) -> Result<String, Error> {
let mut uts = nc::utsname_t::default();
let _ = unsafe { nc::uname(&mut uts)? };
let mut result = Vec::new();
if options.all || options.kernel_name {
result.push(cstr_to_str(&uts.sysname)?);
}
if options.all || options.node_name {
result.push(cstr_to_str(&uts.nodename)?);
}
if options.all || options.kernel_release {
result.push(cstr_to_str(&uts.release)?);
}
if options.all || options.kernel_version {
result.push(cstr_to_str(&uts.version)?);
}
if options.all || options.machine {
result.push(cstr_to_str(&uts.machine)?);
}
if options.all || options.processor {
}
if options.all || options.hardware_platform {
let domain_name = cstr_to_str(&uts.domainname)?;
if domain_name != "(none)" {
result.push(domain_name);
}
}
if options.all || options.operating_system {
result.push(HOST_OS);
}
Ok(result.join(" "))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_uname() {
assert!(uname(&Options::default()).is_ok());
assert!(uname(&Options::with_all()).is_ok());
}
}