pub fn parse_temperature(temp_str: &str) -> Option<u32> {
let cleaned = temp_str
.trim_end_matches(['C', '°', ' '].as_ref())
.split('/')
.next()?
.trim();
cleaned
.parse::<u32>()
.ok()
.or_else(|| cleaned.parse::<f64>().ok().map(|f| f.round() as u32))
}
pub fn parse_power(power_str: &str) -> Option<f64> {
power_str
.trim_end_matches(['W', ' '].as_ref())
.split('/')
.next()?
.trim()
.parse::<f64>()
.ok()
}
pub fn parse_utilization(util_str: &str) -> Option<f64> {
util_str
.trim_end_matches(['%', ' '].as_ref())
.trim()
.parse::<f64>()
.ok()
}
pub fn parse_memory_mb_to_bytes(mem_str: &str) -> Option<u64> {
let cleaned = mem_str
.trim()
.trim_end_matches("MB")
.trim_end_matches("MiB")
.trim();
cleaned.parse::<u64>().ok().map(|mb| mb * 1024 * 1024)
}
pub fn parse_frequency_mhz(freq_str: &str) -> Option<u32> {
freq_str.trim_end_matches("MHz").trim().parse::<u32>().ok()
}
#[allow(dead_code)]
pub fn parse_with_default<T, E>(value_str: &str, default: T, context: &str) -> T
where
T: std::str::FromStr<Err = E>,
E: std::fmt::Display,
{
match value_str.parse::<T>() {
Ok(val) => val,
Err(e) => {
eprintln!("Parse error in {context}: {e} (input: '{value_str}')");
default
}
}
}
pub fn parse_device_id(device_str: &str) -> Option<usize> {
device_str
.chars()
.skip_while(|c| !c.is_ascii_digit())
.collect::<String>()
.parse::<usize>()
.ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_temperature() {
assert_eq!(parse_temperature("45C"), Some(45));
assert_eq!(parse_temperature("45°C"), Some(45));
assert_eq!(parse_temperature("45/90C"), Some(45));
assert_eq!(parse_temperature("41.33°C"), Some(41));
assert_eq!(parse_temperature("37.99°C"), Some(38));
assert_eq!(parse_temperature("invalid"), None);
}
#[test]
fn test_parse_power() {
assert_eq!(parse_power("150W"), Some(150.0));
assert_eq!(parse_power("150.5W"), Some(150.5));
assert_eq!(parse_power("150/250W"), Some(150.0));
assert_eq!(parse_power("invalid"), None);
}
#[test]
fn test_parse_utilization() {
assert_eq!(parse_utilization("85%"), Some(85.0));
assert_eq!(parse_utilization("85.5%"), Some(85.5));
assert_eq!(parse_utilization("invalid"), None);
}
#[test]
fn test_parse_memory_mb_to_bytes() {
assert_eq!(parse_memory_mb_to_bytes("1024MB"), Some(1073741824));
assert_eq!(parse_memory_mb_to_bytes("1024MiB"), Some(1073741824));
assert_eq!(parse_memory_mb_to_bytes("invalid"), None);
}
#[test]
fn test_parse_device_id() {
assert_eq!(parse_device_id("npu0"), Some(0));
assert_eq!(parse_device_id("gpu1"), Some(1));
assert_eq!(parse_device_id("device123"), Some(123));
assert_eq!(parse_device_id("invalid"), None);
}
}