#![allow(clippy::too_many_lines)]
use crate::error::AamlError;
use crate::pipeline::ExecutionContext;
use crate::types_aam::TypeAAM;
use crate::types_aam::primitive_type::PrimitiveType;
use std::fmt;
pub enum PhysicsTypes {
Meter,
Kilogram,
Second,
Ampere,
Kelvin,
Mole,
Candela,
SquareMeter,
CubicMeter,
MeterPerSecond,
MeterPerSecondSquared,
RadianPerSecond,
RadianPerSecondSquared,
Hertz,
KilogramPerCubicMeter,
KilogramMeterPerSecond,
Newton,
NewtonMeter,
Pascal,
Joule,
Watt,
NewtonPerMeter,
Dimensionless,
KilogramSquareMeter,
JoulePerKilogramKelvin,
JoulePerKilogram,
JoulePerKelvin,
Coulomb,
Volt,
Ohm,
OhmMeter,
Farad,
VoltPerMeter,
Tesla,
Weber,
Henry,
Dioptre,
Percentage,
Becquerel,
Gray,
Sievert,
ElectronVolt,
Barn,
LightYear,
Parsec,
AstronomicalUnit,
HubbleConstant,
Siemens,
CoulombPerCubicMeter,
CoulombPerSquareMeter,
FaradPerMeter,
HenryPerMeter,
AmperePerMeter,
AmperePerSquareMeter,
VoltPerKelvin,
PascalSecond,
SquareMeterPerSecond,
NewtonSecond,
NewtonPerCubicMeter,
JouleSecond,
KilogramPerMole,
CubicMeterPerKilogram,
MeterPerCubicSecond,
Lumen,
Lux,
LumenSecond,
CandelaPerSquareMeter,
WattPerSteradian,
WattPerSquareMeter,
WattPerMeterKelvin,
JoulePerSquareMeter,
Radian,
Steradian,
Bit,
Decibel,
Katal,
MolePerCubicMeter,
NewtonPerMeterSquared,
JoulePerMole,
JoulePerMoleKelvin,
KelvinPerWatt,
KilogramPerSecond,
CubicMeterPerSecond,
InverseMeter,
NewtonPerCoulomb,
WeberPerMeter,
TeslaSquareMeter,
ArcDegree,
ArcMinute,
ArcSecond,
Bar,
MillimeterOfMercury,
Atmosphere,
Torr,
Poise,
Stokes,
Sverdrup,
Rayl,
Gal,
Maxwell,
Gauss,
Oersted,
Gilbert,
Franklin,
Debye,
Angstrom,
Lambert,
Phot,
Stilb,
Kayser,
Calorie,
BritishThermalUnit,
Langley,
Fahrenheit,
Celsius,
Rankine,
Curie,
Roentgen,
Rutherford,
Fermi,
Dalton,
Byte,
Baud,
Erlang,
MetabolicEquivalent,
Jansky,
MachNumber,
Knots,
NauticalMile,
Horsepower,
}
impl TypeAAM for PhysicsTypes {
fn from_name(name: &str) -> Result<Self, AamlError> {
match name.to_lowercase().replace(['_', '-'], "").as_str() {
"meter" => Ok(Self::Meter),
"kilogram" => Ok(Self::Kilogram),
"second" => Ok(Self::Second),
"ampere" => Ok(Self::Ampere),
"kelvin" => Ok(Self::Kelvin),
"mole" => Ok(Self::Mole),
"candela" => Ok(Self::Candela),
"squaremeter" => Ok(Self::SquareMeter),
"cubicmeter" => Ok(Self::CubicMeter),
"radian" => Ok(Self::Radian),
"steradian" => Ok(Self::Steradian),
"arcdegree" => Ok(Self::ArcDegree),
"arcminute" => Ok(Self::ArcMinute),
"arcsecond" => Ok(Self::ArcSecond),
"angstrom" => Ok(Self::Angstrom),
"inversemeter" => Ok(Self::InverseMeter),
"meterpersecond" => Ok(Self::MeterPerSecond),
"meterpersecondsquared" => Ok(Self::MeterPerSecondSquared),
"radianpersecond" => Ok(Self::RadianPerSecond),
"radianpersecondsquared" => Ok(Self::RadianPerSecondSquared),
"newton" => Ok(Self::Newton),
"newtonmeter" => Ok(Self::NewtonMeter),
"pascal" => Ok(Self::Pascal),
"joule" => Ok(Self::Joule),
"watt" => Ok(Self::Watt),
"hertz" => Ok(Self::Hertz),
"kilogrampercubicmeter" => Ok(Self::KilogramPerCubicMeter),
"kilogrammeterpersecond" => Ok(Self::KilogramMeterPerSecond),
"newtonpermeter" => Ok(Self::NewtonPerMeter),
"kilogramsquaremeter" => Ok(Self::KilogramSquareMeter),
"pascalsecond" => Ok(Self::PascalSecond),
"squaremeterpersecond" => Ok(Self::SquareMeterPerSecond),
"newtonsecond" => Ok(Self::NewtonSecond),
"newtonpercubicmeter" => Ok(Self::NewtonPerCubicMeter),
"joulesecond" => Ok(Self::JouleSecond),
"meterpercubicsecond" => Ok(Self::MeterPerCubicSecond),
"kilogrampersecond" => Ok(Self::KilogramPerSecond),
"cubicmeterpersecond" => Ok(Self::CubicMeterPerSecond),
"newtonpermetersquared" => Ok(Self::NewtonPerMeterSquared),
"coulomb" => Ok(Self::Coulomb),
"volt" => Ok(Self::Volt),
"ohm" => Ok(Self::Ohm),
"ohmmeter" => Ok(Self::OhmMeter),
"farad" => Ok(Self::Farad),
"voltpermeter" => Ok(Self::VoltPerMeter),
"tesla" => Ok(Self::Tesla),
"weber" => Ok(Self::Weber),
"henry" => Ok(Self::Henry),
"siemens" => Ok(Self::Siemens),
"coulombpercubicmeter" => Ok(Self::CoulombPerCubicMeter),
"coulombpersquaremeter" => Ok(Self::CoulombPerSquareMeter),
"faradpermeter" => Ok(Self::FaradPerMeter),
"henrypermeter" => Ok(Self::HenryPerMeter),
"amperepermeter" => Ok(Self::AmperePerMeter),
"amperepersquaremeter" => Ok(Self::AmperePerSquareMeter),
"newtonpercoulomb" => Ok(Self::NewtonPerCoulomb),
"weberpermeter" => Ok(Self::WeberPerMeter),
"teslasquaremeter" => Ok(Self::TeslaSquareMeter),
"jouleperkilogramkelvin" => Ok(Self::JoulePerKilogramKelvin),
"jouleperkilogram" => Ok(Self::JoulePerKilogram),
"jouleperkelvin" => Ok(Self::JoulePerKelvin),
"voltperkelvin" => Ok(Self::VoltPerKelvin),
"wattpermeterkelvin" => Ok(Self::WattPerMeterKelvin),
"joulepermolekelvin" => Ok(Self::JoulePerMoleKelvin),
"kelvinperwatt" => Ok(Self::KelvinPerWatt),
"celsius" => Ok(Self::Celsius),
"fahrenheit" => Ok(Self::Fahrenheit),
"rankine" => Ok(Self::Rankine),
"kilogrampermole" => Ok(Self::KilogramPerMole),
"cubicmeterperkilogram" => Ok(Self::CubicMeterPerKilogram),
"katal" => Ok(Self::Katal),
"molepercubicmeter" => Ok(Self::MolePerCubicMeter),
"joulepermole" => Ok(Self::JoulePerMole),
"atomicmassunit" | "dalton" => Ok(Self::Dalton), "barn" => Ok(Self::Barn),
"dioptre" => Ok(Self::Dioptre),
"becquerel" => Ok(Self::Becquerel),
"gray" => Ok(Self::Gray),
"sievert" => Ok(Self::Sievert),
"electronvolt" => Ok(Self::ElectronVolt),
"lumen" => Ok(Self::Lumen),
"lux" => Ok(Self::Lux),
"lumensecond" => Ok(Self::LumenSecond),
"candelapersquaremeter" => Ok(Self::CandelaPerSquareMeter),
"wattpersteradian" => Ok(Self::WattPerSteradian),
"wattpersquaremeter" => Ok(Self::WattPerSquareMeter),
"joulepersquaremeter" => Ok(Self::JoulePerSquareMeter),
"curie" => Ok(Self::Curie),
"roentgen" => Ok(Self::Roentgen),
"rutherford" => Ok(Self::Rutherford),
"lightyear" => Ok(Self::LightYear),
"parsec" => Ok(Self::Parsec),
"astronomicalunit" => Ok(Self::AstronomicalUnit),
"hubbleconstant" => Ok(Self::HubbleConstant),
"jansky" => Ok(Self::Jansky),
"bit" => Ok(Self::Bit),
"byte" => Ok(Self::Byte),
"baud" => Ok(Self::Baud),
"erlang" => Ok(Self::Erlang),
"dimensionless" => Ok(Self::Dimensionless),
"percentage" => Ok(Self::Percentage),
"decibel" => Ok(Self::Decibel),
"bar" => Ok(Self::Bar),
"millimeterofmercury" => Ok(Self::MillimeterOfMercury),
"atmosphere" => Ok(Self::Atmosphere),
"torr" => Ok(Self::Torr),
"poise" => Ok(Self::Poise),
"stokes" => Ok(Self::Stokes),
"sverdrup" => Ok(Self::Sverdrup),
"rayl" => Ok(Self::Rayl),
"gal" => Ok(Self::Gal),
"maxwell" => Ok(Self::Maxwell),
"gauss" => Ok(Self::Gauss),
"oersted" => Ok(Self::Oersted),
"gilbert" => Ok(Self::Gilbert),
"franklin" => Ok(Self::Franklin),
"debye" => Ok(Self::Debye),
"lambert" => Ok(Self::Lambert),
"phot" => Ok(Self::Phot),
"stilb" => Ok(Self::Stilb),
"kayser" => Ok(Self::Kayser),
"calorie" => Ok(Self::Calorie),
"britishthermalunit" => Ok(Self::BritishThermalUnit),
"langley" => Ok(Self::Langley),
"fermi" => Ok(Self::Fermi),
"metabolicequivalent" => Ok(Self::MetabolicEquivalent),
"machnumber" => Ok(Self::MachNumber),
"knots" => Ok(Self::Knots),
"nauticalmile" => Ok(Self::NauticalMile),
"horsepower" => Ok(Self::Horsepower),
_ => Err(AamlError::NotFound {
key: name.to_string(),
context: "physics types".to_string(),
diagnostics: Some(Box::new(crate::error::ErrorDiagnostics::new(
"Unknown physics type",
format!("Physics type '{name}' is not recognized"),
"Check the type name or use a built-in physics unit",
))),
}),
}
}
fn base_type(&self) -> PrimitiveType {
match self {
Self::Bit | Self::Byte | Self::Baud => PrimitiveType::I32,
_ => PrimitiveType::F64,
}
}
fn validate(&self, value: &str, _context: &ExecutionContext) -> Result<(), AamlError> {
match self.base_type() {
PrimitiveType::I32 => {
value.parse::<i32>().map_err(|_| AamlError::InvalidValue {
details: format!("'{value}' is not a valid integer"),
expected: "integer value".to_string(),
diagnostics: Some(Box::new(crate::error::ErrorDiagnostics::new(
"Invalid unit value",
format!("Unit {self} requires an integer, got '{value}'"),
"Use integer notation: 42, -100, etc.",
))),
})?;
}
PrimitiveType::F64 => {
value.parse::<f64>().map_err(|_| AamlError::InvalidValue {
details: format!("'{value}' is not a valid number"),
expected: "floating-point number".to_string(),
diagnostics: Some(Box::new(crate::error::ErrorDiagnostics::new(
"Invalid unit value",
format!("Unit {self} requires a number, got '{value}'"),
"Use numeric notation: 3.14, 2.0, -1.5, etc.",
))),
})?;
}
_ => {
return Err(AamlError::InvalidValue {
details: format!("Unit {self} has unsupported base type"),
expected: "i32 or f64".to_string(),
diagnostics: Some(Box::new(crate::error::ErrorDiagnostics::new(
"Unsupported unit type",
format!("Cannot validate unit {self} with current base type"),
"Check the unit definition",
))),
});
}
}
Ok(())
}
}
impl fmt::Display for PhysicsTypes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::Meter => "meter",
Self::Kilogram => "kilogram",
Self::Second => "second",
Self::Ampere => "ampere",
Self::Kelvin => "kelvin",
Self::Mole => "mole",
Self::Candela => "candela",
Self::SquareMeter => "squareMeter",
Self::CubicMeter => "cubicMeter",
Self::MeterPerSecond => "meterPerSecond",
Self::MeterPerSecondSquared => "meterPerSecondSquared",
Self::RadianPerSecond => "radianPerSecond",
Self::RadianPerSecondSquared => "radianPerSecondSquared",
Self::Hertz => "hertz",
Self::KilogramPerCubicMeter => "kilogramPerCubicMeter",
Self::KilogramMeterPerSecond => "kilogramMeterPerSecond",
Self::Newton => "newton",
Self::NewtonMeter => "newtonMeter",
Self::Pascal => "pascal",
Self::Joule => "joule",
Self::Watt => "watt",
Self::NewtonPerMeter => "newtonPerMeter",
Self::Dimensionless => "dimensionless",
Self::KilogramSquareMeter => "kilogramSquareMeter",
Self::JoulePerKilogramKelvin => "joulePerKilogramKelvin",
Self::JoulePerKilogram => "joulePerKilogram",
Self::JoulePerKelvin => "joulePerKelvin",
Self::Coulomb => "coulomb",
Self::Volt => "volt",
Self::Ohm => "ohm",
Self::OhmMeter => "ohmMeter",
Self::Farad => "farad",
Self::VoltPerMeter => "voltPerMeter",
Self::Tesla => "tesla",
Self::Weber => "weber",
Self::Henry => "henry",
Self::Dioptre => "dioptre",
Self::Percentage => "percentage",
Self::Becquerel => "becquerel",
Self::Gray => "gray",
Self::Sievert => "sievert",
Self::ElectronVolt => "electronVolt",
Self::Barn => "barn",
Self::LightYear => "lightYear",
Self::Parsec => "parsec",
Self::AstronomicalUnit => "astronomicalUnit",
Self::HubbleConstant => "hubbleConstant",
Self::Siemens => "siemens",
Self::CoulombPerCubicMeter => "coulombPerCubicMeter",
Self::CoulombPerSquareMeter => "coulombPerSquareMeter",
Self::FaradPerMeter => "faradPerMeter",
Self::HenryPerMeter => "henryPerMeter",
Self::AmperePerMeter => "amperePerMeter",
Self::AmperePerSquareMeter => "amperePerSquareMeter",
Self::VoltPerKelvin => "voltPerKelvin",
Self::PascalSecond => "pascalSecond",
Self::SquareMeterPerSecond => "squareMeterPerSecond",
Self::NewtonSecond => "newtonSecond",
Self::NewtonPerCubicMeter => "newtonPerCubicMeter",
Self::JouleSecond => "jouleSecond",
Self::KilogramPerMole => "kilogramPerMole",
Self::CubicMeterPerKilogram => "cubicMeterPerKilogram",
Self::MeterPerCubicSecond => "meterPerCubicSecond",
Self::Lumen => "lumen",
Self::Lux => "lux",
Self::LumenSecond => "lumenSecond",
Self::CandelaPerSquareMeter => "candelaPerSquareMeter",
Self::WattPerSteradian => "wattPerSteradian",
Self::WattPerSquareMeter => "wattPerSquareMeter",
Self::WattPerMeterKelvin => "wattPerMeterKelvin",
Self::JoulePerSquareMeter => "joulePerSquareMeter",
Self::Radian => "radian",
Self::Steradian => "steradian",
Self::Bit => "bit",
Self::Decibel => "decibel",
Self::Katal => "katal",
Self::MolePerCubicMeter => "molePerCubicMeter",
Self::NewtonPerMeterSquared => "newtonPerMeterSquared",
Self::JoulePerMole => "joulePerMole",
Self::JoulePerMoleKelvin => "joulePerMoleKelvin",
Self::KelvinPerWatt => "kelvinPerWatt",
Self::KilogramPerSecond => "kilogramPerSecond",
Self::CubicMeterPerSecond => "cubicMeterPerSecond",
Self::InverseMeter => "inverseMeter",
Self::NewtonPerCoulomb => "newtonPerCoulomb",
Self::WeberPerMeter => "weberPerMeter",
Self::TeslaSquareMeter => "teslaSquareMeter",
Self::ArcDegree => "arcDegree",
Self::ArcMinute => "arcMinute",
Self::ArcSecond => "arcSecond",
Self::Bar => "bar",
Self::MillimeterOfMercury => "millimeterOfMercury",
Self::Atmosphere => "atmosphere",
Self::Torr => "torr",
Self::Poise => "poise",
Self::Stokes => "stokes",
Self::Sverdrup => "sverdrup",
Self::Rayl => "rayl",
Self::Gal => "gal",
Self::Maxwell => "maxwell",
Self::Gauss => "gauss",
Self::Oersted => "oersted",
Self::Gilbert => "gilbert",
Self::Franklin => "franklin",
Self::Debye => "debye",
Self::Angstrom => "angstrom",
Self::Lambert => "lambert",
Self::Phot => "phot",
Self::Stilb => "stilb",
Self::Kayser => "kayser",
Self::Calorie => "calorie",
Self::BritishThermalUnit => "britishThermalUnit",
Self::Langley => "langley",
Self::Fahrenheit => "fahrenheit",
Self::Celsius => "celsius",
Self::Rankine => "rankine",
Self::Curie => "curie",
Self::Roentgen => "roentgen",
Self::Rutherford => "rutherford",
Self::Fermi => "fermi",
Self::Dalton => "dalton",
Self::Byte => "byte",
Self::Baud => "baud",
Self::Erlang => "erlang",
Self::MetabolicEquivalent => "metabolicEquivalent",
Self::Jansky => "jansky",
Self::MachNumber => "machNumber",
Self::Knots => "knots",
Self::NauticalMile => "nauticalMile",
Self::Horsepower => "horsepower",
};
write!(f, "{s}")
}
}