use crate::ty::*;
#[derive(Default, Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Unit {
#[default]
None,
Percent,
Meter,
Centimeter,
Millimeter,
Micrometer,
Inch,
Foot,
Yard,
Deg,
DegS,
Grad,
Turns,
Rad,
Gram,
Kilogram,
Pound,
Ounce,
Meter2,
Centimeter2,
Millimeter2,
Micrometer2,
Inch2,
Foot2,
Yard2,
Meter3,
Centimeter3,
Millimeter3,
Micrometer3,
Inch3,
Foot3,
Yard3,
Liter,
Centiliter,
Milliliter,
Microliter,
GramPerMeter3,
GramPerMillimeter3,
}
impl std::fmt::Display for Unit {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::None => write!(f, ""),
Self::Percent => write!(f, "%"),
Self::Meter => write!(f, "m"),
Self::Centimeter => write!(f, "cm"),
Self::Millimeter => write!(f, "mm"),
Self::Micrometer => write!(f, "µm"),
Self::Inch => write!(f, "in"),
Self::Foot => write!(f, "ft"),
Self::Yard => write!(f, "yd"),
Self::Deg => write!(f, "deg"),
Self::DegS => write!(f, "°"),
Self::Grad => write!(f, "grad"),
Self::Turns => write!(f, "turns"),
Self::Rad => write!(f, "rad"),
Self::Gram => write!(f, "g"),
Self::Kilogram => write!(f, "kg"),
Self::Pound => write!(f, "lb"),
Self::Ounce => write!(f, "oz"),
Self::Meter2 => write!(f, "m³"),
Self::Centimeter2 => write!(f, "cm²"),
Self::Millimeter2 => write!(f, "mm²"),
Self::Micrometer2 => write!(f, "µm²"),
Self::Inch2 => write!(f, "in²"),
Self::Foot2 => write!(f, "ft²"),
Self::Yard2 => write!(f, "yd²"),
Self::Meter3 => write!(f, "m³"),
Self::Centimeter3 => write!(f, "cm³"),
Self::Millimeter3 => write!(f, "mm³"),
Self::Micrometer3 => write!(f, "µm³"),
Self::Inch3 => write!(f, "in³"),
Self::Foot3 => write!(f, "ft³"),
Self::Yard3 => write!(f, "yd³"),
Self::Milliliter => write!(f, "ml"),
Self::Centiliter => write!(f, "cl"),
Self::Liter => write!(f, "l"),
Self::Microliter => write!(f, "µl"),
Self::GramPerMeter3 => write!(f, "g/m³"),
Self::GramPerMillimeter3 => write!(f, "g/mm³"),
}
}
}
impl Ty for Unit {
fn ty(&self) -> Type {
Type::Quantity(self.quantity_type())
}
}
impl Unit {
pub fn quantity_type(&self) -> QuantityType {
match self {
Self::None | Self::Percent => QuantityType::Scalar,
Self::Meter
| Self::Centimeter
| Self::Millimeter
| Self::Micrometer
| Self::Inch
| Self::Foot
| Self::Yard => QuantityType::Length,
Self::Deg | Self::DegS | Self::Grad | Self::Turns | Self::Rad => QuantityType::Angle,
Self::Gram | Self::Kilogram | Self::Pound | Self::Ounce => QuantityType::Weight,
Self::Meter2
| Self::Centimeter2
| Self::Millimeter2
| Self::Micrometer2
| Self::Inch2
| Self::Foot2
| Self::Yard2 => QuantityType::Area,
Self::Meter3
| Self::Centimeter3
| Self::Millimeter3
| Self::Micrometer3
| Self::Inch3
| Self::Foot3
| Self::Yard3
| Self::Liter
| Self::Centiliter
| Self::Milliliter
| Self::Microliter => QuantityType::Volume,
Self::GramPerMeter3 | Self::GramPerMillimeter3 => QuantityType::Density,
}
}
pub fn factor(&self) -> f64 {
match &self {
Self::None => 1.0,
Self::Percent => 0.01_f64,
Self::Meter => 1_000_f64,
Self::Centimeter => 10_f64,
Self::Millimeter => 1.0,
Self::Micrometer => 1.0 / 1_000_f64,
Self::Inch => 25.4_f64,
Self::Foot => 304.8_f64,
Self::Yard => 914.4_f64,
Self::Deg | Self::DegS => 1.0 / 180. * std::f64::consts::PI,
Self::Grad => 1.0 / 200. * std::f64::consts::PI,
Self::Turns => 2.0 * std::f64::consts::PI,
Self::Rad => 1.0,
Self::Gram => 1.0,
Self::Kilogram => 1_000_f64,
Self::Pound => 453.59237_f64,
Self::Ounce => 28.349_523_125_f64,
Self::Meter2 => 1_000_000_f64,
Self::Centimeter2 => 100_f64,
Self::Millimeter2 => 1.0,
Self::Micrometer2 => 0.000_000_1,
Self::Inch2 => 645.16_f64,
Self::Foot2 => 92_903_043.04_f64,
Self::Yard2 => 836_127.36_f64,
Self::Meter3 => 1_000_000_000_f64,
Self::Centimeter3 => 1_000_f64,
Self::Millimeter3 => 1.0,
Self::Micrometer3 => 0.000_000_000_1,
Self::Inch3 => 16_387.06_f64,
Self::Foot3 => 28_316_846.592_f64,
Self::Yard3 => 764_554_857.984_f64,
Self::Liter => 1_000_000_f64,
Self::Centiliter => 10_000_f64,
Self::Milliliter => 1_000_f64,
Self::Microliter => 1_000_000.0_f64,
Self::GramPerMeter3 => 1_000_000_000_f64,
Self::GramPerMillimeter3 => 1_f64,
}
}
pub fn normalize(self, x: f64) -> f64 {
x * self.factor()
}
pub fn denormalize(self, x: f64) -> f64 {
x / self.factor()
}
}