#[derive(Debug, Clone)]
pub enum Done {}
impl std::fmt::Display for Done {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
unreachable!()
}
}
pub fn parse_size(s: &str) -> Result<u64, String> {
let s = s.trim().to_lowercase();
let mut unit_start = 0;
for (i, ch) in s.char_indices() {
if !ch.is_ascii_digit() && ch != '.' {
unit_start = i;
break;
}
}
if unit_start == 0 {
return Err(format!(
"Invalid size '{s}': expected format like '10mb', '500kb'"
));
}
let number_str = &s[..unit_start];
let unit_str = &s[unit_start..];
let number: f64 = number_str
.parse()
.map_err(|_| format!("Invalid size '{s}': cannot parse numeric value '{number_str}'"))?;
let multiplier = match unit_str {
"b" | "byte" | "bytes" => 1.0,
"k" | "kb" | "kilobyte" | "kilobytes" => 1024.0,
"m" | "mb" | "megabyte" | "megabytes" => 1024.0 * 1024.0,
"g" | "gb" | "gigabyte" | "gigabytes" => 1024.0 * 1024.0 * 1024.0,
"t" | "tb" | "terabyte" | "terabytes" => 1024.0 * 1024.0 * 1024.0 * 1024.0,
_ => {
return Err(format!(
"Invalid size '{s}': unknown unit '{unit_str}' (expected: b, kb, mb, gb, tb)"
))
}
};
Ok((number * multiplier) as u64)
}