pub(crate) fn parse_u64_flexible(s: &str) -> Result<u64, String> {
let s = s.trim();
if let Some(rest) = s.strip_prefix("0x").or_else(|| s.strip_prefix("0X")) {
u64::from_str_radix(rest, 16).map_err(|e| format!("invalid hex: {e}"))
} else {
s.parse::<u64>()
.map_err(|e| format!("invalid integer: {e}"))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn decimal_round_trip() {
assert_eq!(parse_u64_flexible("42").unwrap(), 42);
}
#[test]
fn hex_lowercase_and_uppercase() {
assert_eq!(parse_u64_flexible("0xabcd").unwrap(), 0xabcd);
assert_eq!(parse_u64_flexible("0XABCD").unwrap(), 0xabcd);
}
#[test]
fn whitespace_tolerant() {
assert_eq!(parse_u64_flexible(" 0x10 ").unwrap(), 0x10);
}
#[test]
fn rejects_garbage() {
assert!(parse_u64_flexible("").is_err());
assert!(parse_u64_flexible("0xzz").is_err());
assert!(parse_u64_flexible("abc").is_err());
}
}