pub fn parse_size_limit(s: &str) -> Result<i64, String> {
let s = s.trim().to_lowercase();
if let Ok(bytes) = s.parse::<i64>() {
return Ok(bytes);
}
if s.ends_with('k') {
let number_str = &s[..s.len() - 1];
let number: f64 = number_str
.parse()
.map_err(|_| "Invalid number format".to_string())?;
Ok((number * 1024.0) as i64)
} else if s.ends_with('m') {
let number_str = &s[..s.len() - 1];
let number: f64 = number_str
.parse()
.map_err(|_| "Invalid number format".to_string())?;
Ok((number * 1024.0 * 1024.0) as i64)
} else {
Err("Invalid size format. Use plain bytes, 'k' for KB, or 'm' for MB".to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_bytes() {
assert_eq!(parse_size_limit("1024"), Ok(1024));
assert_eq!(parse_size_limit("0"), Ok(0));
assert_eq!(parse_size_limit("999"), Ok(999));
assert_eq!(parse_size_limit(" 1024 "), Ok(1024));
}
#[test]
fn test_parse_kilobytes() {
assert_eq!(parse_size_limit("1k"), Ok(1024));
assert_eq!(parse_size_limit("1K"), Ok(1024));
assert_eq!(parse_size_limit("0.5k"), Ok(512));
assert_eq!(parse_size_limit("2k"), Ok(2048));
assert_eq!(parse_size_limit(" 1k "), Ok(1024));
}
#[test]
fn test_parse_megabytes() {
assert_eq!(parse_size_limit("1m"), Ok(1048576));
assert_eq!(parse_size_limit("1M"), Ok(1048576));
assert_eq!(parse_size_limit("0.5m"), Ok(524288));
assert_eq!(parse_size_limit("2m"), Ok(2097152));
assert_eq!(parse_size_limit(" 1m "), Ok(1048576));
}
#[test]
fn test_parse_decimal_values() {
assert_eq!(parse_size_limit("1.5k"), Ok(1536));
assert_eq!(parse_size_limit("2.25m"), Ok(2359296));
assert_eq!(parse_size_limit("0.75k"), Ok(768));
}
#[test]
fn test_parse_invalid_format() {
assert!(
parse_size_limit("invalid").is_err(),
"Expected error for 'invalid', got: {:?}",
parse_size_limit("invalid")
);
assert!(
parse_size_limit("1g").is_err(),
"Expected error for '1g', got: {:?}",
parse_size_limit("1g")
);
assert!(
parse_size_limit("1kb").is_err(),
"Expected error for '1kb', got: {:?}",
parse_size_limit("1kb")
);
assert!(
parse_size_limit("k").is_err(),
"Expected error for 'k', got: {:?}",
parse_size_limit("k")
);
assert!(
parse_size_limit("m").is_err(),
"Expected error for 'm', got: {:?}",
parse_size_limit("m")
);
assert!(
parse_size_limit("").is_err(),
"Expected error for empty string, got: {:?}",
parse_size_limit("")
);
}
#[test]
fn test_parse_invalid_numbers() {
assert!(
parse_size_limit("abc").is_err(),
"Expected error for 'abc', got: {:?}",
parse_size_limit("abc")
);
assert!(
parse_size_limit("1.2.3k").is_err(),
"Expected error for '1.2.3k', got: {:?}",
parse_size_limit("1.2.3k")
);
assert!(
parse_size_limit("--1k").is_err(),
"Expected error for '--1k', got: {:?}",
parse_size_limit("--1k")
);
assert!(
parse_size_limit("1..5m").is_err(),
"Expected error for '1..5m', got: {:?}",
parse_size_limit("1..5m")
);
}
#[test]
fn test_parse_negative_values() {
assert_eq!(parse_size_limit("-1"), Ok(-1));
assert_eq!(parse_size_limit("-1k"), Ok(-1024));
assert_eq!(parse_size_limit("-0.5m"), Ok(-524288));
}
#[test]
fn test_parse_large_values() {
assert_eq!(parse_size_limit("1000m"), Ok(1048576000));
assert_eq!(parse_size_limit("9999k"), Ok(10238976));
}
}