Skip to main content

codata/
lib.rs

1#![no_std]
2#![doc(
3    html_logo_url = "https://raw.githubusercontent.com/PlanetesLAB/documentation/refs/heads/main/logo.jpg"
4)]
5
6pub mod astro;
7mod constants;
8pub mod units;
9
10pub use astro::ASTRO_CONSTANTS;
11pub use constants::*;
12pub use constants::{CONSTANTS, Constant};
13
14/// Common aliases for physical and astronomical constants.
15pub mod aliases {
16    pub use crate::astro::iau2015::{AU, L_SUN, M_EARTH, M_JUP, M_SUN, PC, R_EARTH, R_JUP, R_SUN};
17    pub use crate::astro::iau2015::{
18        AU_CGS, AU_SI, L_SUN_CGS, L_SUN_SI, M_EARTH_CGS, M_EARTH_SI, M_JUP_CGS, M_JUP_SI,
19        M_SUN_CGS, M_SUN_SI, PC_CGS, PC_SI, R_EARTH_CGS, R_EARTH_SI, R_JUP_CGS, R_JUP_SI,
20        R_SUN_CGS, R_SUN_SI,
21    };
22    use crate::constants::{
23        AVOGADRO_CONSTANT, BOLTZMANN_CONSTANT, ELECTRON_MASS, ELEMENTARY_CHARGE,
24        MOLAR_GAS_CONSTANT, NEUTRON_MASS, NEWTONIAN_CONSTANT_OF_GRAVITATION, PLANCK_CONSTANT,
25        PROTON_MASS, REDUCED_PLANCK_CONSTANT, SPEED_OF_LIGHT_IN_VACUUM, STEFAN_BOLTZMANN_CONSTANT,
26    };
27    pub use crate::constants::{
28        BOLTZMANN_CONSTANT_CGS, BOLTZMANN_CONSTANT_SI, ELECTRON_MASS_CGS, ELECTRON_MASS_SI,
29        MOLAR_GAS_CONSTANT_CGS, MOLAR_GAS_CONSTANT_SI, NEUTRON_MASS_CGS, NEUTRON_MASS_SI,
30        NEWTONIAN_CONSTANT_OF_GRAVITATION_CGS, NEWTONIAN_CONSTANT_OF_GRAVITATION_SI,
31        PLANCK_CONSTANT_CGS, PLANCK_CONSTANT_SI, PROTON_MASS_CGS, PROTON_MASS_SI,
32        REDUCED_PLANCK_CONSTANT_CGS, REDUCED_PLANCK_CONSTANT_SI, SPEED_OF_LIGHT_IN_VACUUM_CGS,
33        SPEED_OF_LIGHT_IN_VACUUM_SI, STEFAN_BOLTZMANN_CONSTANT_CGS, STEFAN_BOLTZMANN_CONSTANT_SI,
34    };
35
36    /// Speed of light in vacuum
37    pub const C: f64 = SPEED_OF_LIGHT_IN_VACUUM;
38    pub const C_SI: f64 = SPEED_OF_LIGHT_IN_VACUUM_SI;
39    pub const C_CGS: f64 = SPEED_OF_LIGHT_IN_VACUUM_CGS;
40
41    /// Newtonian constant of gravitation
42    pub const G: f64 = NEWTONIAN_CONSTANT_OF_GRAVITATION;
43    pub const G_SI: f64 = NEWTONIAN_CONSTANT_OF_GRAVITATION_SI;
44    pub const G_CGS: f64 = NEWTONIAN_CONSTANT_OF_GRAVITATION_CGS;
45
46    /// Planck constant
47    pub const H: f64 = PLANCK_CONSTANT;
48    pub const H_SI: f64 = PLANCK_CONSTANT_SI;
49    pub const H_CGS: f64 = PLANCK_CONSTANT_CGS;
50
51    /// Reduced Planck constant (h/2pi)
52    pub const HBAR: f64 = REDUCED_PLANCK_CONSTANT;
53    pub const HBAR_SI: f64 = REDUCED_PLANCK_CONSTANT_SI;
54    pub const HBAR_CGS: f64 = REDUCED_PLANCK_CONSTANT_CGS;
55
56    /// Elementary charge
57    pub const E: f64 = ELEMENTARY_CHARGE;
58
59    /// Electron mass
60    pub const ME: f64 = ELECTRON_MASS;
61    pub const ME_SI: f64 = ELECTRON_MASS_SI;
62    pub const ME_CGS: f64 = ELECTRON_MASS_CGS;
63
64    /// Proton mass
65    pub const MP: f64 = PROTON_MASS;
66    pub const MP_SI: f64 = PROTON_MASS_SI;
67    pub const MP_CGS: f64 = PROTON_MASS_CGS;
68
69    /// Neutron mass
70    pub const MN: f64 = NEUTRON_MASS;
71    pub const MN_SI: f64 = NEUTRON_MASS_SI;
72    pub const MN_CGS: f64 = NEUTRON_MASS_CGS;
73
74    /// Avogadro constant
75    pub const NA: f64 = AVOGADRO_CONSTANT;
76
77    /// Molar gas constant
78    pub const R: f64 = MOLAR_GAS_CONSTANT;
79    pub const R_SI: f64 = MOLAR_GAS_CONSTANT_SI;
80    pub const R_CGS: f64 = MOLAR_GAS_CONSTANT_CGS;
81
82    /// Boltzmann constant
83    pub const K: f64 = BOLTZMANN_CONSTANT;
84    pub const K_SI: f64 = BOLTZMANN_CONSTANT_SI;
85    pub const K_CGS: f64 = BOLTZMANN_CONSTANT_CGS;
86
87    /// Stefan-Boltzmann constant
88    pub const SIGMA: f64 = STEFAN_BOLTZMANN_CONSTANT;
89    pub const SIGMA_SI: f64 = STEFAN_BOLTZMANN_CONSTANT_SI;
90    pub const SIGMA_CGS: f64 = STEFAN_BOLTZMANN_CONSTANT_CGS;
91}
92
93/// Find a constant by its official name.
94///
95/// This searches both physical (CODATA) and astronomical (IAU) constants.
96///
97/// Returns `Some(Constant)` if found, `None` otherwise.
98///
99/// # Example
100/// ```
101/// use codata::find;
102/// let c = find("speed of light in vacuum").unwrap();
103/// assert_eq!(c.value, 299792458.0);
104///
105/// let au = find("Astronomical Unit").unwrap();
106/// assert_eq!(au.value, 149597870700.0);
107/// ```
108#[must_use]
109pub fn find(name: &str) -> Option<Constant> {
110    CONSTANTS
111        .iter()
112        .find(|(n, _)| n.eq_ignore_ascii_case(name))
113        .map(|(_, c)| *c)
114        .or_else(|| {
115            ASTRO_CONSTANTS
116                .iter()
117                .find(|(n, _)| n.eq_ignore_ascii_case(name))
118                .map(|(_, c)| *c)
119        })
120}
121
122#[cfg(test)]
123mod tests {
124    #![allow(clippy::float_cmp)]
125
126    use super::*;
127    use crate::constants::SPEED_OF_LIGHT_IN_VACUUM;
128
129    #[test]
130    fn test_speed_of_light() {
131        assert_eq!(SPEED_OF_LIGHT_IN_VACUUM, 299_792_458.0);
132        assert_eq!(aliases::C, 299_792_458.0);
133    }
134
135    #[test]
136    fn test_find() {
137        let c = find("speed of light in vacuum").unwrap();
138        assert_eq!(c.value, 299_792_458.0);
139        assert_eq!(c.unit, "m s^-1");
140        assert_eq!(c.uncertainty, 0.0);
141
142        let au = find("Astronomical Unit").unwrap();
143        assert_eq!(au.value, 149_597_870_700.0);
144    }
145
146    #[test]
147    fn test_astro_aliases() {
148        assert_eq!(aliases::AU, 149_597_870_700.0);
149        const { assert!(aliases::M_SUN > 1.9e30) };
150    }
151
152    #[test]
153    fn test_gravitation() {
154        let g = find("Newtonian constant of gravitation").unwrap();
155        // CODATA 2022 value is 6.674 30(15) x 10^-11 m^3 kg^-1 s^-2
156        assert!((g.value - 6.674_30e-11).abs() < 1e-16);
157    }
158
159    #[test]
160    fn test_cgs_conversions() {
161        // G_cgs = G_si * 10^3
162        assert!((aliases::G_CGS / aliases::G_SI - 1000.0).abs() < 1e-10);
163        // c_cgs = c_si * 100
164        assert_eq!(aliases::C_CGS, aliases::C_SI * 100.0);
165        // h_cgs = h_si * 10^7 (J -> erg)
166        assert!((aliases::H_CGS / aliases::H_SI - 1e7).abs() < 1e-10);
167        // sigma_cgs = sigma_si * 10^3 (W/m^2/K^4 -> erg/s/cm^2/K^4)
168        // 10^7 (erg/s) / 10^4 (cm^2) = 10^3
169        assert!((aliases::SIGMA_CGS / aliases::SIGMA_SI - 1000.0).abs() < 1e-10);
170    }
171
172    #[test]
173    fn test_units() {
174        use crate::units::{length, time};
175        assert_eq!(time::MINUTE, 60.0);
176        assert_eq!(time::HOUR, 3600.0);
177        assert_eq!(length::INCH, 0.0254);
178        assert_eq!(length::LIGHT_YEAR, 9_460_730_472_580_800.0);
179    }
180}