sizes/
lib.rs

1#![no_std]
2
3use core::fmt;
4
5pub const B: u64 = 1;
6pub const KB: u64 = 1000 * B;
7pub const MB: u64 = 1000 * KB;
8pub const GB: u64 = 1000 * MB;
9pub const TB: u64 = 1000 * GB;
10pub const PB: u64 = 1000 * TB;
11pub const EB: u64 = 1000 * PB;
12pub const ZB: u128 = 1000 * EB as u128;
13pub const YB: u128 = 1000 * ZB;
14
15pub const KIB: u64 = 1024 * B;
16pub const MIB: u64 = 1024 * KIB;
17pub const GIB: u64 = 1024 * MIB;
18pub const TIB: u64 = 1024 * GIB;
19pub const PIB: u64 = 1024 * TIB;
20pub const EIB: u64 = 1024 * PIB;
21pub const ZIB: u128 = 1024 * EIB as u128;
22pub const YIB: u128 = 1024 * ZIB;
23
24/// Represents size in bytes as per IEC 80000-13
25pub struct BinarySize(pub u128);
26/// Represents size in bytes as per IEC 80000-13, rounded to the
27/// given decimal places when displayed
28pub struct RoundedBinarySize(pub u128, pub u8);
29
30impl fmt::Display for BinarySize {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        match self {
33            s if s.0 as u128 >= YIB => write!(f, "{} YiB", s.0 as u128 / YIB),
34            s if s.0 as u128 >= ZIB => write!(f, "{} ZiB", s.0 as u128 / ZIB),
35            s if s.0 as u128 >= EIB as u128 => write!(f, "{} EiB", s.0 as u128 / EIB as u128),
36            s if s.0 as u64 >= PIB => write!(f, "{} PiB", s.0 as u64 / PIB),
37            s if s.0 as u64 >= TIB => write!(f, "{} TiB", s.0 as u64 / TIB),
38            s if s.0 as u64 >= GIB => write!(f, "{} GiB", s.0 as u64 / GIB),
39            s if s.0 as u64 >= MIB => write!(f, "{} MiB", s.0 as u64 / MIB),
40            s if s.0 as u64 >= KIB => write!(f, "{} KiB", s.0 as u64 / KIB),
41            _ => write!(f, "{} B", self.0)
42        }
43    }
44}
45
46impl BinarySize {
47    /// Returns an instance of RoundedBinarySize that rounds to as many
48    /// decimal places as specified in `decimal_places` upon display
49    pub fn rounded_to(self, decimal_places: u8) -> RoundedBinarySize {
50        RoundedBinarySize(self.0, decimal_places)
51    }
52
53    /// Returns an instance of RoundedBinarySize that rounds to 2 decimal
54    /// places upon display.
55    ///
56    /// Example:
57    ///
58    /// ```rust
59    /// BinarySize::from(1024_u64).rounded()
60    /// ```
61    pub fn rounded(self) -> RoundedBinarySize {
62        self.rounded_to(2)
63    }
64}
65
66impl From<u128> for BinarySize {
67    fn from(value: u128) -> Self {
68        Self(value)
69    }
70}
71
72impl From<u64> for BinarySize {
73    fn from(value: u64) -> Self {
74        Self(value as u128)
75    }
76}
77
78impl From<u32> for BinarySize {
79    fn from(value: u32) -> Self {
80        Self(value as u128)
81    }
82}
83
84impl From<u16> for BinarySize {
85    fn from(value: u16) -> Self {
86        Self(value as u128)
87    }
88}
89
90impl From<u8> for BinarySize {
91    fn from(value: u8) -> Self {
92        Self(value as u128)
93    }
94}
95
96impl From<usize> for BinarySize {
97    fn from(value: usize) -> Self {
98        Self(value as u128)
99    }
100}
101
102impl fmt::Display for RoundedBinarySize {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        match self {
105            s if s.0 as u64 >= PIB => write!(f, "{:.dp$}", s.0 as f64 / PIB as f64, dp=s.1 as usize),
106            s if s.0 as u64 >= TIB => write!(f, "{:.dp$} TiB", s.0 as f64 / TIB as f64, dp=s.1 as usize),
107            s if s.0 as u64 >= GIB => write!(f, "{:.dp$} GiB", s.0 as f64 / GIB as f64, dp=s.1 as usize),
108            s if s.0 as u64 >= MIB => write!(f, "{:.dp$} MiB", s.0 as f64 / MIB as f64, dp=s.1 as usize),
109            s if s.0 as u64 >= KIB => write!(f, "{:.dp$} KiB", s.0 as f64 / KIB as f64, dp=s.1 as usize),
110            _ => write!(f, "{} B", self.0)
111        }
112    }
113}