use crate::detect::{Row, Rows};
#[cfg(target_os = "linux")]
use crate::util::read_trim;
#[cfg(target_os = "linux")]
pub fn detect() -> Rows {
let base = "/sys/devices/virtual/dmi/id";
let product_name = read_trim(&format!("{base}/product_name"));
let product_version = read_trim(&format!("{base}/product_version"));
let board_name = read_trim(&format!("{base}/board_name"));
let (primary, secondary) = match (&product_version, &product_name) {
(Some(pv), pn) if looks_like_name(pv) => (pv.clone(), pn.clone()),
(_, Some(pn)) if looks_like_name(pn) => (pn.clone(), product_version.clone()),
(Some(pv), pn) => (pv.clone(), pn.clone()),
(_, Some(pn)) => (pn.clone(), None),
_ => (board_name.unwrap_or_default(), None),
};
if primary.is_empty() {
return Vec::new();
}
let value = match secondary {
Some(s) if !s.is_empty() && s != primary => format!("{primary} ({s})"),
_ => primary,
};
vec![Row::val(value)]
}
#[cfg(target_os = "linux")]
fn looks_like_name(s: &str) -> bool {
s.chars().any(|c| c.is_ascii_alphabetic()) && s.contains(' ')
}
#[cfg(target_os = "macos")]
pub fn detect() -> Rows {
let model = crate::sys::sysctl_string("hw.model");
let marketing = crate::util::cmd("ioreg", &["-rd1", "-c", "IOPlatformExpertDevice"])
.and_then(|dump| crate::util::ioreg_string(&dump, "product-name"));
match (marketing, model) {
(Some(name), Some(id)) if name != id => vec![Row::val(format!("{name} ({id})"))],
(Some(name), _) => vec![Row::val(name)],
(None, Some(id)) => vec![Row::val(id)],
(None, None) => Vec::new(),
}
}