use crate::{Quantity, Unit};
use core::f64::consts::PI;
use qtty_derive::Unit;
pub use crate::dimension::Length;
pub trait LengthUnit: Unit<Dim = Length> {}
impl<T: Unit<Dim = Length>> LengthUnit for T {}
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "m", dimension = Length, ratio = 1.0)]
pub struct Meter;
pub type Meters = Quantity<Meter>;
pub const M: Meters = Meters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "km", dimension = Length, ratio = 1_000.0)]
pub struct Kilometer;
pub type Km = Kilometer;
pub type Kilometers = Quantity<Km>;
pub const KM: Kilometers = Kilometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "cm", dimension = Length, ratio = 1e-2)]
pub struct Centimeter;
pub type Cm = Centimeter;
pub type Centimeters = Quantity<Cm>;
pub const CM: Centimeters = Centimeters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "mm", dimension = Length, ratio = 1e-3)]
pub struct Millimeter;
pub type Mm = Millimeter;
pub type Millimeters = Quantity<Mm>;
pub const MM: Millimeters = Millimeters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "μm", dimension = Length, ratio = 1e-6)]
pub struct Micrometer;
pub type Um = Micrometer;
pub type Micrometers = Quantity<Um>;
pub const UM: Micrometers = Micrometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "nm", dimension = Length, ratio = 1e-9)]
pub struct Nanometer;
pub type Nm = Nanometer;
pub type Nanometers = Quantity<Nm>;
pub const NM: Nanometers = Nanometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "pm", dimension = Length, ratio = 1e-12)]
pub struct Picometer;
pub type Picometers = Quantity<Picometer>;
pub const PMETER: Picometers = Picometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "fm", dimension = Length, ratio = 1e-15)]
pub struct Femtometer;
pub type Femtometers = Quantity<Femtometer>;
pub const FM: Femtometers = Femtometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "am", dimension = Length, ratio = 1e-18)]
pub struct Attometer;
pub type Attometers = Quantity<Attometer>;
pub const AM: Attometers = Attometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "zm", dimension = Length, ratio = 1e-21)]
pub struct Zeptometer;
pub type Zeptometers = Quantity<Zeptometer>;
pub const ZMETER: Zeptometers = Zeptometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "ym", dimension = Length, ratio = 1e-24)]
pub struct Yoctometer;
pub type Yoctometers = Quantity<Yoctometer>;
pub const YMETER: Yoctometers = Yoctometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Mm", dimension = Length, ratio = 1e6)]
pub struct Megameter;
pub type MegaMeter = Megameter;
pub type Megameters = Quantity<Megameter>;
pub const MEGAMETER: Megameters = Megameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "dm", dimension = Length, ratio = 1e-1)]
pub struct Decimeter;
pub type Decimeters = Quantity<Decimeter>;
pub const DM: Decimeters = Decimeters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "dam", dimension = Length, ratio = 1e1)]
pub struct Decameter;
pub type Decameters = Quantity<Decameter>;
pub const DAM: Decameters = Decameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "hm", dimension = Length, ratio = 1e2)]
pub struct Hectometer;
pub type Hectometers = Quantity<Hectometer>;
pub const HM: Hectometers = Hectometers::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Gm", dimension = Length, ratio = 1e9)]
pub struct Gigameter;
pub type Gigameters = Quantity<Gigameter>;
pub const GM: Gigameters = Gigameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Tm", dimension = Length, ratio = 1e12)]
pub struct Terameter;
pub type Terameters = Quantity<Terameter>;
pub const TM: Terameters = Terameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Pm", dimension = Length, ratio = 1e15)]
pub struct Petameter;
pub type Petameters = Quantity<Petameter>;
pub const PM: Petameters = Petameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Em", dimension = Length, ratio = 1e18)]
pub struct Exameter;
pub type Exameters = Quantity<Exameter>;
pub const EM: Exameters = Exameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Zm", dimension = Length, ratio = 1e21)]
pub struct Zettameter;
pub type Zettameters = Quantity<Zettameter>;
pub const ZM: Zettameters = Zettameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Ym", dimension = Length, ratio = 1e24)]
pub struct Yottameter;
pub type Yottameters = Quantity<Yottameter>;
pub const YM: Yottameters = Yottameters::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "au", dimension = Length, ratio = 149_597_870_700.0)]
pub struct AstronomicalUnit;
pub type Au = AstronomicalUnit;
pub type AstronomicalUnits = Quantity<Au>;
pub const AU: AstronomicalUnits = AstronomicalUnits::new(1.0);
const SPEED_OF_LIGHT_M_PER_S: f64 = 299_792_458.0;
const SECONDS_PER_DAY: f64 = 86_400.0;
const DAYS_PER_JULIAN_YEAR: f64 = 36525.0 / 100.0; const SECONDS_PER_JULIAN_YEAR: f64 = SECONDS_PER_DAY * DAYS_PER_JULIAN_YEAR;
const METERS_PER_LIGHT_YEAR: f64 = SPEED_OF_LIGHT_M_PER_S * SECONDS_PER_JULIAN_YEAR;
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "ly", dimension = Length, ratio = METERS_PER_LIGHT_YEAR)]
pub struct LightYear;
pub type Ly = LightYear;
pub type LightYears = Quantity<Ly>;
pub const LY: LightYears = LightYears::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "pc", dimension = Length, ratio = 149_597_870_700.0 * (648_000.0 / PI))]
pub struct Parsec;
pub type Pc = Parsec;
pub type Parsecs = Quantity<Pc>;
pub const PC: Parsecs = Parsecs::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "kpc", dimension = Length, ratio = 1_000.0 * 149_597_870_700.0 * (648_000.0 / PI))]
pub struct Kiloparsec;
pub type Kiloparsecs = Quantity<Kiloparsec>;
pub const KPC: Kiloparsecs = Kiloparsecs::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Mpc", dimension = Length, ratio = 1_000_000.0 * 149_597_870_700.0 * (648_000.0 / PI))]
pub struct Megaparsec;
pub type Megaparsecs = Quantity<Megaparsec>;
pub const MPC: Megaparsecs = Megaparsecs::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Gpc", dimension = Length, ratio = 1_000_000_000.0 * 149_597_870_700.0 * (648_000.0 / PI))]
pub struct Gigaparsec;
pub type Gigaparsecs = Quantity<Gigaparsec>;
pub const GPC: Gigaparsecs = Gigaparsecs::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "in", dimension = Length, ratio = 254.0 / 10_000.0)]
pub struct Inch;
pub type Inches = Quantity<Inch>;
pub const INCH: Inches = Inches::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "ft", dimension = Length, ratio = 3048.0 / 10_000.0)]
pub struct Foot;
pub type Feet = Quantity<Foot>;
pub const FT: Feet = Feet::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "yd", dimension = Length, ratio = 9144.0 / 10_000.0)]
pub struct Yard;
pub type Yards = Quantity<Yard>;
pub const YD: Yards = Yards::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "mi", dimension = Length, ratio = 1_609_344.0 / 1_000.0)]
pub struct Mile;
pub type Miles = Quantity<Mile>;
pub const MI: Miles = Miles::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "nmi", dimension = Length, ratio = 1_852.0)]
pub struct NauticalMile;
pub type NauticalMiles = Quantity<NauticalMile>;
pub const NMI: NauticalMiles = NauticalMiles::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "ch", dimension = Length, ratio = 66.0 * (3048.0 / 10_000.0))]
pub struct Chain;
pub type Chains = Quantity<Chain>;
pub const CHAIN: Chains = Chains::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "rd", dimension = Length, ratio = 16.5 * (3048.0 / 10_000.0))]
pub struct Rod;
pub type Rods = Quantity<Rod>;
pub const ROD: Rods = Rods::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "lk", dimension = Length, ratio = (66.0 / 100.0) * (3048.0 / 10_000.0))]
pub struct Link;
pub type Links = Quantity<Link>;
pub const LINK: Links = Links::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "ftm", dimension = Length, ratio = 6.0 * (3048.0 / 10_000.0))]
pub struct Fathom;
pub type Fathoms = Quantity<Fathom>;
pub const FTM: Fathoms = Fathoms::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Cmer", dimension = Length, ratio = 40_007_863.0)]
pub struct EarthMeridionalCircumference;
pub type EarthMeridionalCircumferences = Quantity<EarthMeridionalCircumference>;
pub const C_MERIDIONAL: EarthMeridionalCircumferences = EarthMeridionalCircumferences::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Ceq", dimension = Length, ratio = 40_075_017.0)]
pub struct EarthEquatorialCircumference;
pub type EarthEquatorialCircumferences = Quantity<EarthEquatorialCircumference>;
pub const C_EQUATORIAL: EarthEquatorialCircumferences = EarthEquatorialCircumferences::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "a0", dimension = Length, ratio = 5.291_772_109_03e-11)]
pub struct BohrRadius;
pub type BohrRadii = Quantity<BohrRadius>;
pub const A0: BohrRadii = BohrRadii::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "re", dimension = Length, ratio = 2.817_940_326_2e-15)]
pub struct ClassicalElectronRadius;
pub type ClassicalElectronRadii = Quantity<ClassicalElectronRadius>;
pub const RE: ClassicalElectronRadii = ClassicalElectronRadii::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "lp", dimension = Length, ratio = 1.616_255e-35)]
pub struct PlanckLength;
pub type PlanckLengths = Quantity<PlanckLength>;
pub const LP: PlanckLengths = PlanckLengths::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "lambda_bar_e", dimension = Length, ratio = 3.861_592_679_6e-13)]
pub struct ElectronReducedComptonWavelength;
pub type ElectronReducedComptonWavelengths = Quantity<ElectronReducedComptonWavelength>;
pub const LAMBDA_BAR_E: ElectronReducedComptonWavelengths =
ElectronReducedComptonWavelengths::new(1.0);
pub mod nominal {
use super::*;
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Rsun", dimension = Length, ratio = 695_700_000.0)]
pub struct SolarRadius;
pub type SolarRadiuses = Quantity<SolarRadius>;
pub const RSUN: SolarRadiuses = SolarRadiuses::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Rearth", dimension = Length, ratio = 6_371_000.0)]
pub struct EarthRadius;
pub type EarthRadii = Quantity<EarthRadius>;
pub const R_EARTH: EarthRadii = EarthRadii::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Rearth_eq", dimension = Length, ratio = 6_378_137.0)]
pub struct EarthEquatorialRadius;
pub type EarthEquatorialRadii = Quantity<EarthEquatorialRadius>;
pub const R_EARTH_EQ: EarthEquatorialRadii = EarthEquatorialRadii::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Rearth_p", dimension = Length, ratio = 6_356_752.314_2)]
pub struct EarthPolarRadius;
pub type EarthPolarRadii = Quantity<EarthPolarRadius>;
pub const R_EARTH_P: EarthPolarRadii = EarthPolarRadii::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Rmoon", dimension = Length, ratio = 1_737_400.0)]
pub struct LunarRadius;
pub type LunarRadii = Quantity<LunarRadius>;
pub const R_MOON: LunarRadii = LunarRadii::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Rjup", dimension = Length, ratio = 71_492_000.0)]
pub struct JupiterRadius;
pub type JupiterRadii = Quantity<JupiterRadius>;
pub const R_JUPITER: JupiterRadii = JupiterRadii::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "LD", dimension = Length, ratio = 384_400_000.0)]
pub struct LunarDistance;
pub type LunarDistances = Quantity<LunarDistance>;
pub const LD: LunarDistances = LunarDistances::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "Dsun", dimension = Length, ratio = 2.0 * 695_700_000.0)]
pub struct SolarDiameter;
pub type SolarDiameters = Quantity<SolarDiameter>;
pub const D_SUN: SolarDiameters = SolarDiameters::new(1.0);
crate::impl_unit_from_conversions!(SolarRadius, Kilometer);
#[cfg(feature = "cross-unit-ops")]
crate::impl_unit_cross_unit_ops!(SolarRadius, Kilometer);
}
crate::impl_unit_from_conversions!(
Meter,
Decimeter,
Centimeter,
Millimeter,
Micrometer,
Nanometer,
Picometer,
Femtometer,
Attometer,
Zeptometer,
Yoctometer,
Decameter,
Hectometer,
Kilometer,
Megameter,
Gigameter,
Terameter,
Petameter,
Exameter,
Zettameter,
Yottameter,
AstronomicalUnit,
LightYear,
Parsec,
Kiloparsec,
Megaparsec,
Gigaparsec,
Inch,
Foot,
Yard,
Mile,
NauticalMile,
Chain,
Rod,
Link,
Fathom,
EarthMeridionalCircumference,
EarthEquatorialCircumference,
BohrRadius,
ClassicalElectronRadius,
PlanckLength,
ElectronReducedComptonWavelength
);
#[cfg(feature = "cross-unit-ops")]
crate::impl_unit_cross_unit_ops!(
Meter,
Decimeter,
Centimeter,
Millimeter,
Micrometer,
Nanometer,
Picometer,
Femtometer,
Attometer,
Zeptometer,
Yoctometer,
Decameter,
Hectometer,
Kilometer,
Megameter,
Gigameter,
Terameter,
Petameter,
Exameter,
Zettameter,
Yottameter,
AstronomicalUnit,
LightYear,
Parsec,
Kiloparsec,
Megaparsec,
Gigaparsec,
Inch,
Foot,
Yard,
Mile,
NauticalMile,
Chain,
Rod,
Link,
Fathom,
EarthMeridionalCircumference,
EarthEquatorialCircumference,
BohrRadius,
ClassicalElectronRadius,
PlanckLength,
ElectronReducedComptonWavelength
);
#[cfg(test)]
mod tests {
use super::nominal::SolarRadiuses;
use super::*;
use approx::{assert_abs_diff_eq, assert_relative_eq};
use proptest::prelude::*;
#[test]
fn kilometer_to_meter() {
let km = Kilometers::new(1.0);
let m = km.to::<Meter>();
assert_abs_diff_eq!(m.value(), 1000.0, epsilon = 1e-9);
}
#[test]
fn meter_to_kilometer() {
let m = Meters::new(1000.0);
let km = m.to::<Kilometer>();
assert_abs_diff_eq!(km.value(), 1.0, epsilon = 1e-12);
}
#[test]
fn au_to_meters() {
let au = AstronomicalUnits::new(1.0);
let m = au.to::<Meter>();
assert_abs_diff_eq!(m.value(), 149_597_870_700.0, epsilon = 1e-6);
}
#[test]
fn au_to_kilometers() {
let au = AstronomicalUnits::new(1.0);
let km = au.to::<Kilometer>();
assert_relative_eq!(km.value(), 149_597_870.7, max_relative = 1e-12);
}
#[test]
fn light_year_to_meters() {
let ly = LightYears::new(1.0);
let m = ly.to::<Meter>();
assert_relative_eq!(m.value(), METERS_PER_LIGHT_YEAR, max_relative = 1e-12);
}
#[test]
fn light_year_to_kilometers() {
let ly = LightYears::new(1.0);
let km = ly.to::<Kilometer>();
assert_relative_eq!(km.value(), 9_460_730_472_580.000_8, max_relative = 1e-9);
}
#[test]
fn au_to_light_year() {
let au = AstronomicalUnits::new(1.0);
let ly = au.to::<LightYear>();
assert_relative_eq!(ly.value(), 1.582e-5, max_relative = 1e-3);
}
#[test]
fn light_year_to_au() {
let ly = LightYears::new(1.0);
let au = ly.to::<AstronomicalUnit>();
assert_relative_eq!(au.value(), 63241.0, max_relative = 1e-3);
}
#[test]
fn from_impl_au_to_ly() {
let au = 1.0 * AU;
let ly: LightYears = au.into();
assert_relative_eq!(ly.value(), 1.582e-5, max_relative = 1e-3);
}
#[test]
fn from_impl_ly_to_au() {
let ly = 1.0 * LY;
let au: AstronomicalUnits = ly.into();
assert_relative_eq!(au.value(), 63241.0, max_relative = 1e-3);
}
#[test]
fn parsec_to_light_year() {
let pc = Parsecs::new(1.0);
let ly = pc.to::<LightYear>();
let expected = (AstronomicalUnit::RATIO * (648_000.0 / PI)) / LightYear::RATIO;
assert_relative_eq!(ly.value(), expected, max_relative = 1e-15);
}
#[test]
fn parsec_to_au() {
let pc = Parsecs::new(1.0);
let au = pc.to::<AstronomicalUnit>();
assert_relative_eq!(au.value(), 3.26 * 63241.0, max_relative = 1e-2);
}
#[test]
fn parsec_ratio_sanity() {
let lhs = Parsec::RATIO / AstronomicalUnit::RATIO;
let rhs = 648_000.0 / PI;
assert_relative_eq!(lhs, rhs, max_relative = 1e-12);
}
#[test]
fn solar_radius_to_meters() {
let sr = SolarRadiuses::new(1.0);
let m = sr.to::<Meter>();
assert_abs_diff_eq!(m.value(), 695_700_000.0, epsilon = 1e-3);
}
#[test]
fn solar_radius_to_km() {
let sr = SolarRadiuses::new(1.0);
let km = sr.to::<Kilometer>();
assert_abs_diff_eq!(km.value(), 695_700.0, epsilon = 1e-6);
}
#[test]
fn roundtrip_km_m() {
let original = Kilometers::new(42.5);
let converted = original.to::<Meter>();
let back = converted.to::<Kilometer>();
assert_abs_diff_eq!(back.value(), original.value(), epsilon = 1e-12);
}
#[test]
fn roundtrip_au_ly() {
let original = AstronomicalUnits::new(10000.0);
let converted = original.to::<LightYear>();
let back = converted.to::<AstronomicalUnit>();
assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
}
#[test]
fn roundtrip_parsec_ly() {
let original = Parsecs::new(5.0);
let converted = original.to::<LightYear>();
let back = converted.to::<Parsec>();
assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
}
#[test]
fn inch_to_meter_exact_ratio() {
let inch = Inches::new(1.0);
let m = inch.to::<Meter>();
assert_relative_eq!(m.value(), 0.0254, max_relative = 1e-16);
}
#[test]
fn nautical_mile_to_meter_exact_ratio() {
let nmi = NauticalMiles::new(1.0);
let m = nmi.to::<Meter>();
assert_abs_diff_eq!(m.value(), 1852.0, epsilon = 1e-12);
}
#[test]
fn roundtrip_inch_meter() {
let original = Inches::new(123.456);
let converted = original.to::<Meter>();
let back = converted.to::<Inch>();
assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
}
#[test]
fn roundtrip_nautical_mile_meter() {
let original = NauticalMiles::new(3.75);
let converted = original.to::<Meter>();
let back = converted.to::<NauticalMile>();
assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
}
#[test]
fn roundtrip_parsec_kpc() {
let original = Parsecs::new(12_345.0);
let converted = original.to::<Kiloparsec>();
let back = converted.to::<Parsec>();
assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
}
proptest! {
#[test]
fn prop_roundtrip_km_m(k in -1e6..1e6f64) {
let original = Kilometers::new(k);
let converted = original.to::<Meter>();
let back = converted.to::<Kilometer>();
prop_assert!((back.value() - original.value()).abs() < 1e-9 * k.abs().max(1.0));
}
#[test]
fn prop_km_m_ratio(k in 1e-6..1e6f64) {
let km = Kilometers::new(k);
let m = km.to::<Meter>();
prop_assert!((m.value() / km.value() - 1000.0).abs() < 1e-9);
}
#[test]
fn prop_roundtrip_au_km(a in 1e-6..1e6f64) {
let original = AstronomicalUnits::new(a);
let converted = original.to::<Kilometer>();
let back = converted.to::<AstronomicalUnit>();
prop_assert!((back.value() - original.value()).abs() / original.value() < 1e-12);
}
#[test]
fn prop_roundtrip_inch_m(i in -1e6..1e6f64) {
let original = Inches::new(i);
let converted = original.to::<Meter>();
let back = converted.to::<Inch>();
let scale = i.abs().max(1.0);
prop_assert!((back.value() - original.value()).abs() < 1e-9 * scale);
}
}
#[test]
fn decimeter_to_meter() {
let q = Decimeters::new(10.0);
assert_relative_eq!(q.to::<Meter>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn centimeter_to_meter() {
let q = Centimeters::new(100.0);
assert_relative_eq!(q.to::<Meter>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn millimeter_to_centimeter() {
let q = Millimeters::new(10.0);
assert_relative_eq!(q.to::<Centimeter>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn micrometer_to_millimeter() {
let q = Micrometers::new(1_000.0);
assert_relative_eq!(q.to::<Millimeter>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn nanometer_to_micrometer() {
let q = Nanometers::new(1_000.0);
assert_relative_eq!(q.to::<Micrometer>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn picometer_to_nanometer() {
let q = Picometers::new(1_000.0);
assert_relative_eq!(q.to::<Nanometer>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn femtometer_to_picometer() {
let q = Femtometers::new(1_000.0);
assert_relative_eq!(q.to::<Picometer>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn attometer_to_femtometer() {
let q = Attometers::new(1_000.0);
assert_relative_eq!(q.to::<Femtometer>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn zeptometer_to_attometer() {
let q = Zeptometers::new(1_000.0);
assert_relative_eq!(q.to::<Attometer>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn yoctometer_to_zeptometer() {
let q = Yoctometers::new(1_000.0);
assert_relative_eq!(q.to::<Zeptometer>().value(), 1.0, max_relative = 1e-15);
}
#[test]
fn decameter_to_meter() {
let q = Decameters::new(1.0);
assert_relative_eq!(q.to::<Meter>().value(), 10.0, max_relative = 1e-15);
}
#[test]
fn hectometer_to_meter() {
let q = Hectometers::new(1.0);
assert_relative_eq!(q.to::<Meter>().value(), 100.0, max_relative = 1e-15);
}
#[test]
fn megameter_to_kilometer() {
let q = Megameters::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 1_000.0, max_relative = 1e-15);
}
#[test]
fn gigameter_to_megameter() {
let q = Gigameters::new(1.0);
assert_relative_eq!(q.to::<Megameter>().value(), 1_000.0, max_relative = 1e-15);
}
#[test]
fn terameter_to_gigameter() {
let q = Terameters::new(1.0);
assert_relative_eq!(q.to::<Gigameter>().value(), 1_000.0, max_relative = 1e-15);
}
#[test]
fn petameter_to_terameter() {
let q = Petameters::new(1.0);
assert_relative_eq!(q.to::<Terameter>().value(), 1_000.0, max_relative = 1e-15);
}
#[test]
fn exameter_to_petameter() {
let q = Exameters::new(1.0);
assert_relative_eq!(q.to::<Petameter>().value(), 1_000.0, max_relative = 1e-15);
}
#[test]
fn zettameter_to_exameter() {
let q = Zettameters::new(1.0);
assert_relative_eq!(q.to::<Exameter>().value(), 1_000.0, max_relative = 1e-15);
}
#[test]
fn yottameter_to_zettameter() {
let q = Yottameters::new(1.0);
assert_relative_eq!(q.to::<Zettameter>().value(), 1_000.0, max_relative = 1e-15);
}
#[test]
fn foot_to_meter() {
let q = Feet::new(1.0);
assert_relative_eq!(q.to::<Meter>().value(), 0.3048, max_relative = 1e-15);
}
#[test]
fn yard_to_meter() {
let q = Yards::new(1.0);
assert_relative_eq!(q.to::<Meter>().value(), 0.9144, max_relative = 1e-15);
}
#[test]
fn mile_to_kilometer() {
let q = Miles::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 1.609_344, max_relative = 1e-15);
}
#[test]
fn fathom_to_foot() {
let q = Fathoms::new(1.0);
assert_relative_eq!(q.to::<Foot>().value(), 6.0, max_relative = 1e-14);
}
#[test]
fn chain_to_foot() {
let q = Chains::new(1.0);
assert_relative_eq!(q.to::<Foot>().value(), 66.0, max_relative = 1e-14);
}
#[test]
fn rod_to_foot() {
let q = Rods::new(1.0);
assert_relative_eq!(q.to::<Foot>().value(), 16.5, max_relative = 1e-14);
}
#[test]
fn link_to_foot() {
let q = Links::new(100.0);
assert_relative_eq!(q.to::<Foot>().value(), 66.0, max_relative = 1e-14);
}
#[test]
fn megaparsec_to_kiloparsec() {
let q = Megaparsecs::new(1.0);
assert_relative_eq!(q.to::<Kiloparsec>().value(), 1_000.0, max_relative = 1e-12);
}
#[test]
fn gigaparsec_to_megaparsec() {
let q = Gigaparsecs::new(1.0);
assert_relative_eq!(q.to::<Megaparsec>().value(), 1_000.0, max_relative = 1e-12);
}
#[test]
fn earth_meridional_circumference_to_km() {
let q = EarthMeridionalCircumferences::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 40_007.863, max_relative = 1e-6);
}
#[test]
fn earth_equatorial_circumference_to_km() {
let q = EarthEquatorialCircumferences::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 40_075.017, max_relative = 1e-6);
}
#[test]
fn bohr_radius_to_picometers() {
let q = BohrRadii::new(1.0);
assert_relative_eq!(q.to::<Picometer>().value(), 52.917_72, max_relative = 1e-5);
}
#[test]
fn classical_electron_radius_to_femtometers() {
let q = ClassicalElectronRadii::new(1.0);
assert_relative_eq!(
q.to::<Femtometer>().value(),
2.817_940_326_2,
max_relative = 1e-9
);
}
#[test]
fn planck_length_ratio() {
let q = PlanckLengths::new(1.0);
let back = q.to::<Meter>().to::<PlanckLength>();
assert_relative_eq!(back.value(), 1.0, max_relative = 1e-9);
}
#[test]
fn electron_compton_wavelength_to_femtometers() {
let q = ElectronReducedComptonWavelengths::new(1.0);
assert_relative_eq!(
q.to::<Femtometer>().value(),
386.159_267_96,
max_relative = 1e-7
);
}
#[test]
fn earth_radius_to_km() {
let q = nominal::EarthRadii::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 6_371.0, max_relative = 1e-9);
}
#[test]
fn earth_equatorial_radius_to_km() {
let q = nominal::EarthEquatorialRadii::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 6_378.137, max_relative = 1e-9);
}
#[test]
fn earth_polar_radius_to_km() {
let q = nominal::EarthPolarRadii::new(1.0);
assert_relative_eq!(
q.to::<Kilometer>().value(),
6_356.752_314_2,
max_relative = 1e-9
);
}
#[test]
fn lunar_radius_to_km() {
let q = nominal::LunarRadii::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 1_737.4, max_relative = 1e-9);
}
#[test]
fn jupiter_radius_to_km() {
let q = nominal::JupiterRadii::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 71_492.0, max_relative = 1e-9);
}
#[test]
fn lunar_distance_to_km() {
let q = nominal::LunarDistances::new(1.0);
assert_relative_eq!(q.to::<Kilometer>().value(), 384_400.0, max_relative = 1e-9);
}
#[test]
fn solar_diameter_to_solar_radius() {
let diameters = nominal::SolarDiameters::new(1.0);
let radii = diameters.to::<nominal::SolarRadius>();
assert_relative_eq!(radii.value(), 2.0, max_relative = 1e-14);
}
#[test]
fn symbols_are_correct() {
assert_eq!(Meter::SYMBOL, "m");
assert_eq!(Kilometer::SYMBOL, "km");
assert_eq!(Centimeter::SYMBOL, "cm");
assert_eq!(Inch::SYMBOL, "in");
assert_eq!(AstronomicalUnit::SYMBOL, "au");
assert_eq!(Parsec::SYMBOL, "pc");
}
}