use std::fmt::{Display, Formatter};
use std::str::FromStr;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::errors::Result;
use crate::protocol::errors::UnitsError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[cfg_attr(feature = "specta", specta(rename = "MavInspectUnits"))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Units {
Seconds,
DeciSeconds,
CentiSeconds,
MilliSeconds,
MicroSeconds,
NanoSeconds,
Hertz,
MegaHertz,
KiloMetres,
DecaMetres,
Metres,
MetresPerSecond,
MetresPerSecondSquared,
FiveMetresPerSecond,
DeciMetres,
DeciMetresPerSecond,
CentiMetres,
SquareCentiMetres,
CentiMetresPerSecond,
MilliMetres,
MilliMetresPerSecond,
MilliMetresPerHour,
Kelvins,
DegreesCelsius,
CentiDegreeCelsius,
Radians,
RadiansPerSecond,
MilliRadiansPerSecond,
Degrees,
HalfDegrees,
DegreesPerSecond,
CentiDegrees,
CentiDegreesPerSecond,
DegreesE5,
DegreesE7,
RotationsPerMinute,
Volt,
CentiVolt,
MilliVolt,
Ampere,
AmpereHour,
CentiAmpere,
MilliAmpere,
MilliAmpereHour,
MilliTesla,
Gauss,
MilliGauss,
HectoJoule,
Watt,
MilliG,
Grams,
KiloGrams,
Pascal,
HectoPascal,
KiloPascal,
MilliBar,
Percent,
DeciPercent,
CentiPercent,
DeciBel,
DeciBelMilliWats,
KibiByte,
KibiBytePerSecond,
MebiByte,
MebiBytePerSecond,
Bytes,
BytesPerSecond,
BitsPerSecond,
Pixels,
DeciPixels,
GramsPerMinute,
CubicCentiMetresPerMinute,
CubicCentiMetres,
Litres,
}
impl FromStr for Units {
type Err = crate::errors::Error;
fn from_str(s: &str) -> Result<Self> {
Units::parse(s)
}
}
impl From<Units> for String {
fn from(value: Units) -> Self {
value.to_str().to_string()
}
}
impl Display for Units {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_str())
}
}
impl Units {
pub fn parse(s: &str) -> Result<Units> {
let normalized = s.trim();
let known = match normalized {
"s" => Units::Seconds,
"ds" => Units::DeciSeconds,
"cs" => Units::CentiSeconds,
"ms" => Units::MilliSeconds,
"us" => Units::MicroSeconds,
"ns" => Units::NanoSeconds,
"Hz" => Units::Hertz,
"MHz" => Units::MegaHertz,
"km" => Units::KiloMetres,
"dam" => Units::DecaMetres,
"m" => Units::Metres,
"m/s" => Units::MetresPerSecond,
"m/s/s" => Units::MetresPerSecondSquared,
"m/s*5" => Units::FiveMetresPerSecond,
"dm" => Units::DeciMetres,
"dm/s" => Units::DeciMetresPerSecond,
"cm" => Units::CentiMetres,
"cm^2" => Units::SquareCentiMetres,
"cm/s" => Units::CentiMetresPerSecond,
"mm" => Units::MilliMetres,
"mm/s" => Units::MilliMetresPerSecond,
"mm/h" => Units::MilliMetresPerHour,
"K" => Units::Kelvins,
"degC" => Units::DegreesCelsius,
"cdegC" => Units::CentiDegreeCelsius,
"rad" => Units::Radians,
"rad/s" => Units::RadiansPerSecond,
"mrad/s" => Units::MilliRadiansPerSecond,
"deg" => Units::Degrees,
"deg/2" => Units::HalfDegrees,
"deg/s" => Units::DegreesPerSecond,
"cdeg" => Units::CentiDegrees,
"cdeg/s" => Units::CentiDegreesPerSecond,
"degE5" => Units::DegreesE5,
"degE7" => Units::DegreesE7,
"rpm" => Units::RotationsPerMinute,
"V" => Units::Volt,
"cV" => Units::CentiVolt,
"mV" => Units::MilliVolt,
"A" => Units::Ampere,
"Ah" => Units::AmpereHour,
"cA" => Units::CentiAmpere,
"mA" => Units::MilliAmpere,
"mAh" => Units::MilliAmpereHour,
"mT" => Units::MilliTesla,
"gauss" => Units::Gauss,
"mgauss" => Units::MilliGauss,
"hJ" => Units::HectoJoule,
"W" => Units::Watt,
"mG" => Units::MilliG,
"g" => Units::Grams,
"kg" => Units::KiloGrams,
"Pa" => Units::Pascal,
"hPa" => Units::HectoPascal,
"kPa" => Units::KiloPascal,
"mbar" => Units::MilliBar,
"%" => Units::Percent,
"d%" => Units::DeciPercent,
"c%" => Units::CentiPercent,
"dB" => Units::DeciBel,
"dBm" => Units::DeciBelMilliWats,
"KiB" => Units::KibiByte,
"KiB/s" => Units::KibiBytePerSecond,
"MiB" => Units::MebiByte,
"MiB/s" => Units::MebiBytePerSecond,
"bytes" => Units::Bytes,
"bytes/s" => Units::BytesPerSecond,
"bits/s" => Units::BitsPerSecond,
"pix" => Units::Pixels,
"dpix" => Units::DeciPixels,
"g/min" => Units::GramsPerMinute,
"cm^3/min" => Units::CubicCentiMetresPerMinute,
"cm^3" => Units::CubicCentiMetres,
"l" => Units::Litres,
unknown => return Err(UnitsError::Other(unknown.to_string()).into()),
};
Ok(known)
}
pub fn to_str(&self) -> &str {
match self {
Units::Seconds => "s",
Units::DeciSeconds => "ds",
Units::CentiSeconds => "cs",
Units::MilliSeconds => "ms",
Units::MicroSeconds => "us",
Units::NanoSeconds => "ns",
Units::Hertz => "Hz",
Units::MegaHertz => "MHz",
Units::KiloMetres => "km",
Units::DecaMetres => "dam",
Units::Metres => "m",
Units::MetresPerSecond => "m/s",
Units::MetresPerSecondSquared => "m/s/s",
Units::FiveMetresPerSecond => "m/s*5",
Units::DeciMetres => "dm",
Units::DeciMetresPerSecond => "dm/s",
Units::CentiMetres => "cm",
Units::SquareCentiMetres => "cm^2",
Units::CentiMetresPerSecond => "cm/s",
Units::MilliMetres => "mm",
Units::MilliMetresPerSecond => "mm/s",
Units::MilliMetresPerHour => "mm/h",
Units::Kelvins => "K",
Units::DegreesCelsius => "degC",
Units::CentiDegreeCelsius => "cdegC",
Units::Radians => "rad",
Units::RadiansPerSecond => "rad/s",
Units::MilliRadiansPerSecond => "mrad/s",
Units::Degrees => "deg",
Units::HalfDegrees => "deg/2",
Units::DegreesPerSecond => "deg/s",
Units::CentiDegrees => "cdeg",
Units::CentiDegreesPerSecond => "cdeg/s",
Units::DegreesE5 => "degE5",
Units::DegreesE7 => "degE7",
Units::RotationsPerMinute => "rpm",
Units::Volt => "V",
Units::CentiVolt => "cV",
Units::MilliVolt => "mV",
Units::Ampere => "A",
Units::AmpereHour => "Ah",
Units::CentiAmpere => "cA",
Units::MilliAmpere => "mA",
Units::MilliAmpereHour => "mAh",
Units::MilliTesla => "mT",
Units::Gauss => "gauss",
Units::MilliGauss => "mgauss",
Units::HectoJoule => "hJ",
Units::Watt => "W",
Units::MilliG => "mG",
Units::Grams => "g",
Units::KiloGrams => "kg",
Units::Pascal => "Pa",
Units::HectoPascal => "hPa",
Units::KiloPascal => "kPa",
Units::MilliBar => "mbar",
Units::Percent => "%",
Units::DeciPercent => "d%",
Units::CentiPercent => "c%",
Units::DeciBel => "dB",
Units::DeciBelMilliWats => "dBm",
Units::KibiByte => "KiB",
Units::KibiBytePerSecond => "KiB/s",
Units::MebiByte => "MiB",
Units::MebiBytePerSecond => "MiB/s",
Units::Bytes => "bytes",
Units::BytesPerSecond => "bytes/s",
Units::BitsPerSecond => "bits/s",
Units::Pixels => "pix",
Units::DeciPixels => "dpix",
Units::GramsPerMinute => "g/min",
Units::CubicCentiMetresPerMinute => "cm^3/min",
Units::CubicCentiMetres => "cm^3",
Units::Litres => "l",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn all_units() -> Vec<Units> {
vec![
Units::Seconds,
Units::DeciSeconds,
Units::CentiSeconds,
Units::MilliSeconds,
Units::MicroSeconds,
Units::NanoSeconds,
Units::Hertz,
Units::MegaHertz,
Units::KiloMetres,
Units::DecaMetres,
Units::Metres,
Units::MetresPerSecond,
Units::MetresPerSecondSquared,
Units::FiveMetresPerSecond,
Units::DeciMetres,
Units::DeciMetresPerSecond,
Units::CentiMetres,
Units::SquareCentiMetres,
Units::CentiMetresPerSecond,
Units::MilliMetres,
Units::MilliMetresPerSecond,
Units::MilliMetresPerHour,
Units::Kelvins,
Units::DegreesCelsius,
Units::CentiDegreeCelsius,
Units::Radians,
Units::RadiansPerSecond,
Units::MilliRadiansPerSecond,
Units::Degrees,
Units::HalfDegrees,
Units::DegreesPerSecond,
Units::CentiDegrees,
Units::CentiDegreesPerSecond,
Units::DegreesE5,
Units::DegreesE7,
Units::RotationsPerMinute,
Units::Volt,
Units::CentiVolt,
Units::MilliVolt,
Units::Ampere,
Units::AmpereHour,
Units::CentiAmpere,
Units::MilliAmpere,
Units::MilliAmpereHour,
Units::MilliTesla,
Units::Gauss,
Units::MilliGauss,
Units::HectoJoule,
Units::Watt,
Units::MilliG,
Units::Grams,
Units::KiloGrams,
Units::Pascal,
Units::HectoPascal,
Units::KiloPascal,
Units::MilliBar,
Units::Percent,
Units::DeciPercent,
Units::CentiPercent,
Units::DeciBel,
Units::DeciBelMilliWats,
Units::KibiByte,
Units::KibiBytePerSecond,
Units::MebiByte,
Units::MebiBytePerSecond,
Units::Bytes,
Units::BytesPerSecond,
Units::BitsPerSecond,
Units::Pixels,
Units::DeciPixels,
Units::GramsPerMinute,
Units::CubicCentiMetresPerMinute,
Units::CubicCentiMetres,
Units::Litres,
]
}
#[test]
fn units_to_str_parse() {
for unit in all_units() {
let parsed = Units::parse(unit.to_str()).unwrap();
assert_eq!(unit, parsed);
}
}
}