1#![allow(non_upper_case_globals)]
5
6use std::fmt::Write as _;
7
8
9pub const KiB: i128 = 1024;
12pub const MiB: i128 = 1024 * KiB;
14pub const GiB: i128 = 1024 * MiB;
16pub const TiB: i128 = 1024 * GiB;
18pub const PiB: i128 = 1024 * TiB;
20pub const EiB: i128 = 1024 * PiB;
22pub const ZiB: i128 = 1024 * EiB;
24pub const YiB: i128 = 1024 * ZiB;
26pub const RiB: i128 = 1024 * YiB;
28pub const QiB: i128 = 1024 * RiB;
30
31pub const KB: i128 = 1000;
34pub const MB: i128 = 1000 * KB;
36pub const GB: i128 = 1000 * MB;
38pub const TB: i128 = 1000 * GB;
40pub const PB: i128 = 1000 * TB;
42pub const EB: i128 = 1000 * PB;
44pub const ZB: i128 = 1000 * EB;
46pub const YB: i128 = 1000 * ZB;
48pub const RB: i128 = 1000 * YB;
50pub const QB: i128 = 1000 * RB;
52
53pub fn binary(byte_size: impl Into<i128>) -> Result<String, std::fmt::Error> {
54 let byte_size = byte_size.into();
55 let mut buffer = String::new();
56 match byte_size {
57 ..KiB => write!(buffer, "{} B", byte_size)?,
58 KiB..MiB => write!(buffer, "{} KiB", byte_size / KiB)?,
59 MiB..GiB => write!(buffer, "{} MiB", byte_size / MiB)?,
60 GiB..TiB => write!(buffer, "{} GiB", byte_size / GiB)?,
61 TiB..PiB => write!(buffer, "{} TiB", byte_size / TiB)?,
62 PiB..EiB => write!(buffer, "{} PiB", byte_size / PiB)?,
63 EiB..ZiB => write!(buffer, "{} EiB", byte_size / EiB)?,
64 ZiB..YiB => write!(buffer, "{} ZiB", byte_size / ZiB)?,
65 YiB..RiB => write!(buffer, "{} YiB", byte_size / YiB)?,
66 RiB..QiB => write!(buffer, "{} RiB", byte_size / RiB)?,
67 QiB.. => write!(buffer, "{} QiB", byte_size / QiB)?,
68 }
69 Ok(buffer)
70}
71
72pub fn decimal(byte_size: impl Into<i128>) -> Result<String, std::fmt::Error> {
73 let byte_size = byte_size.into();
74 let mut buffer = String::new();
75 match byte_size {
76 ..KB => write!(buffer, "{} B", byte_size)?,
77 KB..MB => write!(buffer, "{} KB", byte_size / KB)?,
78 MB..GB => write!(buffer, "{} MB", byte_size / MB)?,
79 GB..TB => write!(buffer, "{} GB", byte_size / GB)?,
80 TB..PB => write!(buffer, "{} TB", byte_size / TB)?,
81 PB..EB => write!(buffer, "{} PB", byte_size / PB)?,
82 EB..ZB => write!(buffer, "{} EB", byte_size / EB)?,
83 ZB..YB => write!(buffer, "{} ZB", byte_size / ZB)?,
84 YB..RB => write!(buffer, "{} YB", byte_size / YB)?,
85 RB..QB => write!(buffer, "{} RB", byte_size / RB)?,
86 QB.. => write!(buffer, "{} QB", byte_size / QB)?,
87 }
88 Ok(buffer)
89}
90
91
92#[cfg(test)]
93mod tests {
94
95 #[test]
96 fn binary() -> std::fmt::Result {
97 let hsize = super::binary(4_400)?;
98 println!("hsize={hsize}");
99 assert_eq!(hsize, "4 KiB");
100 Ok(())
101 }
102
103 #[test]
104 fn decimal() -> std::fmt::Result {
105 let hsize = super::decimal(4_812_935)?;
106 println!("hsize={hsize}");
107 assert_eq!(hsize, "4 MB");
108 Ok(())
109 }
110}