Tried: byte_unit
, bytesize
and ubyte
.
All of them, when given a string "4.1 MB" return 4099999 bytes. Not good.
Is there anything there that works properly on decimals and not floats?
Tried: byte_unit
, bytesize
and ubyte
.
All of them, when given a string "4.1 MB" return 4099999 bytes. Not good.
Is there anything there that works properly on decimals and not floats?
/// Takes a decimal number.
/// The `unit` argument should be how many digits after the period to accept:
/// for kB => 3, MB => 6, GB => 9
///
/// Returns None on parse failure.
fn parse_decimal(s: &str, unit: usize) -> Option<u128> {
if s == "." || s.is_empty() { return None; }
let (to_dot, from_dot) = s.as_bytes().iter().position(|i| *i == b'.')
.map(|i| (i, i+1))
.unwrap_or((s.len(), s.len()));
let mut res = if to_dot == 0 { 0 } else { s[..to_dot].parse::<u128>().ok()? };
for _ in 0..unit {
res = res.checked_mul(10)?;
}
let after_dot = &s[from_dot..];
if !after_dot.is_empty() {
let mut len = after_dot.len();
while after_dot[..len].as_bytes().last().copied() == Some(b'0') {
len -= 1;
}
if len > unit {
// Not an integer number of bytes.
return None;
}
let mut after_dot = after_dot[..len].parse::<u128>().ok()?;
for _ in 0..unit - len {
after_dot = after_dot.checked_mul(10)?;
}
res += after_dot;
}
Some(res)
}
fn main() {
println!("{:?}", parse_decimal("4.1", 6));
}
Some(4100000)
Thank you, @alice, I haven't expected you code it by yourself
Wow, this forum is awesome!
Anyway, I guess the fact you coded it instead of pointing me to a library means there is probably no crate that does it correctly out-of-the-box.
Ah, nope, I was wrong, there is one that seems to work correctly:
https://crates.io/crates/parse-size
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.