use core::fmt::Display;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct MemorySize(pub u64);
impl MemorySize {
pub fn new(bytes: usize) -> Self {
MemorySize(bytes as u64)
}
pub fn as_bytes(&self) -> usize {
self.0 as usize
}
pub fn as_kilobytes(&self) -> f64 {
self.0 as f64 / 1024.0
}
pub fn as_megabytes(&self) -> f64 {
self.0 as f64 / (1024.0 * 1024.0)
}
pub fn as_gigabytes(&self) -> f64 {
self.0 as f64 / (1024.0 * 1024.0 * 1024.0)
}
pub fn as_terabytes(&self) -> f64 {
self.0 as f64 / (1024.0 * 1024.0 * 1024.0 * 1024.0)
}
pub fn appropriate_unit(&self) -> MemoryUnit {
if self.0 >= 1024 * 1024 * 1024 * 1024 {
MemoryUnit::Terabytes
} else if self.0 >= 1024 * 1024 * 1024 {
MemoryUnit::Gigabytes
} else if self.0 >= 1024 * 1024 {
MemoryUnit::Megabytes
} else if self.0 >= 1024 {
MemoryUnit::Kilobytes
} else {
MemoryUnit::Bytes
}
}
}
impl Display for MemorySize {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let unit = self.appropriate_unit();
match unit {
MemoryUnit::Bytes => write!(f, "{} B", self.as_bytes()),
MemoryUnit::Kilobytes => write!(f, "{:.2} KiB", self.as_kilobytes()),
MemoryUnit::Megabytes => write!(f, "{:.2} MiB", self.as_megabytes()),
MemoryUnit::Gigabytes => write!(f, "{:.2} GiB", self.as_gigabytes()),
MemoryUnit::Terabytes => write!(f, "{:.2} TiB", self.as_terabytes()),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MemoryUnit {
Bytes,
Kilobytes,
Megabytes,
Gigabytes,
Terabytes,
}