human_sized/
lib.rs

1//! For more information see the [`wikipedia`] article on byte sizes.
2//!
3//! [`wikipedia`]: https://en.wikipedia.org/wiki/Byte#Multiple-byte_units
4#![allow(non_upper_case_globals)]
5
6use std::fmt::Write as _;
7
8
9// Binary constants
10/// Kibibyte
11pub const KiB: i128 = 1024;
12/// Mebibyte
13pub const MiB: i128 = 1024 * KiB;
14/// Gibibyte
15pub const GiB: i128 = 1024 * MiB;
16/// Tebibyte
17pub const TiB: i128 = 1024 * GiB;
18/// Pebibyte
19pub const PiB: i128 = 1024 * TiB;
20/// Exbibyte
21pub const EiB: i128 = 1024 * PiB;
22/// Zebibyte
23pub const ZiB: i128 = 1024 * EiB;
24/// Yobibyte
25pub const YiB: i128 = 1024 * ZiB;
26/// Robibyte
27pub const RiB: i128 = 1024 * YiB;
28/// Quebibyte
29pub const QiB: i128 = 1024 * RiB;
30
31// Decimal constants
32/// Kilobyte
33pub const KB: i128 = 1000;
34/// Megabyte
35pub const MB: i128 = 1000 * KB;
36/// Gigabyte
37pub const GB: i128 = 1000 * MB;
38/// Terabyte
39pub const TB: i128 = 1000 * GB;
40/// Petabyte
41pub const PB: i128 = 1000 * TB;
42/// Exabyte
43pub const EB: i128 = 1000 * PB;
44/// Zettabyte
45pub const ZB: i128 = 1000 * EB;
46/// Yottabyte
47pub const YB: i128 = 1000 * ZB;
48/// Ronnabyte
49pub const RB: i128 = 1000 * YB;
50/// Quettabyte
51pub 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}