pub fn normalize_name(raw: &str) -> String {
let s = raw.trim_start_matches('/');
let mut out = String::new();
for ch in s.chars() {
if ch == '_' || ch == '-' || ch == '.' || ch == '/' {
continue;
}
if ch.is_ascii_uppercase() {
out.push(ch.to_ascii_lowercase());
} else {
out.push(ch);
}
}
out
}
pub fn parse_test_id(raw: &str) -> Option<u32> {
let s = raw.trim_start_matches('/');
if !s.to_ascii_lowercase().starts_with("test") {
return None;
}
let tail = s.get(4..)?;
let digits = tail.trim_start_matches(['-', '_']);
if digits.is_empty() {
return None;
}
digits.parse::<u32>().ok()
}