pub(crate) fn parse_slurm_memory(s: &str) -> Option<i64> {
let s = s.trim();
if s.is_empty() {
return None;
}
if s == "0" {
return Some(0);
}
let (num_str, multiplier) = if let Some(rest) = s.strip_suffix('K') {
(rest, 1_024i64)
} else if let Some(rest) = s.strip_suffix('M') {
(rest, 1_024 * 1_024)
} else if let Some(rest) = s.strip_suffix('G') {
(rest, 1_024 * 1_024 * 1_024)
} else if let Some(rest) = s.strip_suffix('T') {
(rest, 1_024 * 1_024 * 1_024 * 1_024)
} else {
(s, 1)
};
let n: f64 = num_str.parse().ok()?;
Some((n * multiplier as f64) as i64)
}
pub(crate) fn parse_slurm_cpu_time(s: &str) -> Option<f64> {
let s = s.trim();
if s.is_empty() {
return None;
}
let (days, rest) = if let Some(dash) = s.find('-') {
let d: u64 = s[..dash].parse().ok()?;
(d, &s[dash + 1..])
} else {
(0, s)
};
let parts: Vec<&str> = rest.split(':').collect();
if parts.len() != 3 {
return None;
}
let h: u64 = parts[0].parse().ok()?;
let m: u64 = parts[1].parse().ok()?;
let sec: f64 = parts[2].parse().ok()?;
Some((days * 86_400 + h * 3_600 + m * 60) as f64 + sec)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_slurm_memory_units() {
assert_eq!(parse_slurm_memory("0"), Some(0));
assert_eq!(parse_slurm_memory("512K"), Some(512 * 1_024));
assert_eq!(parse_slurm_memory("2M"), Some(2 * 1_024 * 1_024));
assert_eq!(parse_slurm_memory("1G"), Some(1_024 * 1_024 * 1_024));
assert_eq!(
parse_slurm_memory("1T"),
Some(1_024 * 1_024 * 1_024 * 1_024)
);
}
#[test]
fn test_parse_slurm_memory_decimal() {
let result = parse_slurm_memory("1.50M").unwrap();
assert!((result as f64 - 1.5 * 1_024.0 * 1_024.0).abs() < 1.0);
}
#[test]
fn test_parse_slurm_memory_no_suffix() {
assert_eq!(parse_slurm_memory("1024"), Some(1024));
}
#[test]
fn test_parse_slurm_memory_empty() {
assert_eq!(parse_slurm_memory(""), None);
assert_eq!(parse_slurm_memory(" "), None);
}
#[test]
fn test_parse_slurm_cpu_time_hhmmss() {
assert_eq!(parse_slurm_cpu_time("00:01:30"), Some(90.0));
assert_eq!(parse_slurm_cpu_time("01:00:00"), Some(3_600.0));
assert_eq!(parse_slurm_cpu_time("00:00:00"), Some(0.0));
}
#[test]
fn test_parse_slurm_cpu_time_with_days() {
assert_eq!(parse_slurm_cpu_time("1-02:30:00"), Some(95_400.0));
assert_eq!(parse_slurm_cpu_time("0-00:00:01"), Some(1.0));
}
#[test]
fn test_parse_slurm_cpu_time_empty() {
assert_eq!(parse_slurm_cpu_time(""), None);
assert_eq!(parse_slurm_cpu_time(" "), None);
}
#[test]
fn test_parse_slurm_cpu_time_fractional_seconds() {
let result = parse_slurm_cpu_time("00:00:01.5").unwrap();
assert!((result - 1.5).abs() < 0.001);
}
}