1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
use std::str::FromStr;
use crate::{error::PissError, PissAmount};
impl<T> From<T> for PissAmount
where T: Into<u128> {
fn from(num: T) -> PissAmount {
PissAmount {
to_piss: num.into()
}
}
}
fn parse_suffix(s: &str) -> Result<u128, PissError> {
Ok(match s { // nepal
"k" | "kb" => 1_000,
"m" | "mb" => 1_000_000,
"g" | "gb" => 1_000_000_000,
"t" | "tb" => 1_000_000_000_000,
"p" | "pb" => 1_000_000_000_000_000,
"e" | "eb" => 1_000_000_000_000_000_000,
"x" | "xb" => 1_000_000_000_000_000_000_000,
"y" | "yb" => 1_000_000_000_000_000_000_000_000,
"r" | "rb" => 1_000_000_000_000_000_000_000_000_000,
"q" | "qb" => 1_000_000_000_000_000_000_000_000_000_000,
"ki" | "kib" => 0x400,
"mi" | "mib" => 0x100000,
"gi" | "gib" => 0x40000000,
"ti" | "tib" => 0x10000000000,
"pi" | "pib" => 0x4000000000000,
"ei" | "eib" => 0x1000000000000000,
"xi" | "xib" => 0x400000000000000000,
"yi" | "yib" => 0x100000000000000000000,
"ri" | "rib" => 0x40000000000000000000000,
"qi" | "qib" => 0x10000000000000000000000000,
"" | "b" => 1, // uwu
_ => return Err(PissError::InvalidSuffix(s.into())) // such nepal
})
}
fn parse_file_size(s: &str) -> Result<PissAmount, PissError> {
let mut end = 0;
for (i, c) in s.char_indices() {
if c.is_digit(10) || c == '.' { continue; }
end = i;
break;
}
let num_text = &s[..end];
let suffix_text = &s[end..];
let Ok(num) = num_text.parse::<f64>() else {
return Err(PissError::InvalidNumber(num_text.into()))
};
if num <= 0f64 {
return Err(PissError::NumberNotPositive)
}
let multiplier = parse_suffix(suffix_text)?;
Ok(PissAmount {
to_piss: (num * multiplier as f64) as u128
})
}
impl FromStr for PissAmount {
type Err = PissError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
parse_file_size(s)
}
}
|