diff --git a/src/unit.rs b/src/unit.rs new file mode 100644 index 0000000..a1393f8 --- /dev/null +++ b/src/unit.rs @@ -0,0 +1,84 @@ +use std::fmt::Display; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Unit { + Byte, + + Kilo, + Kibi, + + Mega, + Mibi, + + Giga, + Gibi, + + Tera, + Tibi, +} +impl Unit { + pub fn parse(s: &str) -> Result { + let s = s.to_lowercase(); + match s.as_str() { + "b" => Ok(Self::Byte), + "k" | "kb" => Ok(Self::Kilo), + "ki" => Ok(Self::Kibi), + "m" | "mb" => Ok(Self::Mega), + "mi" => Ok(Self::Mibi), + "g" | "gb" => Ok(Self::Giga), + "gi" => Ok(Self::Gibi), + "t" | "tb" => Ok(Self::Tera), + "ti" => Ok(Self::Tibi), + _ => Err(s), + } + } + + pub fn convert(self, n: u64) -> String { + format!("{}{}", n/self.integer_value(), self.units_pretty()) + } + + const fn units_pretty(self) -> &'static str { + match self { + Self::Byte => "", + Self::Kilo => " K", + Self::Kibi => " Ki", + Self::Mega => " M", + Self::Mibi => " Mi", + Self::Giga => " G", + Self::Gibi => " Gi", + Self::Tera => " T", + Self::Tibi => " Ti", + } + } + + const fn integer_value(self) -> u64 { + match self { + Self::Byte => 1, + Self::Kilo => 1_000, + Self::Kibi => 1_024, + Self::Mega => 1_000_000, + Self::Mibi => 1_048_576, + Self::Giga => 1_000_000_000, + Self::Gibi => 1_073_741_824, + Self::Tera => 1_000_000_000_000, + Self::Tibi => 1_099_511_627_776, + } + } +} +impl Display for Unit { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + Self::Byte => "b", + Self::Kilo => "K", + Self::Kibi => "Ki", + Self::Mega => "M", + Self::Mibi => "Mi", + Self::Giga => "G", + Self::Gibi => "Gi", + Self::Tera => "T", + Self::Tibi => "Ti", + }; + + f.write_str(s) + } +}