1use crate::{Quantity, Unit};
70use qtty_derive::Unit;
71
72pub use crate::dimension::Length;
74
75pub trait LengthUnit: Unit<Dim = Length> {}
77impl<T: Unit<Dim = Length>> LengthUnit for T {}
78
79#[cfg(feature = "astro")]
80mod astro;
81#[cfg(feature = "astro")]
82pub use astro::*;
83#[cfg(feature = "customary")]
84mod customary;
85#[cfg(feature = "customary")]
86pub use customary::*;
87#[cfg(feature = "navigation")]
88mod navigation;
89#[cfg(feature = "navigation")]
90pub use navigation::*;
91#[cfg(feature = "fundamental-physics")]
92mod fundamental_physics;
93#[cfg(feature = "fundamental-physics")]
94pub use fundamental_physics::*;
95
96#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
102#[unit(symbol = "m", dimension = Length, ratio = 1.0)]
103pub struct Meter;
104pub type Meters = Quantity<Meter>;
106pub const M: Meters = Meters::new(1.0);
108
109#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
111#[unit(symbol = "km", dimension = Length, ratio = 1_000.0)]
112pub struct Kilometer;
113pub type Km = Kilometer;
115pub type Kilometers = Quantity<Km>;
117pub const KM: Kilometers = Kilometers::new(1.0);
119
120#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
122#[unit(symbol = "cm", dimension = Length, ratio = 1e-2)]
123pub struct Centimeter;
124pub type Cm = Centimeter;
126pub type Centimeters = Quantity<Cm>;
128pub const CM: Centimeters = Centimeters::new(1.0);
130
131#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
133#[unit(symbol = "mm", dimension = Length, ratio = 1e-3)]
134pub struct Millimeter;
135pub type Mm = Millimeter;
137pub type Millimeters = Quantity<Mm>;
139pub const MM: Millimeters = Millimeters::new(1.0);
141
142#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
144#[unit(symbol = "μm", dimension = Length, ratio = 1e-6)]
145pub struct Micrometer;
146pub type Um = Micrometer;
148pub type Micrometers = Quantity<Um>;
150pub const UM: Micrometers = Micrometers::new(1.0);
152
153#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
155#[unit(symbol = "nm", dimension = Length, ratio = 1e-9)]
156pub struct Nanometer;
157pub type Nm = Nanometer;
159pub type Nanometers = Quantity<Nm>;
161pub const NM: Nanometers = Nanometers::new(1.0);
163
164#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
166#[unit(symbol = "pm", dimension = Length, ratio = 1e-12)]
167pub struct Picometer;
168pub type Picometers = Quantity<Picometer>;
170pub const PMETER: Picometers = Picometers::new(1.0);
172
173#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
175#[unit(symbol = "fm", dimension = Length, ratio = 1e-15)]
176pub struct Femtometer;
177pub type Femtometers = Quantity<Femtometer>;
179pub const FM: Femtometers = Femtometers::new(1.0);
181
182#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
184#[unit(symbol = "am", dimension = Length, ratio = 1e-18)]
185pub struct Attometer;
186pub type Attometers = Quantity<Attometer>;
188pub const AM: Attometers = Attometers::new(1.0);
190
191#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
193#[unit(symbol = "zm", dimension = Length, ratio = 1e-21)]
194pub struct Zeptometer;
195pub type Zeptometers = Quantity<Zeptometer>;
197pub const ZMETER: Zeptometers = Zeptometers::new(1.0);
199
200#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
202#[unit(symbol = "ym", dimension = Length, ratio = 1e-24)]
203pub struct Yoctometer;
204pub type Yoctometers = Quantity<Yoctometer>;
206pub const YMETER: Yoctometers = Yoctometers::new(1.0);
208
209#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
211#[unit(symbol = "Mm", dimension = Length, ratio = 1e6)]
212pub struct Megameter;
213pub type MegaMeter = Megameter;
215pub type Megameters = Quantity<Megameter>;
217pub const MEGAMETER: Megameters = Megameters::new(1.0);
219
220#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
222#[unit(symbol = "dm", dimension = Length, ratio = 1e-1)]
223pub struct Decimeter;
224pub type Decimeters = Quantity<Decimeter>;
226pub const DM: Decimeters = Decimeters::new(1.0);
228
229#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
231#[unit(symbol = "dam", dimension = Length, ratio = 1e1)]
232pub struct Decameter;
233pub type Decameters = Quantity<Decameter>;
235pub const DAM: Decameters = Decameters::new(1.0);
237
238#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
240#[unit(symbol = "hm", dimension = Length, ratio = 1e2)]
241pub struct Hectometer;
242pub type Hectometers = Quantity<Hectometer>;
244pub const HM: Hectometers = Hectometers::new(1.0);
246
247#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
249#[unit(symbol = "Gm", dimension = Length, ratio = 1e9)]
250pub struct Gigameter;
251pub type Gigameters = Quantity<Gigameter>;
253pub const GM: Gigameters = Gigameters::new(1.0);
255
256#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
258#[unit(symbol = "Tm", dimension = Length, ratio = 1e12)]
259pub struct Terameter;
260pub type Terameters = Quantity<Terameter>;
262pub const TM: Terameters = Terameters::new(1.0);
264
265#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
267#[unit(symbol = "Pm", dimension = Length, ratio = 1e15)]
268pub struct Petameter;
269pub type Petameters = Quantity<Petameter>;
271pub const PM: Petameters = Petameters::new(1.0);
273
274#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
276#[unit(symbol = "Em", dimension = Length, ratio = 1e18)]
277pub struct Exameter;
278pub type Exameters = Quantity<Exameter>;
280pub const EM: Exameters = Exameters::new(1.0);
282
283#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
285#[unit(symbol = "Zm", dimension = Length, ratio = 1e21)]
286pub struct Zettameter;
287pub type Zettameters = Quantity<Zettameter>;
289pub const ZM: Zettameters = Zettameters::new(1.0);
291
292#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
294#[unit(symbol = "Ym", dimension = Length, ratio = 1e24)]
295pub struct Yottameter;
296pub type Yottameters = Quantity<Yottameter>;
298pub const YM: Yottameters = Yottameters::new(1.0);
300
301#[macro_export]
314#[doc(hidden)]
315macro_rules! length_units {
316 ($cb:path) => {
317 $cb!(
318 Meter, Decimeter, Centimeter, Millimeter, Micrometer, Nanometer, Picometer, Femtometer,
319 Attometer, Zeptometer, Yoctometer, Decameter, Hectometer, Kilometer, Megameter,
320 Gigameter, Terameter, Petameter, Exameter, Zettameter, Yottameter
321 );
322 };
323}
324
325length_units!(crate::impl_unit_from_conversions);
327
328#[cfg(feature = "cross-unit-ops")]
332length_units!(crate::impl_unit_cross_unit_ops);
333
334#[cfg(feature = "astro")]
348macro_rules! __impl_length_bridges_with_astro_as_base {
349 ($($extra:ty),+ $(,)?) => {
350 crate::__impl_from_each_extra_to_bases!(
351 {
352 AstronomicalUnit, LightYear, Parsec, Kiloparsec, Megaparsec, Gigaparsec,
353 nominal::SolarRadius, nominal::SolarDiameter, nominal::EarthRadius,
354 nominal::EarthEquatorialRadius, nominal::EarthPolarRadius,
355 nominal::JupiterRadius, nominal::LunarRadius, nominal::LunarDistance
356 }
357 $($extra),+
358 );
359 #[cfg(feature = "cross-unit-ops")]
360 crate::__impl_cross_ops_each_extra_to_bases!(
361 {
362 AstronomicalUnit, LightYear, Parsec, Kiloparsec, Megaparsec, Gigaparsec,
363 nominal::SolarRadius, nominal::SolarDiameter, nominal::EarthRadius,
364 nominal::EarthEquatorialRadius, nominal::EarthPolarRadius,
365 nominal::JupiterRadius, nominal::LunarRadius, nominal::LunarDistance
366 }
367 $($extra),+
368 );
369 };
370}
371
372#[cfg(feature = "navigation")]
373macro_rules! __impl_length_bridges_with_navigation_as_base {
374 ($($extra:ty),+ $(,)?) => {
375 crate::__impl_from_each_extra_to_bases!(
376 {NauticalMile, Chain, Rod, Link, Fathom, EarthMeridionalCircumference, EarthEquatorialCircumference}
377 $($extra),+
378 );
379 #[cfg(feature = "cross-unit-ops")]
380 crate::__impl_cross_ops_each_extra_to_bases!(
381 {NauticalMile, Chain, Rod, Link, Fathom, EarthMeridionalCircumference, EarthEquatorialCircumference}
382 $($extra),+
383 );
384 };
385}
386
387#[cfg(all(feature = "astro", feature = "customary"))]
398__impl_length_bridges_with_astro_as_base!(Inch, Foot, Yard, Mile);
399
400#[cfg(all(feature = "astro", feature = "navigation"))]
401__impl_length_bridges_with_astro_as_base!(
402 NauticalMile,
403 Chain,
404 Rod,
405 Link,
406 Fathom,
407 EarthMeridionalCircumference,
408 EarthEquatorialCircumference
409);
410
411#[cfg(all(feature = "astro", feature = "fundamental-physics"))]
412__impl_length_bridges_with_astro_as_base!(
413 BohrRadius,
414 ClassicalElectronRadius,
415 PlanckLength,
416 ElectronReducedComptonWavelength
417);
418
419#[cfg(all(feature = "customary", feature = "navigation"))]
421__impl_length_bridges_with_navigation_as_base!(Inch, Foot, Yard, Mile);
422
423#[cfg(all(feature = "navigation", feature = "fundamental-physics"))]
424__impl_length_bridges_with_navigation_as_base!(
425 BohrRadius,
426 ClassicalElectronRadius,
427 PlanckLength,
428 ElectronReducedComptonWavelength
429);
430
431#[cfg(all(feature = "customary", feature = "fundamental-physics"))]
433crate::__impl_from_each_extra_to_bases!(
434 {Inch, Foot, Yard, Mile}
435 BohrRadius, ClassicalElectronRadius, PlanckLength, ElectronReducedComptonWavelength
436);
437#[cfg(all(
438 feature = "customary",
439 feature = "fundamental-physics",
440 feature = "cross-unit-ops"
441))]
442crate::__impl_cross_ops_each_extra_to_bases!(
443 {Inch, Foot, Yard, Mile}
444 BohrRadius, ClassicalElectronRadius, PlanckLength, ElectronReducedComptonWavelength
445);
446
447#[cfg(test)]
449length_units!(crate::assert_units_are_builtin);
450
451#[cfg(all(test, feature = "std"))]
452mod tests {
453 use super::*;
454 #[cfg(feature = "astro")]
455 use crate::units::length::astro::{ARCSECONDS_PER_RADIAN, AU_IN_METERS};
456 use approx::{assert_abs_diff_eq, assert_relative_eq};
457 use proptest::prelude::*;
458
459 #[test]
464 fn kilometer_to_meter() {
465 let km = Kilometers::new(1.0);
466 let m = km.to::<Meter>();
467 assert_abs_diff_eq!(m.value(), 1000.0, epsilon = 1e-9);
468 }
469
470 #[test]
471 fn meter_to_kilometer() {
472 let m = Meters::new(1000.0);
473 let km = m.to::<Kilometer>();
474 assert_abs_diff_eq!(km.value(), 1.0, epsilon = 1e-12);
475 }
476
477 #[test]
478 #[cfg(feature = "astro")]
479 fn au_to_meters() {
480 let au = AstronomicalUnits::new(1.0);
481 let m = au.to::<Meter>();
482 assert_abs_diff_eq!(m.value(), AU_IN_METERS, epsilon = 1e-6);
484 }
485
486 #[test]
487 #[cfg(feature = "astro")]
488 fn au_to_kilometers() {
489 let au = AstronomicalUnits::new(1.0);
490 let km = au.to::<Kilometer>();
491 assert_relative_eq!(km.value(), 149_597_870.7, max_relative = 1e-12);
493 }
494
495 #[test]
496 #[cfg(feature = "astro")]
497 fn light_year_to_meters() {
498 let ly = LightYears::new(1.0);
499 let m = ly.to::<Meter>();
500 assert_relative_eq!(m.value(), LightYear::RATIO, max_relative = 1e-12);
502 }
503
504 #[test]
505 #[cfg(feature = "astro")]
506 fn light_year_to_kilometers() {
507 let ly = LightYears::new(1.0);
508 let km = ly.to::<Kilometer>();
509 assert_relative_eq!(km.value(), 9_460_730_472_580.000_8, max_relative = 1e-9);
511 }
512
513 #[test]
518 #[cfg(feature = "astro")]
519 fn au_to_light_year() {
520 let au = AstronomicalUnits::new(1.0);
521 let ly = au.to::<LightYear>();
522 assert_relative_eq!(ly.value(), 1.582e-5, max_relative = 1e-3);
524 }
525
526 #[test]
527 #[cfg(feature = "astro")]
528 fn light_year_to_au() {
529 let ly = LightYears::new(1.0);
530 let au = ly.to::<AstronomicalUnit>();
531 assert_relative_eq!(au.value(), 63241.0, max_relative = 1e-3);
533 }
534
535 #[test]
536 #[cfg(feature = "astro")]
537 fn from_impl_au_to_ly() {
538 let au = 1.0 * AU;
539 let ly: LightYears = au.into();
540 assert_relative_eq!(ly.value(), 1.582e-5, max_relative = 1e-3);
541 }
542
543 #[test]
544 #[cfg(feature = "astro")]
545 fn from_impl_ly_to_au() {
546 let ly = 1.0 * LY;
547 let au: AstronomicalUnits = ly.into();
548 assert_relative_eq!(au.value(), 63241.0, max_relative = 1e-3);
549 }
550
551 #[test]
556 #[cfg(feature = "astro")]
557 fn parsec_to_light_year() {
558 let pc = Parsecs::new(1.0);
559 let ly = pc.to::<LightYear>();
560 let expected = (AstronomicalUnit::RATIO * ARCSECONDS_PER_RADIAN) / LightYear::RATIO;
562 assert_relative_eq!(ly.value(), expected, max_relative = 1e-15);
563 }
564
565 #[test]
566 #[cfg(feature = "astro")]
567 fn parsec_to_au() {
568 let pc = Parsecs::new(1.0);
569 let au = pc.to::<AstronomicalUnit>();
570 assert_relative_eq!(au.value(), 3.26 * 63241.0, max_relative = 1e-2);
573 }
574
575 #[test]
576 #[cfg(feature = "astro")]
577 fn parsec_ratio_sanity() {
578 let lhs = Parsec::RATIO / AstronomicalUnit::RATIO;
580 let rhs = ARCSECONDS_PER_RADIAN;
581 assert_relative_eq!(lhs, rhs, max_relative = 1e-12);
582 }
583
584 #[test]
589 #[cfg(feature = "astro")]
590 fn solar_radius_to_meters() {
591 let sr = nominal::SolarRadiuses::new(1.0);
592 let m = sr.to::<Meter>();
593 assert_abs_diff_eq!(m.value(), 695_700_000.0, epsilon = 1e-3);
595 }
596
597 #[test]
598 #[cfg(feature = "astro")]
599 fn solar_radius_to_km() {
600 let sr = nominal::SolarRadiuses::new(1.0);
601 let km = sr.to::<Kilometer>();
602 assert_abs_diff_eq!(km.value(), 695_700.0, epsilon = 1e-6);
604 }
605
606 #[test]
611 fn roundtrip_km_m() {
612 let original = Kilometers::new(42.5);
613 let converted = original.to::<Meter>();
614 let back = converted.to::<Kilometer>();
615 assert_abs_diff_eq!(back.value(), original.value(), epsilon = 1e-12);
616 }
617
618 #[test]
619 #[cfg(feature = "astro")]
620 fn roundtrip_au_ly() {
621 let original = AstronomicalUnits::new(10000.0);
622 let converted = original.to::<LightYear>();
623 let back = converted.to::<AstronomicalUnit>();
624 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
625 }
626
627 #[test]
628 #[cfg(feature = "astro")]
629 fn roundtrip_parsec_ly() {
630 let original = Parsecs::new(5.0);
631 let converted = original.to::<LightYear>();
632 let back = converted.to::<Parsec>();
633 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
634 }
635
636 #[test]
641 #[cfg(feature = "customary")]
642 fn inch_to_meter_exact_ratio() {
643 let inch = Inches::new(1.0);
644 let m = inch.to::<Meter>();
645 assert_relative_eq!(m.value(), 0.0254, max_relative = 1e-16);
647 }
648
649 #[test]
650 #[cfg(feature = "navigation")]
651 fn nautical_mile_to_meter_exact_ratio() {
652 let nmi = NauticalMiles::new(1.0);
653 let m = nmi.to::<Meter>();
654 assert_abs_diff_eq!(m.value(), 1852.0, epsilon = 1e-12);
656 }
657
658 #[test]
663 #[cfg(feature = "customary")]
664 fn roundtrip_inch_meter() {
665 let original = Inches::new(123.456);
666 let converted = original.to::<Meter>();
667 let back = converted.to::<Inch>();
668 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
669 }
670
671 #[test]
672 #[cfg(feature = "navigation")]
673 fn roundtrip_nautical_mile_meter() {
674 let original = NauticalMiles::new(3.75);
675 let converted = original.to::<Meter>();
676 let back = converted.to::<NauticalMile>();
677 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
678 }
679
680 #[test]
681 #[cfg(feature = "astro")]
682 fn roundtrip_parsec_kpc() {
683 let original = Parsecs::new(12_345.0);
684 let converted = original.to::<Kiloparsec>();
685 let back = converted.to::<Parsec>();
686 assert_relative_eq!(back.value(), original.value(), max_relative = 1e-12);
687 }
688
689 proptest! {
694 #[test]
695 fn prop_roundtrip_km_m(k in -1e6..1e6f64) {
696 let original = Kilometers::new(k);
697 let converted = original.to::<Meter>();
698 let back = converted.to::<Kilometer>();
699 prop_assert!((back.value() - original.value()).abs() < 1e-9 * k.abs().max(1.0));
700 }
701
702 #[test]
703 fn prop_km_m_ratio(k in 1e-6..1e6f64) {
704 let km = Kilometers::new(k);
705 let m = km.to::<Meter>();
706 prop_assert!((m.value() / km.value() - 1000.0).abs() < 1e-9);
708 }
709
710 #[test]
711 #[cfg(feature = "astro")]
712 fn prop_roundtrip_au_km(a in 1e-6..1e6f64) {
713 let original = AstronomicalUnits::new(a);
714 let converted = original.to::<Kilometer>();
715 let back = converted.to::<AstronomicalUnit>();
716 prop_assert!((back.value() - original.value()).abs() / original.value() < 1e-12);
717 }
718
719 #[test]
720 #[cfg(feature = "customary")]
721 fn prop_roundtrip_inch_m(i in -1e6..1e6f64) {
722 let original = Inches::new(i);
723 let converted = original.to::<Meter>();
724 let back = converted.to::<Inch>();
725 let scale = i.abs().max(1.0);
726 prop_assert!((back.value() - original.value()).abs() < 1e-9 * scale);
727 }
728 }
729
730 #[test]
735 fn decimeter_to_meter() {
736 let q = Decimeters::new(10.0);
737 assert_relative_eq!(q.to::<Meter>().value(), 1.0, max_relative = 1e-15);
738 }
739
740 #[test]
741 fn centimeter_to_meter() {
742 let q = Centimeters::new(100.0);
743 assert_relative_eq!(q.to::<Meter>().value(), 1.0, max_relative = 1e-15);
744 }
745
746 #[test]
747 fn millimeter_to_centimeter() {
748 let q = Millimeters::new(10.0);
749 assert_relative_eq!(q.to::<Centimeter>().value(), 1.0, max_relative = 1e-15);
750 }
751
752 #[test]
753 fn micrometer_to_millimeter() {
754 let q = Micrometers::new(1_000.0);
755 assert_relative_eq!(q.to::<Millimeter>().value(), 1.0, max_relative = 1e-15);
756 }
757
758 #[test]
759 fn nanometer_to_micrometer() {
760 let q = Nanometers::new(1_000.0);
761 assert_relative_eq!(q.to::<Micrometer>().value(), 1.0, max_relative = 1e-15);
762 }
763
764 #[test]
765 fn picometer_to_nanometer() {
766 let q = Picometers::new(1_000.0);
767 assert_relative_eq!(q.to::<Nanometer>().value(), 1.0, max_relative = 1e-15);
768 }
769
770 #[test]
771 fn femtometer_to_picometer() {
772 let q = Femtometers::new(1_000.0);
773 assert_relative_eq!(q.to::<Picometer>().value(), 1.0, max_relative = 1e-15);
774 }
775
776 #[test]
777 fn attometer_to_femtometer() {
778 let q = Attometers::new(1_000.0);
779 assert_relative_eq!(q.to::<Femtometer>().value(), 1.0, max_relative = 1e-15);
780 }
781
782 #[test]
783 fn zeptometer_to_attometer() {
784 let q = Zeptometers::new(1_000.0);
785 assert_relative_eq!(q.to::<Attometer>().value(), 1.0, max_relative = 1e-15);
786 }
787
788 #[test]
789 fn yoctometer_to_zeptometer() {
790 let q = Yoctometers::new(1_000.0);
791 assert_relative_eq!(q.to::<Zeptometer>().value(), 1.0, max_relative = 1e-15);
792 }
793
794 #[test]
799 fn decameter_to_meter() {
800 let q = Decameters::new(1.0);
801 assert_relative_eq!(q.to::<Meter>().value(), 10.0, max_relative = 1e-15);
802 }
803
804 #[test]
805 fn hectometer_to_meter() {
806 let q = Hectometers::new(1.0);
807 assert_relative_eq!(q.to::<Meter>().value(), 100.0, max_relative = 1e-15);
808 }
809
810 #[test]
811 fn megameter_to_kilometer() {
812 let q = Megameters::new(1.0);
813 assert_relative_eq!(q.to::<Kilometer>().value(), 1_000.0, max_relative = 1e-15);
814 }
815
816 #[test]
817 fn gigameter_to_megameter() {
818 let q = Gigameters::new(1.0);
819 assert_relative_eq!(q.to::<Megameter>().value(), 1_000.0, max_relative = 1e-15);
820 }
821
822 #[test]
823 fn terameter_to_gigameter() {
824 let q = Terameters::new(1.0);
825 assert_relative_eq!(q.to::<Gigameter>().value(), 1_000.0, max_relative = 1e-15);
826 }
827
828 #[test]
829 fn petameter_to_terameter() {
830 let q = Petameters::new(1.0);
831 assert_relative_eq!(q.to::<Terameter>().value(), 1_000.0, max_relative = 1e-15);
832 }
833
834 #[test]
835 fn exameter_to_petameter() {
836 let q = Exameters::new(1.0);
837 assert_relative_eq!(q.to::<Petameter>().value(), 1_000.0, max_relative = 1e-15);
838 }
839
840 #[test]
841 fn zettameter_to_exameter() {
842 let q = Zettameters::new(1.0);
843 assert_relative_eq!(q.to::<Exameter>().value(), 1_000.0, max_relative = 1e-15);
844 }
845
846 #[test]
847 fn yottameter_to_zettameter() {
848 let q = Yottameters::new(1.0);
849 assert_relative_eq!(q.to::<Zettameter>().value(), 1_000.0, max_relative = 1e-15);
850 }
851
852 #[test]
857 #[cfg(feature = "customary")]
858 fn foot_to_meter() {
859 let q = Feet::new(1.0);
860 assert_relative_eq!(q.to::<Meter>().value(), 0.3048, max_relative = 1e-15);
862 }
863
864 #[test]
865 #[cfg(feature = "customary")]
866 fn yard_to_meter() {
867 let q = Yards::new(1.0);
868 assert_relative_eq!(q.to::<Meter>().value(), 0.9144, max_relative = 1e-15);
870 }
871
872 #[test]
873 #[cfg(feature = "customary")]
874 fn mile_to_kilometer() {
875 let q = Miles::new(1.0);
876 assert_relative_eq!(q.to::<Kilometer>().value(), 1.609_344, max_relative = 1e-15);
878 }
879
880 #[test]
881 #[cfg(all(feature = "navigation", feature = "customary"))]
882 fn fathom_to_foot() {
883 let q = Fathoms::new(1.0);
884 assert_relative_eq!(q.to::<Foot>().value(), 6.0, max_relative = 1e-14);
886 }
887
888 #[test]
889 #[cfg(all(feature = "navigation", feature = "customary"))]
890 fn chain_to_foot() {
891 let q = Chains::new(1.0);
892 assert_relative_eq!(q.to::<Foot>().value(), 66.0, max_relative = 1e-14);
894 }
895
896 #[test]
897 #[cfg(all(feature = "navigation", feature = "customary"))]
898 fn rod_to_foot() {
899 let q = Rods::new(1.0);
900 assert_relative_eq!(q.to::<Foot>().value(), 16.5, max_relative = 1e-14);
902 }
903
904 #[test]
905 #[cfg(all(feature = "navigation", feature = "customary"))]
906 fn link_to_foot() {
907 let q = Links::new(100.0);
908 assert_relative_eq!(q.to::<Foot>().value(), 66.0, max_relative = 1e-14);
910 }
911
912 #[test]
917 #[cfg(feature = "astro")]
918 fn megaparsec_to_kiloparsec() {
919 let q = Megaparsecs::new(1.0);
920 assert_relative_eq!(q.to::<Kiloparsec>().value(), 1_000.0, max_relative = 1e-12);
921 }
922
923 #[test]
924 #[cfg(feature = "astro")]
925 fn gigaparsec_to_megaparsec() {
926 let q = Gigaparsecs::new(1.0);
927 assert_relative_eq!(q.to::<Megaparsec>().value(), 1_000.0, max_relative = 1e-12);
928 }
929
930 #[test]
935 #[cfg(feature = "navigation")]
936 fn earth_meridional_circumference_to_km() {
937 let q = EarthMeridionalCircumferences::new(1.0);
938 assert_relative_eq!(q.to::<Kilometer>().value(), 40_007.863, max_relative = 1e-6);
940 }
941
942 #[test]
943 #[cfg(feature = "navigation")]
944 fn earth_equatorial_circumference_to_km() {
945 let q = EarthEquatorialCircumferences::new(1.0);
946 assert_relative_eq!(q.to::<Kilometer>().value(), 40_075.017, max_relative = 1e-6);
948 }
949
950 #[test]
955 #[cfg(feature = "fundamental-physics")]
956 fn bohr_radius_to_picometers() {
957 let q = BohrRadii::new(1.0);
958 assert_relative_eq!(q.to::<Picometer>().value(), 52.917_72, max_relative = 1e-5);
960 }
961
962 #[test]
963 #[cfg(feature = "fundamental-physics")]
964 fn classical_electron_radius_to_femtometers() {
965 let q = ClassicalElectronRadii::new(1.0);
966 assert_relative_eq!(
968 q.to::<Femtometer>().value(),
969 2.817_940_320_5,
970 max_relative = 1e-9
971 );
972 }
973
974 #[test]
975 #[cfg(feature = "fundamental-physics")]
976 fn planck_length_ratio() {
977 let q = PlanckLengths::new(1.0);
979 let back = q.to::<Meter>().to::<PlanckLength>();
980 assert_relative_eq!(back.value(), 1.0, max_relative = 1e-9);
981 }
982
983 #[test]
984 #[cfg(feature = "fundamental-physics")]
985 fn electron_compton_wavelength_to_femtometers() {
986 let q = ElectronReducedComptonWavelengths::new(1.0);
987 assert_relative_eq!(
989 q.to::<Femtometer>().value(),
990 386.159_267_44,
991 max_relative = 1e-7
992 );
993 }
994
995 #[test]
1000 #[cfg(feature = "astro")]
1001 fn earth_radius_to_km() {
1002 let q = nominal::EarthRadii::new(1.0);
1003 assert_relative_eq!(q.to::<Kilometer>().value(), 6_371.0, max_relative = 1e-9);
1004 }
1005
1006 #[test]
1007 #[cfg(feature = "astro")]
1008 fn earth_equatorial_radius_to_km() {
1009 let q = nominal::EarthEquatorialRadii::new(1.0);
1010 assert_relative_eq!(q.to::<Kilometer>().value(), 6_378.137, max_relative = 1e-9);
1011 }
1012
1013 #[test]
1014 #[cfg(feature = "astro")]
1015 fn earth_polar_radius_to_km() {
1016 let q = nominal::EarthPolarRadii::new(1.0);
1017 assert_relative_eq!(
1018 q.to::<Kilometer>().value(),
1019 6_356.752_314_2,
1020 max_relative = 1e-9
1021 );
1022 }
1023
1024 #[test]
1025 #[cfg(feature = "astro")]
1026 fn lunar_radius_to_km() {
1027 let q = nominal::LunarRadii::new(1.0);
1028 assert_relative_eq!(q.to::<Kilometer>().value(), 1_737.4, max_relative = 1e-9);
1029 }
1030
1031 #[test]
1032 #[cfg(feature = "astro")]
1033 fn jupiter_radius_to_km() {
1034 let q = nominal::JupiterRadii::new(1.0);
1035 assert_relative_eq!(q.to::<Kilometer>().value(), 71_492.0, max_relative = 1e-9);
1036 }
1037
1038 #[test]
1039 #[cfg(feature = "astro")]
1040 fn lunar_distance_to_km() {
1041 let q = nominal::LunarDistances::new(1.0);
1042 assert_relative_eq!(q.to::<Kilometer>().value(), 384_400.0, max_relative = 1e-9);
1043 }
1044
1045 #[test]
1046 #[cfg(feature = "astro")]
1047 fn solar_diameter_to_solar_radius() {
1048 let diameters = nominal::SolarDiameters::new(1.0);
1049 let radii = diameters.to::<nominal::SolarRadius>();
1050 assert_relative_eq!(radii.value(), 2.0, max_relative = 1e-14);
1051 }
1052
1053 #[test]
1054 fn symbols_are_correct() {
1055 assert_eq!(Meter::SYMBOL, "m");
1056 assert_eq!(Kilometer::SYMBOL, "km");
1057 assert_eq!(Centimeter::SYMBOL, "cm");
1058 #[cfg(feature = "customary")]
1059 assert_eq!(Inch::SYMBOL, "in");
1060 #[cfg(feature = "astro")]
1061 assert_eq!(AstronomicalUnit::SYMBOL, "au");
1062 #[cfg(feature = "astro")]
1063 assert_eq!(Parsec::SYMBOL, "pc");
1064 }
1065}