use core::fmt;
pub(crate) const NDIM: usize = 7;
pub(crate) const BASE_SYMBOLS: [&str; NDIM] = ["m", "s", "g", "rad", "K", "C", "cd"];
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub struct Dimension(pub [i8; NDIM]);
impl Dimension {
pub const DIMENSIONLESS: Dimension = Dimension([0; NDIM]);
#[must_use]
pub fn is_dimensionless(&self) -> bool {
self.0.iter().all(|&e| e == 0)
}
#[must_use]
#[allow(clippy::should_implement_trait)]
pub fn mul(self, other: Dimension) -> Dimension {
let mut out = self.0;
for (o, &b) in out.iter_mut().zip(other.0.iter()) {
*o = o.saturating_add(b);
}
Dimension(out)
}
#[must_use]
pub fn inv(self) -> Dimension {
let mut out = self.0;
for e in &mut out {
*e = e.saturating_neg();
}
Dimension(out)
}
#[must_use]
pub fn powi(self, n: i8) -> Dimension {
let mut out = self.0;
for e in &mut out {
*e = e.saturating_mul(n);
}
Dimension(out)
}
}
impl fmt::Display for Dimension {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_dimensionless() {
return f.write_str("1");
}
let mut first = true;
for (i, &e) in self.0.iter().enumerate() {
if e == 0 {
continue;
}
if !first {
f.write_str(".")?;
}
first = false;
if e == 1 {
write!(f, "{}", BASE_SYMBOLS[i])?;
} else {
write!(f, "{}{}", BASE_SYMBOLS[i], e)?;
}
}
Ok(())
}
}