starina_utils/
byte_size.rs

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
use core::fmt;

/// A pretty printer for byte sizes.
///
/// # Example
///
/// ```
/// use starina_utils::byte_size::ByteSize;
///
/// assert_eq!(format!("{}", ByteSize(128)), "128 B");
/// assert_eq!(format!("{}", ByteSize(1024)), "1 KiB");
/// assert_eq!(format!("{}", ByteSize(16 * 1024 * 1024)), "16 MiB");
/// ```
#[repr(transparent)]
pub struct ByteSize(pub usize);

impl ByteSize {
    pub const fn from_kib(kib: usize) -> Self {
        Self(kib * 1024)
    }

    pub fn in_bytes(&self) -> usize {
        self.0
    }

    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let units = &["B", "KiB", "MiB", "GiB", "TiB"];
        let mut value = self.0;
        let mut i = 0;
        let mut unit = units[0];
        while value >= 1024 && i + 1 < units.len() {
            value /= 1024;
            unit = units[i + 1];
            i += 1;
        }

        write!(f, "{} {}", value, unit)
    }
}

impl fmt::Debug for ByteSize {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.fmt(f)
    }
}

impl fmt::Display for ByteSize {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.fmt(f)
    }
}