1use crate::{Quantity, Unit};
38use core::f64::consts::PI;
39use qtty_derive::Unit;
40
41pub use crate::dimension::Length;
43
44pub trait LengthUnit: Unit<Dim = Length> {}
46impl<T: Unit<Dim = Length>> LengthUnit for T {}
47
48#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
54#[unit(symbol = "m", dimension = Length, ratio = 1.0)]
55pub struct Meter;
56pub type Meters = Quantity<Meter>;
58pub const M: Meters = Meters::new(1.0);
60
61#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
63#[unit(symbol = "km", dimension = Length, ratio = 1_000.0)]
64pub struct Kilometer;
65pub type Km = Kilometer;
67pub type Kilometers = Quantity<Km>;
69pub const KM: Kilometers = Kilometers::new(1.0);
71
72#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
74#[unit(symbol = "cm", dimension = Length, ratio = 1e-2)]
75pub struct Centimeter;
76pub type Cm = Centimeter;
78pub type Centimeters = Quantity<Cm>;
80pub const CM: Centimeters = Centimeters::new(1.0);
82
83#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
85#[unit(symbol = "mm", dimension = Length, ratio = 1e-3)]
86pub struct Millimeter;
87pub type Mm = Millimeter;
89pub type Millimeters = Quantity<Mm>;
91pub const MM: Millimeters = Millimeters::new(1.0);
93
94#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
96#[unit(symbol = "μm", dimension = Length, ratio = 1e-6)]
97pub struct Micrometer;
98pub type Um = Micrometer;
100pub type Micrometers = Quantity<Um>;
102pub const UM: Micrometers = Micrometers::new(1.0);
104
105#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
107#[unit(symbol = "nm", dimension = Length, ratio = 1e-9)]
108pub struct Nanometer;
109pub type Nm = Nanometer;
111pub type Nanometers = Quantity<Nm>;
113pub const NM: Nanometers = Nanometers::new(1.0);
115
116#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
118#[unit(symbol = "pm", dimension = Length, ratio = 1e-12)]
119pub struct Picometer;
120pub type Picometers = Quantity<Picometer>;
122pub const PMETER: Picometers = Picometers::new(1.0);
124
125#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
127#[unit(symbol = "fm", dimension = Length, ratio = 1e-15)]
128pub struct Femtometer;
129pub type Femtometers = Quantity<Femtometer>;
131pub const FM: Femtometers = Femtometers::new(1.0);
133
134#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
136#[unit(symbol = "am", dimension = Length, ratio = 1e-18)]
137pub struct Attometer;
138pub type Attometers = Quantity<Attometer>;
140pub const AM: Attometers = Attometers::new(1.0);
142
143#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
145#[unit(symbol = "zm", dimension = Length, ratio = 1e-21)]
146pub struct Zeptometer;
147pub type Zeptometers = Quantity<Zeptometer>;
149pub const ZMETER: Zeptometers = Zeptometers::new(1.0);
151
152#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
154#[unit(symbol = "ym", dimension = Length, ratio = 1e-24)]
155pub struct Yoctometer;
156pub type Yoctometers = Quantity<Yoctometer>;
158pub const YMETER: Yoctometers = Yoctometers::new(1.0);
160
161#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
163#[unit(symbol = "Mm", dimension = Length, ratio = 1e6)]
164pub struct Megameter;
165pub type MegaMeter = Megameter;
167pub type Megameters = Quantity<Megameter>;
169pub const MEGAMETER: Megameters = Megameters::new(1.0);
171
172#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
174#[unit(symbol = "dm", dimension = Length, ratio = 1e-1)]
175pub struct Decimeter;
176pub type Decimeters = Quantity<Decimeter>;
178pub const DM: Decimeters = Decimeters::new(1.0);
180
181#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
183#[unit(symbol = "dam", dimension = Length, ratio = 1e1)]
184pub struct Decameter;
185pub type Decameters = Quantity<Decameter>;
187pub const DAM: Decameters = Decameters::new(1.0);
189
190#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
192#[unit(symbol = "hm", dimension = Length, ratio = 1e2)]
193pub struct Hectometer;
194pub type Hectometers = Quantity<Hectometer>;
196pub const HM: Hectometers = Hectometers::new(1.0);
198
199#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
201#[unit(symbol = "Gm", dimension = Length, ratio = 1e9)]
202pub struct Gigameter;
203pub type Gigameters = Quantity<Gigameter>;
205pub const GM: Gigameters = Gigameters::new(1.0);
207
208#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
210#[unit(symbol = "Tm", dimension = Length, ratio = 1e12)]
211pub struct Terameter;
212pub type Terameters = Quantity<Terameter>;
214pub const TM: Terameters = Terameters::new(1.0);
216
217#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
219#[unit(symbol = "Pm", dimension = Length, ratio = 1e15)]
220pub struct Petameter;
221pub type Petameters = Quantity<Petameter>;
223pub const PM: Petameters = Petameters::new(1.0);
225
226#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
228#[unit(symbol = "Em", dimension = Length, ratio = 1e18)]
229pub struct Exameter;
230pub type Exameters = Quantity<Exameter>;
232pub const EM: Exameters = Exameters::new(1.0);
234
235#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
237#[unit(symbol = "Zm", dimension = Length, ratio = 1e21)]
238pub struct Zettameter;
239pub type Zettameters = Quantity<Zettameter>;
241pub const ZM: Zettameters = Zettameters::new(1.0);
243
244#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
246#[unit(symbol = "Ym", dimension = Length, ratio = 1e24)]
247pub struct Yottameter;
248pub type Yottameters = Quantity<Yottameter>;
250pub const YM: Yottameters = Yottameters::new(1.0);
252
253#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
259#[unit(symbol = "au", dimension = Length, ratio = 149_597_870_700.0)]
260pub struct AstronomicalUnit;
261pub type Au = AstronomicalUnit;
263pub type AstronomicalUnits = Quantity<Au>;
265pub const AU: AstronomicalUnits = AstronomicalUnits::new(1.0);
267
268const SPEED_OF_LIGHT_M_PER_S: f64 = 299_792_458.0;
270const SECONDS_PER_DAY: f64 = 86_400.0;
271const DAYS_PER_JULIAN_YEAR: f64 = 36525.0 / 100.0; const SECONDS_PER_JULIAN_YEAR: f64 = SECONDS_PER_DAY * DAYS_PER_JULIAN_YEAR;
273const METERS_PER_LIGHT_YEAR: f64 = SPEED_OF_LIGHT_M_PER_S * SECONDS_PER_JULIAN_YEAR;
274
275#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
277#[unit(symbol = "ly", dimension = Length, ratio = METERS_PER_LIGHT_YEAR)]
278pub struct LightYear;
279pub type Ly = LightYear;
281pub type LightYears = Quantity<Ly>;
283pub const LY: LightYears = LightYears::new(1.0);
285
286#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
288#[unit(symbol = "pc", dimension = Length, ratio = 149_597_870_700.0 * (648_000.0 / PI))]
289pub struct Parsec;
290pub type Pc = Parsec;
292pub type Parsecs = Quantity<Pc>;
294pub const PC: Parsecs = Parsecs::new(1.0);
296
297#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
299#[unit(symbol = "kpc", dimension = Length, ratio = 1_000.0 * 149_597_870_700.0 * (648_000.0 / PI))]
300pub struct Kiloparsec;
301pub type Kiloparsecs = Quantity<Kiloparsec>;
303pub const KPC: Kiloparsecs = Kiloparsecs::new(1.0);
305
306#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
308#[unit(symbol = "Mpc", dimension = Length, ratio = 1_000_000.0 * 149_597_870_700.0 * (648_000.0 / PI))]
309pub struct Megaparsec;
310pub type Megaparsecs = Quantity<Megaparsec>;
312pub const MPC: Megaparsecs = Megaparsecs::new(1.0);
314
315#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
317#[unit(symbol = "Gpc", dimension = Length, ratio = 1_000_000_000.0 * 149_597_870_700.0 * (648_000.0 / PI))]
318pub struct Gigaparsec;
319pub type Gigaparsecs = Quantity<Gigaparsec>;
321pub const GPC: Gigaparsecs = Gigaparsecs::new(1.0);
323
324#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
330#[unit(symbol = "in", dimension = Length, ratio = 254.0 / 10_000.0)]
331pub struct Inch;
332pub type Inches = Quantity<Inch>;
334pub const INCH: Inches = Inches::new(1.0);
336
337#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
339#[unit(symbol = "ft", dimension = Length, ratio = 3048.0 / 10_000.0)]
340pub struct Foot;
341pub type Feet = Quantity<Foot>;
343pub const FT: Feet = Feet::new(1.0);
345
346#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
348#[unit(symbol = "yd", dimension = Length, ratio = 9144.0 / 10_000.0)]
349pub struct Yard;
350pub type Yards = Quantity<Yard>;
352pub const YD: Yards = Yards::new(1.0);
354
355#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
357#[unit(symbol = "mi", dimension = Length, ratio = 1_609_344.0 / 1_000.0)]
358pub struct Mile;
359pub type Miles = Quantity<Mile>;
361pub const MI: Miles = Miles::new(1.0);
363
364#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
366#[unit(symbol = "nmi", dimension = Length, ratio = 1_852.0)]
367pub struct NauticalMile;
368pub type NauticalMiles = Quantity<NauticalMile>;
370pub const NMI: NauticalMiles = NauticalMiles::new(1.0);
372
373#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
375#[unit(symbol = "ch", dimension = Length, ratio = 66.0 * (3048.0 / 10_000.0))]
376pub struct Chain;
377pub type Chains = Quantity<Chain>;
379pub const CHAIN: Chains = Chains::new(1.0);
381
382#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
384#[unit(symbol = "rd", dimension = Length, ratio = 16.5 * (3048.0 / 10_000.0))]
385pub struct Rod;
386pub type Rods = Quantity<Rod>;
388pub const ROD: Rods = Rods::new(1.0);
390
391#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
393#[unit(symbol = "lk", dimension = Length, ratio = (66.0 / 100.0) * (3048.0 / 10_000.0))]
394pub struct Link;
395pub type Links = Quantity<Link>;
397pub const LINK: Links = Links::new(1.0);
399
400#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
402#[unit(symbol = "ftm", dimension = Length, ratio = 6.0 * (3048.0 / 10_000.0))]
403pub struct Fathom;
404pub type Fathoms = Quantity<Fathom>;
406pub const FTM: Fathoms = Fathoms::new(1.0);
408
409#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
415#[unit(symbol = "Cmer", dimension = Length, ratio = 40_007_863.0)]
416pub struct EarthMeridionalCircumference;
417pub type EarthMeridionalCircumferences = Quantity<EarthMeridionalCircumference>;
419pub const C_MERIDIONAL: EarthMeridionalCircumferences = EarthMeridionalCircumferences::new(1.0);
421
422#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
424#[unit(symbol = "Ceq", dimension = Length, ratio = 40_075_017.0)]
425pub struct EarthEquatorialCircumference;
426pub type EarthEquatorialCircumferences = Quantity<EarthEquatorialCircumference>;
428pub const C_EQUATORIAL: EarthEquatorialCircumferences = EarthEquatorialCircumferences::new(1.0);
430
431#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
437#[unit(symbol = "a0", dimension = Length, ratio = 5.291_772_109_03e-11)]
438pub struct BohrRadius;
439pub type BohrRadii = Quantity<BohrRadius>;
441pub const A0: BohrRadii = BohrRadii::new(1.0);
443
444#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
446#[unit(symbol = "re", dimension = Length, ratio = 2.817_940_326_2e-15)]
447pub struct ClassicalElectronRadius;
448pub type ClassicalElectronRadii = Quantity<ClassicalElectronRadius>;
450pub const RE: ClassicalElectronRadii = ClassicalElectronRadii::new(1.0);
452
453#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
455#[unit(symbol = "lp", dimension = Length, ratio = 1.616_255e-35)]
456pub struct PlanckLength;
457pub type PlanckLengths = Quantity<PlanckLength>;
459pub const LP: PlanckLengths = PlanckLengths::new(1.0);
461
462#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
464#[unit(symbol = "lambda_bar_e", dimension = Length, ratio = 3.861_592_679_6e-13)]
465pub struct ElectronReducedComptonWavelength;
466pub type ElectronReducedComptonWavelengths = Quantity<ElectronReducedComptonWavelength>;
468pub const LAMBDA_BAR_E: ElectronReducedComptonWavelengths =
470 ElectronReducedComptonWavelengths::new(1.0);
471
472pub mod nominal {
481 use super::*;
482
483 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
485 #[unit(symbol = "Rsun", dimension = Length, ratio = 695_700_000.0)]
486 pub struct SolarRadius;
487 pub type SolarRadiuses = Quantity<SolarRadius>;
489 pub const RSUN: SolarRadiuses = SolarRadiuses::new(1.0);
491
492 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
494 #[unit(symbol = "Rearth", dimension = Length, ratio = 6_371_000.0)]
495 pub struct EarthRadius;
496 pub type EarthRadii = Quantity<EarthRadius>;
498 pub const R_EARTH: EarthRadii = EarthRadii::new(1.0);
500
501 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
503 #[unit(symbol = "Rearth_eq", dimension = Length, ratio = 6_378_137.0)]
504 pub struct EarthEquatorialRadius;
505 pub type EarthEquatorialRadii = Quantity<EarthEquatorialRadius>;
507 pub const R_EARTH_EQ: EarthEquatorialRadii = EarthEquatorialRadii::new(1.0);
509
510 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
512 #[unit(symbol = "Rearth_p", dimension = Length, ratio = 6_356_752.314_2)]
513 pub struct EarthPolarRadius;
514 pub type EarthPolarRadii = Quantity<EarthPolarRadius>;
516 pub const R_EARTH_P: EarthPolarRadii = EarthPolarRadii::new(1.0);
518
519 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
521 #[unit(symbol = "Rmoon", dimension = Length, ratio = 1_737_400.0)]
522 pub struct LunarRadius;
523 pub type LunarRadii = Quantity<LunarRadius>;
525 pub const R_MOON: LunarRadii = LunarRadii::new(1.0);
527
528 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
530 #[unit(symbol = "Rjup", dimension = Length, ratio = 71_492_000.0)]
531 pub struct JupiterRadius;
532 pub type JupiterRadii = Quantity<JupiterRadius>;
534 pub const R_JUPITER: JupiterRadii = JupiterRadii::new(1.0);
536
537 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
539 #[unit(symbol = "LD", dimension = Length, ratio = 384_400_000.0)]
540 pub struct LunarDistance;
541 pub type LunarDistances = Quantity<LunarDistance>;
543 pub const LD: LunarDistances = LunarDistances::new(1.0);
545
546 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
548 #[unit(symbol = "Dsun", dimension = Length, ratio = 2.0 * 695_700_000.0)]
549 pub struct SolarDiameter;
550 pub type SolarDiameters = Quantity<SolarDiameter>;
552 pub const D_SUN: SolarDiameters = SolarDiameters::new(1.0);
554
555 crate::impl_unit_from_conversions!(SolarRadius, Kilometer);
559 #[cfg(feature = "cross-unit-ops")]
560 crate::impl_unit_cross_unit_ops!(SolarRadius, Kilometer);
561}
562
563crate::impl_unit_from_conversions!(
569 Meter,
570 Decimeter,
571 Centimeter,
572 Millimeter,
573 Micrometer,
574 Nanometer,
575 Picometer,
576 Femtometer,
577 Attometer,
578 Zeptometer,
579 Yoctometer,
580 Decameter,
581 Hectometer,
582 Kilometer,
583 Megameter,
584 Gigameter,
585 Terameter,
586 Petameter,
587 Exameter,
588 Zettameter,
589 Yottameter,
590 AstronomicalUnit,
591 LightYear,
592 Parsec,
593 Kiloparsec,
594 Megaparsec,
595 Gigaparsec,
596 Inch,
597 Foot,
598 Yard,
599 Mile,
600 NauticalMile,
601 Chain,
602 Rod,
603 Link,
604 Fathom,
605 EarthMeridionalCircumference,
606 EarthEquatorialCircumference,
607 BohrRadius,
608 ClassicalElectronRadius,
609 PlanckLength,
610 ElectronReducedComptonWavelength
611);
612
613#[cfg(feature = "cross-unit-ops")]
615crate::impl_unit_cross_unit_ops!(
616 Meter,
617 Decimeter,
618 Centimeter,
619 Millimeter,
620 Micrometer,
621 Nanometer,
622 Picometer,
623 Femtometer,
624 Attometer,
625 Zeptometer,
626 Yoctometer,
627 Decameter,
628 Hectometer,
629 Kilometer,
630 Megameter,
631 Gigameter,
632 Terameter,
633 Petameter,
634 Exameter,
635 Zettameter,
636 Yottameter,
637 AstronomicalUnit,
638 LightYear,
639 Parsec,
640 Kiloparsec,
641 Megaparsec,
642 Gigaparsec,
643 Inch,
644 Foot,
645 Yard,
646 Mile,
647 NauticalMile,
648 Chain,
649 Rod,
650 Link,
651 Fathom,
652 EarthMeridionalCircumference,
653 EarthEquatorialCircumference,
654 BohrRadius,
655 ClassicalElectronRadius,
656 PlanckLength,
657 ElectronReducedComptonWavelength
658);
659
660#[cfg(test)]
661mod tests {
662 use super::nominal::SolarRadiuses;
663 use super::*;
664 use approx::{assert_abs_diff_eq, assert_relative_eq};
665 use proptest::prelude::*;
666
667 #[test]
672 fn kilometer_to_meter() {
673 let km = Kilometers::new(1.0);
674 let m = km.to::<Meter>();
675 assert_abs_diff_eq!(m.value(), 1000.0, epsilon = 1e-9);
676 }
677
678 #[test]
679 fn meter_to_kilometer() {
680 let m = Meters::new(1000.0);
681 let km = m.to::<Kilometer>();
682 assert_abs_diff_eq!(km.value(), 1.0, epsilon = 1e-12);
683 }
684
685 #[test]
686 fn au_to_meters() {
687 let au = AstronomicalUnits::new(1.0);
688 let m = au.to::<Meter>();
689 assert_abs_diff_eq!(m.value(), 149_597_870_700.0, epsilon = 1e-6);
691 }
692
693 #[test]
694 fn au_to_kilometers() {
695 let au = AstronomicalUnits::new(1.0);
696 let km = au.to::<Kilometer>();
697 assert_relative_eq!(km.value(), 149_597_870.7, max_relative = 1e-12);
699 }
700
701 #[test]
702 fn light_year_to_meters() {
703 let ly = LightYears::new(1.0);
704 let m = ly.to::<Meter>();
705 assert_relative_eq!(m.value(), METERS_PER_LIGHT_YEAR, max_relative = 1e-12);
707 }
708
709 #[test]
710 fn light_year_to_kilometers() {
711 let ly = LightYears::new(1.0);
712 let km = ly.to::<Kilometer>();
713 assert_relative_eq!(km.value(), 9_460_730_472_580.000_8, max_relative = 1e-9);
715 }
716
717 #[test]
722 fn au_to_light_year() {
723 let au = AstronomicalUnits::new(1.0);
724 let ly = au.to::<LightYear>();
725 assert_relative_eq!(ly.value(), 1.582e-5, max_relative = 1e-3);
727 }
728
729 #[test]
730 fn light_year_to_au() {
731 let ly = LightYears::new(1.0);
732 let au = ly.to::<AstronomicalUnit>();
733 assert_relative_eq!(au.value(), 63241.0, max_relative = 1e-3);
735 }
736
737 #[test]
738 fn from_impl_au_to_ly() {
739 let au = 1.0 * AU;
740 let ly: LightYears = au.into();
741 assert_relative_eq!(ly.value(), 1.582e-5, max_relative = 1e-3);
742 }
743
744 #[test]
745 fn from_impl_ly_to_au() {
746 let ly = 1.0 * LY;
747 let au: AstronomicalUnits = ly.into();
748 assert_relative_eq!(au.value(), 63241.0, max_relative = 1e-3);
749 }
750
751 #[test]
756 fn parsec_to_light_year() {
757 let pc = Parsecs::new(1.0);
758 let ly = pc.to::<LightYear>();
759 let expected = (AstronomicalUnit::RATIO * (648_000.0 / PI)) / LightYear::RATIO;
761 assert_relative_eq!(ly.value(), expected, max_relative = 1e-15);
762 }
763
764 #[test]
765 fn parsec_to_au() {
766 let pc = Parsecs::new(1.0);
767 let au = pc.to::<AstronomicalUnit>();
768 assert_relative_eq!(au.value(), 3.26 * 63241.0, max_relative = 1e-2);
771 }
772
773 #[test]
774 fn parsec_ratio_sanity() {
775 let lhs = Parsec::RATIO / AstronomicalUnit::RATIO;
777 let rhs = 648_000.0 / PI;
778 assert_relative_eq!(lhs, rhs, max_relative = 1e-12);
779 }
780
781 #[test]
786 fn solar_radius_to_meters() {
787 let sr = SolarRadiuses::new(1.0);
788 let m = sr.to::<Meter>();
789 assert_abs_diff_eq!(m.value(), 695_700_000.0, epsilon = 1e-3);
791 }
792
793 #[test]
794 fn solar_radius_to_km() {
795 let sr = SolarRadiuses::new(1.0);
796 let km = sr.to::<Kilometer>();
797 assert_abs_diff_eq!(km.value(), 695_700.0, epsilon = 1e-6);
799 }
800
801 #[test]
806 fn roundtrip_km_m() {
807 let original = Kilometers::new(42.5);
808 let converted = original.to::<Meter>();
809 let back = converted.to::<Kilometer>();
810 assert_abs_diff_eq!(back.value(), original.value(), epsilon = 1e-12);
811 }
812
813 #[test]
814 fn roundtrip_au_ly() {
815 let original = AstronomicalUnits::new(10000.0);
816 let converted = original.to::<LightYear>();
817 let back = converted.to::<AstronomicalUnit>();
818 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
819 }
820
821 #[test]
822 fn roundtrip_parsec_ly() {
823 let original = Parsecs::new(5.0);
824 let converted = original.to::<LightYear>();
825 let back = converted.to::<Parsec>();
826 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
827 }
828
829 #[test]
834 fn inch_to_meter_exact_ratio() {
835 let inch = Inches::new(1.0);
836 let m = inch.to::<Meter>();
837 assert_relative_eq!(m.value(), 0.0254, max_relative = 1e-16);
839 }
840
841 #[test]
842 fn nautical_mile_to_meter_exact_ratio() {
843 let nmi = NauticalMiles::new(1.0);
844 let m = nmi.to::<Meter>();
845 assert_abs_diff_eq!(m.value(), 1852.0, epsilon = 1e-12);
847 }
848
849 #[test]
854 fn roundtrip_inch_meter() {
855 let original = Inches::new(123.456);
856 let converted = original.to::<Meter>();
857 let back = converted.to::<Inch>();
858 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
859 }
860
861 #[test]
862 fn roundtrip_nautical_mile_meter() {
863 let original = NauticalMiles::new(3.75);
864 let converted = original.to::<Meter>();
865 let back = converted.to::<NauticalMile>();
866 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
867 }
868
869 #[test]
870 fn roundtrip_parsec_kpc() {
871 let original = Parsecs::new(12_345.0);
872 let converted = original.to::<Kiloparsec>();
873 let back = converted.to::<Parsec>();
874 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
875 }
876
877 proptest! {
882 #[test]
883 fn prop_roundtrip_km_m(k in -1e6..1e6f64) {
884 let original = Kilometers::new(k);
885 let converted = original.to::<Meter>();
886 let back = converted.to::<Kilometer>();
887 prop_assert!((back.value() - original.value()).abs() < 1e-9 * k.abs().max(1.0));
888 }
889
890 #[test]
891 fn prop_km_m_ratio(k in 1e-6..1e6f64) {
892 let km = Kilometers::new(k);
893 let m = km.to::<Meter>();
894 prop_assert!((m.value() / km.value() - 1000.0).abs() < 1e-9);
896 }
897
898 #[test]
899 fn prop_roundtrip_au_km(a in 1e-6..1e6f64) {
900 let original = AstronomicalUnits::new(a);
901 let converted = original.to::<Kilometer>();
902 let back = converted.to::<AstronomicalUnit>();
903 prop_assert!((back.value() - original.value()).abs() / original.value() < 1e-12);
904 }
905
906 #[test]
907 fn prop_roundtrip_inch_m(i in -1e6..1e6f64) {
908 let original = Inches::new(i);
909 let converted = original.to::<Meter>();
910 let back = converted.to::<Inch>();
911 let scale = i.abs().max(1.0);
912 prop_assert!((back.value() - original.value()).abs() < 1e-9 * scale);
913 }
914 }
915}