use std::collections::HashMap;
#[cfg_attr(not(any(target_os = "windows", all_smi_level_zero)), allow(dead_code))]
pub fn note_metrics_source(detail: &mut HashMap<String, String>, source: &str) {
let entry = detail.entry("Metrics Source".to_string()).or_default();
if entry.is_empty() {
*entry = source.to_string();
return;
}
if entry.split(" + ").any(|part| part == source) {
return;
}
entry.push_str(" + ");
entry.push_str(source);
}
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
pub fn missing_metric_sources<'a>(
detail: &HashMap<String, String>,
fields: &[&'a str],
) -> Vec<&'a str> {
fields
.iter()
.copied()
.filter(|field| {
detail
.get(&format!("Source: {field}"))
.is_none_or(|source| source == "unavailable")
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn metrics_source_starts_clean_when_absent() {
let mut detail = HashMap::new();
note_metrics_source(&mut detail, "DXGI");
assert_eq!(detail["Metrics Source"], "DXGI");
note_metrics_source(&mut detail, "PDH");
assert_eq!(detail["Metrics Source"], "DXGI + PDH");
}
#[test]
fn appending_is_idempotent() {
let mut detail = HashMap::new();
for _ in 0..3 {
note_metrics_source(&mut detail, "WMI");
note_metrics_source(&mut detail, "DXGI");
}
assert_eq!(detail["Metrics Source"], "WMI + DXGI");
}
#[test]
fn a_later_layer_never_erases_an_earlier_one() {
let mut detail = HashMap::new();
note_metrics_source(&mut detail, "WMI");
note_metrics_source(&mut detail, "DXGI");
note_metrics_source(&mut detail, "PDH");
note_metrics_source(&mut detail, "Level Zero Sysman");
assert_eq!(
detail["Metrics Source"],
"WMI + DXGI + PDH + Level Zero Sysman"
);
}
#[test]
fn deduplication_compares_whole_parts() {
let mut detail = HashMap::new();
note_metrics_source(&mut detail, "Level Zero Sysman");
note_metrics_source(&mut detail, "Level Zero");
assert_eq!(detail["Metrics Source"], "Level Zero Sysman + Level Zero");
}
const METRIC_FIELDS: &[&str] = &["Temperature", "Power", "Frequency", "Utilization"];
fn detail_with(pairs: &[(&str, &str)]) -> HashMap<String, String> {
pairs
.iter()
.map(|(field, source)| (format!("Source: {field}"), (*source).to_string()))
.collect()
}
#[test]
fn a_fully_sourced_device_is_missing_nothing() {
let detail = detail_with(&[
("Temperature", "Level Zero Sysman"),
("Power", "Level Zero Sysman"),
("Frequency", "Level Zero Sysman"),
("Utilization", "PDH"),
]);
assert!(missing_metric_sources(&detail, METRIC_FIELDS).is_empty());
}
#[test]
fn the_unavailable_sentinel_counts_as_missing() {
let detail = detail_with(&[
("Temperature", "unavailable"),
("Power", "Level Zero Sysman"),
("Frequency", "Level Zero Sysman"),
("Utilization", "PDH"),
]);
assert_eq!(
missing_metric_sources(&detail, METRIC_FIELDS),
vec!["Temperature"]
);
}
#[test]
fn an_absent_key_also_counts_as_missing() {
let detail = detail_with(&[("Utilization", "PDH")]);
assert_eq!(
missing_metric_sources(&detail, METRIC_FIELDS),
vec!["Temperature", "Power", "Frequency"]
);
}
#[test]
fn the_result_follows_the_requested_order() {
let detail = HashMap::new();
assert_eq!(
missing_metric_sources(&detail, &["Fan", "Power"]),
vec!["Fan", "Power"]
);
assert_eq!(
missing_metric_sources(&detail, &["Power", "Fan"]),
vec!["Power", "Fan"]
);
}
}