use regex::Regex;
use std::sync::OnceLock;
pub fn extract_http_status(message: &str) -> Option<u16> {
static RE: OnceLock<Regex> = OnceLock::new();
let re = RE.get_or_init(|| {
Regex::new(r"(?i)\bhttp[^0-9]{0,64}(\d{3})\b|\bstatus:\s*(\d{3})\b").expect("valid status regex")
});
let caps = re.captures(message)?;
caps.get(1).or_else(|| caps.get(2)).and_then(|m| m.as_str().parse().ok())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extract_status_handles_common_shapes() {
assert_eq!(
extract_http_status("HTTP status server error (503 Service Unavailable) for url (https://example.com/)"),
Some(503)
);
assert_eq!(extract_http_status("error sending request: status: 403 Forbidden"), Some(403));
assert_eq!(extract_http_status("server returned 404"), None);
assert_eq!(extract_http_status("request timed out after 30s"), None);
assert_eq!(extract_http_status("no error here"), None);
}
#[test]
fn extract_status_ignores_non_three_digit_numbers() {
assert_eq!(extract_http_status("timed out after 30000ms"), None);
assert_eq!(extract_http_status("response body 1234 bytes"), None);
}
#[test]
fn extract_status_handles_status_with_spaces() {
assert_eq!(extract_http_status("error: status: 429 Too Many Requests"), Some(429));
}
}