#[derive(Debug, Clone, PartialEq, Eq, Default)]
#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Unit {
#[default]
Plain,
Si(String),
Bytes,
Suffix(String),
}
impl Unit {
pub fn si(unit: impl Into<String>) -> Unit {
Unit::Si(unit.into())
}
pub fn suffix(suffix: impl Into<String>) -> Unit {
Unit::Suffix(suffix.into())
}
pub fn is_plain(&self) -> bool {
*self == Unit::Plain
}
}
pub(crate) const BINARY_UNITS: [&str; 9] =
["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
pub(crate) fn binary_prefix(max_abs: f64) -> (usize, f64) {
let power = if max_abs.is_finite() && max_abs >= 1024.0 {
((max_abs.log2() / 10.0).floor() as usize).min(BINARY_UNITS.len() - 1)
} else {
0
};
(power, 1024f64.powi(power as i32))
}