pub mod atomic;
pub mod electromagnetic;
pub mod fundamental;
pub mod units;
pub use fundamental::{
ATOMIC_MASS_UNIT, AVOGADRO_CONSTANT, BOLTZMANN_CONSTANT, ELECTRON_CHARGE_MASS_RATIO,
ELECTRON_MASS, ELEMENTARY_CHARGE, FINE_STRUCTURE_CONSTANT, GAS_CONSTANT,
GRAVITATIONAL_CONSTANT, NEUTRON_MASS, PLANCK_CONSTANT, PROTON_MASS, REDUCED_PLANCK_CONSTANT,
SPEED_OF_LIGHT, STEFAN_BOLTZMANN_CONSTANT,
};
pub use atomic::{
BOHR_MAGNETON, BOHR_RADIUS, CLASSICAL_ELECTRON_RADIUS, COMPTON_WAVELENGTH, ELECTRON_G_FACTOR,
HARTREE_ENERGY, NUCLEAR_MAGNETON, PROTON_MAGNETIC_MOMENT, RYDBERG_CONSTANT,
};
pub use electromagnetic::{
CONDUCTANCE_QUANTUM, COULOMB_CONSTANT, IMPEDANCE_OF_FREE_SPACE, JOSEPHSON_CONSTANT,
MAGNETIC_FLUX_QUANTUM, VACUUM_PERMEABILITY, VACUUM_PERMITTIVITY, VON_KLITZING_CONSTANT,
};
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct PhysicalConstant {
pub value: f64,
pub uncertainty: f64,
pub unit: &'static str,
pub symbol: &'static str,
pub name: &'static str,
}
impl PhysicalConstant {
pub fn relative_uncertainty(&self) -> f64 {
if self.value == 0.0 || self.uncertainty == 0.0 {
0.0
} else {
self.uncertainty / self.value.abs()
}
}
pub fn is_exact(&self) -> bool {
self.uncertainty == 0.0
}
}
impl fmt::Display for PhysicalConstant {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_exact() {
write!(
f,
"{} ({}) = {} {} (exact)",
self.name, self.symbol, self.value, self.unit
)
} else {
write!(
f,
"{} ({}) = {} {} (uncertainty: {})",
self.name, self.symbol, self.value, self.unit, self.uncertainty
)
}
}
}
#[cfg(test)]
#[allow(clippy::assertions_on_constants)]
mod tests {
use super::*;
#[test]
fn test_physical_constant_display_exact() {
let c = PhysicalConstant {
value: 299_792_458.0,
uncertainty: 0.0,
unit: "m/s",
symbol: "c",
name: "Speed of light in vacuum",
};
let display = format!("{}", c);
assert!(display.contains("exact"));
assert!(display.contains("299792458"));
assert!(display.contains("m/s"));
}
#[test]
fn test_physical_constant_display_with_uncertainty() {
let g = PhysicalConstant {
value: 6.674_30e-11,
uncertainty: 1.5e-15,
unit: "m^3 kg^-1 s^-2",
symbol: "G",
name: "Newtonian constant of gravitation",
};
let display = format!("{}", g);
assert!(display.contains("uncertainty"));
assert!(!display.contains("exact"));
}
#[test]
fn test_is_exact() {
assert!(SPEED_OF_LIGHT.is_exact());
assert!(PLANCK_CONSTANT.is_exact());
assert!(ELEMENTARY_CHARGE.is_exact());
assert!(BOLTZMANN_CONSTANT.is_exact());
assert!(AVOGADRO_CONSTANT.is_exact());
assert!(!GRAVITATIONAL_CONSTANT.is_exact());
assert!(!FINE_STRUCTURE_CONSTANT.is_exact());
}
#[test]
fn test_relative_uncertainty_exact() {
assert_eq!(SPEED_OF_LIGHT.relative_uncertainty(), 0.0);
}
#[test]
fn test_relative_uncertainty_nonexact() {
let rel = GRAVITATIONAL_CONSTANT.relative_uncertainty();
assert!(rel > 0.0);
assert!(rel < 1.0e-4); }
#[test]
fn test_physical_constant_clone() {
let c1 = SPEED_OF_LIGHT;
let c2 = c1;
assert_eq!(c1.value, c2.value);
assert_eq!(c1.symbol, c2.symbol);
}
#[test]
fn test_physical_constant_debug() {
let debug_str = format!("{:?}", SPEED_OF_LIGHT);
assert!(debug_str.contains("PhysicalConstant"));
assert!(debug_str.contains("value"));
}
#[test]
fn test_zero_value_relative_uncertainty() {
let zero_const = PhysicalConstant {
value: 0.0,
uncertainty: 0.0,
unit: "",
symbol: "",
name: "Zero constant",
};
assert_eq!(zero_const.relative_uncertainty(), 0.0);
}
#[test]
fn test_reexports_fundamental() {
assert!(SPEED_OF_LIGHT.value > 0.0);
assert!(PLANCK_CONSTANT.value > 0.0);
assert!(BOLTZMANN_CONSTANT.value > 0.0);
assert!(AVOGADRO_CONSTANT.value > 0.0);
assert!(ELEMENTARY_CHARGE.value > 0.0);
}
#[test]
fn test_reexports_atomic() {
assert!(BOHR_RADIUS.value > 0.0);
assert!(RYDBERG_CONSTANT.value > 0.0);
assert!(HARTREE_ENERGY.value > 0.0);
}
#[test]
fn test_reexports_electromagnetic() {
assert!(VACUUM_PERMITTIVITY.value > 0.0);
assert!(VACUUM_PERMEABILITY.value > 0.0);
assert!(IMPEDANCE_OF_FREE_SPACE.value > 0.0);
}
#[test]
fn test_physical_constant_partial_eq() {
let c1 = PhysicalConstant {
value: 1.0,
uncertainty: 0.0,
unit: "m",
symbol: "x",
name: "Test",
};
let c2 = PhysicalConstant {
value: 1.0,
uncertainty: 0.0,
unit: "m",
symbol: "x",
name: "Test",
};
assert_eq!(c1, c2);
}
#[test]
fn test_physical_constant_copy() {
let c1 = PLANCK_CONSTANT;
let c2 = c1;
assert_eq!(c1.value, c2.value);
assert_eq!(c1.uncertainty, c2.uncertainty);
}
#[test]
fn test_unit_strings_not_empty() {
assert!(!SPEED_OF_LIGHT.unit.is_empty());
assert!(!PLANCK_CONSTANT.unit.is_empty());
assert!(!GRAVITATIONAL_CONSTANT.unit.is_empty());
assert!(!BOHR_RADIUS.unit.is_empty());
assert!(!VACUUM_PERMITTIVITY.unit.is_empty());
}
#[test]
fn test_symbol_strings_not_empty() {
assert!(!SPEED_OF_LIGHT.symbol.is_empty());
assert!(!PLANCK_CONSTANT.symbol.is_empty());
assert!(!ELEMENTARY_CHARGE.symbol.is_empty());
}
}