1use std::str::FromStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
7pub enum StorageUnit {
8 #[default]
10 Bytes,
11 Kilobytes,
13 Megabytes,
15 Gigabytes,
17 Terabytes,
19 Kibibytes,
21 Mebibytes,
23 Gibibytes,
25 Tebibytes,
27}
28
29impl StorageUnit {
30 pub fn units(&self, bytes: u64) -> f64 {
33 let bytes = bytes as f64;
34 match self {
35 Self::Bytes => bytes,
36 Self::Kilobytes => bytes / 1000.0,
37 Self::Megabytes => bytes / 1000000.0,
38 Self::Gigabytes => bytes / 1000000000.0,
39 Self::Terabytes => bytes / 1000000000000.0,
40 Self::Kibibytes => bytes / 1024.0,
41 Self::Mebibytes => bytes / 1048576.0,
42 Self::Gibibytes => bytes / 1073741824.0,
43 Self::Tebibytes => bytes / 1099511627776.0,
44 }
45 }
46
47 pub fn bytes(&self, bytes: u64) -> Option<u64> {
50 match self {
51 Self::Bytes => Some(bytes),
52 Self::Kilobytes => bytes.checked_mul(1000),
53 Self::Megabytes => bytes.checked_mul(1000000),
54 Self::Gigabytes => bytes.checked_mul(1000000000),
55 Self::Terabytes => bytes.checked_mul(1000000000000),
56 Self::Kibibytes => bytes.checked_mul(1024),
57 Self::Mebibytes => bytes.checked_mul(1048576),
58 Self::Gibibytes => bytes.checked_mul(1073741824),
59 Self::Tebibytes => bytes.checked_mul(1099511627776),
60 }
61 }
62}
63
64impl FromStr for StorageUnit {
65 type Err = ();
66
67 fn from_str(s: &str) -> Result<Self, Self::Err> {
68 match s {
69 "B" => Ok(Self::Bytes),
70 "KB" | "K" => Ok(Self::Kilobytes),
71 "MB" | "M" => Ok(Self::Megabytes),
72 "GB" | "G" => Ok(Self::Gigabytes),
73 "TB" | "T" => Ok(Self::Terabytes),
74 "KiB" | "Ki" => Ok(Self::Kibibytes),
75 "MiB" | "Mi" => Ok(Self::Mebibytes),
76 "GiB" | "Gi" => Ok(Self::Gibibytes),
77 "TiB" | "Ti" => Ok(Self::Tebibytes),
78 _ => Err(()),
79 }
80 }
81}
82
83pub fn convert_unit_string(s: &str) -> Option<u64> {
90 let (n, unit) = match s.chars().position(|c| c.is_ascii_alphabetic()) {
92 Some(index) => {
93 let (n, unit) = s.split_at(index);
94 (
95 n.trim().parse::<u64>().ok()?,
96 unit.trim().parse::<StorageUnit>().ok()?,
97 )
98 }
99 None => return None,
100 };
101
102 unit.bytes(n)
103}