diff --git a/src/constants.rs b/src/constants.rs index 9ff26c3..1044b92 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,6 +1,9 @@ // Copyright © 2023 Common (CMN) library. All rights reserved. // SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright © 2023 Common (CMN) library. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 OR MIT + use serde::{Deserialize, Serialize}; /// Contains several commonly used mathematical and cryptographic constants. @@ -32,6 +35,55 @@ pub struct Constants { } impl Constants { + /// Returns the value of the constant. + /// + /// # Example + /// + /// ``` + /// use cmn::constants::Constants; + /// use cmn::constants::ConstantValue; + /// + /// let constants = Constants::new(); + /// let constant = constants.constant("EULER").unwrap(); + /// let value = constants.get_value(constant.name); + /// + /// if let Some(ConstantValue::Float(float_value)) = value { + /// assert!((float_value - 2.71828).abs() < 1e-5); + /// } + /// else { + /// panic!("Expected a float value"); + /// } + /// + /// ``` + pub fn get_value(&self, name: &str) -> Option { + if let Some(constant) = self.constant(name) { + if let Ok(float_value) = constant.value.parse::() { + Some(ConstantValue::Float(float_value)) + } else if let Ok(u32_value) = constant.value.parse::() + { + Some(ConstantValue::U32(u32_value)) + } else if let Ok(usize_value) = + constant.value.parse::() + { + Some(ConstantValue::Usize(usize_value)) + } else if let Some(char_array) = Self::get_char_array(name) + { + Some(ConstantValue::CharArray(char_array)) + } else { + Some(ConstantValue::String(constant.value.clone())) + } + } else { + None + } + } + + fn get_char_array(name: &str) -> Option<&'static [char]> { + match name { + "SPECIAL_CHARS" => Some(SPECIAL_CHARS), + _ => None, + } + } + /// Returns a vector of tuples with the constant name and its value. /// /// # Arguments @@ -82,12 +134,16 @@ impl Constants { /// use cmn::constants::Constants; /// /// let constants = Constants::new(); - /// assert_eq!(constants.constants().len(), 16); + /// assert_eq!(constants.constants().len(), 28); /// /// ``` /// pub fn new() -> Self { let constants = vec![ + Constant { + name: "APERY", + value: APERY.to_string(), + }, Constant { name: "AVOGADRO", value: AVOGADRO.to_string(), @@ -96,14 +152,38 @@ impl Constants { name: "BOLTZMANN", value: BOLTZMANN.to_string(), }, + Constant { + name: "CATALAN", + value: CATALAN.to_string(), + }, + Constant { + name: "COULOMB", + value: COULOMB.to_string(), + }, Constant { name: "EULER", value: EULER.to_string(), }, + Constant { + name: "FARADAY", + value: FARADAY.to_string(), + }, Constant { name: "GAMMA", value: GAMMA.to_string(), }, + Constant { + name: "GAS_CONSTANT", + value: GAS_CONSTANT.to_string(), + }, + Constant { + name: "GLAISHER_KINKELIN", + value: GLAISHER_KINKELIN.to_string(), + }, + Constant { + name: "GRAVITATIONAL_CONSTANT", + value: GRAVITATIONAL_CONSTANT.to_string(), + }, Constant { name: "HASH_ALGORITHM", value: HASH_ALGORITHM.to_string(), @@ -116,6 +196,10 @@ impl Constants { name: "HASH_LENGTH", value: HASH_LENGTH.to_string(), }, + Constant { + name: "KHINCHIN", + value: KHINCHIN.to_string(), + }, Constant { name: "PHI", value: PHI.to_string(), @@ -128,10 +212,18 @@ impl Constants { name: "PLANCK", value: PLANCK.to_string(), }, + Constant { + name: "PLANCK_REDUCED", + value: PLANCK_REDUCED.to_string(), + }, Constant { name: "SILVER_RATIO", value: SILVER_RATIO.to_string(), }, + Constant { + name: "SPEED_OF_LIGHT", + value: SPEED_OF_LIGHT.to_string(), + }, Constant { name: "SPECIAL_CHARS", value: SPECIAL_CHARS.iter().collect::(), @@ -152,6 +244,14 @@ impl Constants { name: "TAU", value: TAU.to_string(), }, + Constant { + name: "VACUUM_PERMEABILITY", + value: VACUUM_PERMEABILITY.to_string(), + }, + Constant { + name: "VACUUM_PERMITTIVITY", + value: VACUUM_PERMITTIVITY.to_string(), + }, ]; Self { constants } @@ -188,23 +288,50 @@ pub enum ConstantValue { CharArray(&'static [char]), } -/// Avogadro's constant -/// Approximately 6.02214076 x 10^23 -pub const AVOGADRO: f64 = 602214076000000000000000.0; +/// Apéry's constant, which is the sum of the reciprocals of the positive cubes. +/// ζ(3) ≈ 1.2020569032 +pub const APERY: f64 = 1.2020569031595942; + +/// Avogadro's constant, which is the number of constituent particles contained in one mole of a substance. +/// N_A ≈ 6.02214076 x 10^23 mol^-1 +pub const AVOGADRO: f64 = 6.02214076e23; -/// Boltzmann's constant -/// Approximately 1.380648 x 10^-23 +/// Boltzmann's constant, which relates the average kinetic energy of particles in a gas with the temperature of the gas. +/// k_B ≈ 1.380648 x 10^-23 J K^-1 pub const BOLTZMANN: f64 = 1.380648e-23; -/// The base of the natural logarithm, Euler's number (e). +/// Catalan's constant, which is the sum of the alternating harmonic series. +/// C ≈ 0.9159655942 +pub const CATALAN: f64 = 0.9159655941772190; + +/// Coulomb's constant, which is the proportionality constant in Coulomb's law. +/// k_e ≈ 8.9875517923 x 10^9 N m^2 C^-2 +pub const COULOMB: f64 = 8.9875517923e9; + +/// The base of the natural logarithm, Euler's number. /// e ≈ 2.7182818284590452353602874713527 pub const EULER: f64 = std::f64::consts::E; -/// The mathematical constant `γ` or the Euler–Mascheroni constant. It -/// is the limit of the difference between the harmonic series and the -/// natural logarithm of the natural numbers. +/// Faraday constant, which represents the amount of electric charge carried by one mole of electrons. +/// F ≈ 96485.33212 C mol^-1 +pub const FARADAY: f64 = 96485.33212; + +/// The Euler-Mascheroni constant, which is the limiting difference between the harmonic series and the natural logarithm. +/// γ ≈ 0.5772156649015329 pub const GAMMA: f64 = 0.5772156649015329; +/// The gas constant, which relates the energy scale to the temperature scale in the ideal gas law. +/// R ≈ 8.314462618 J mol^-1 K^-1 +pub const GAS_CONSTANT: f64 = 8.314462618; + +/// Glaisher-Kinkelin constant, which arises in the asymptotic expansion of the Barnes G-function. +/// A ≈ 1.2824271291 +pub const GLAISHER_KINKELIN: f64 = 1.2824271291006226; + +/// The gravitational constant, which is the proportionality constant in Newton's law of universal gravitation. +/// G ≈ 6.67430 x 10^-11 m^3 kg^-1 s^-2 +pub const GRAVITATIONAL_CONSTANT: f64 = 6.67430e-11; + /// The hash algorithm used. The default is Blake3. pub const HASH_ALGORITHM: &str = "Blake3"; @@ -217,22 +344,34 @@ pub const HASH_COST: u32 = 8; /// - The minimum is 16. pub const HASH_LENGTH: usize = 32; -/// The mathematical constant `φ` or the golden ratio. It is the -/// limit of the ratio of consecutive Fibonacci numbers. -/// Φ = (1+√5)/2 = 2.cos(π/5). Diagonal of a unit-side pentagon. +/// Khinchin's constant, which appears in the theory of continued fractions. +/// K ≈ 2.6854520010 +pub const KHINCHIN: f64 = 2.6854520010653064; + +/// The golden ratio, which is the limit of the ratio of consecutive Fibonacci numbers. +/// φ = (1 + √5) / 2 ≈ 1.6180339887498948482045868343656 pub const PHI: f64 = (1.0 + SQRT5) / 2.0; -/// The mathematical constant `π` or the ratio of a circle's -/// circumference to its diameter. +/// The ratio of a circle's circumference to its diameter. +/// π ≈ 3.14159265358979323846264338327950288 pub const PI: f64 = std::f64::consts::PI; -/// The Planck constant, `h`. +/// Planck's constant, which relates the energy of a photon to its frequency. +/// h ≈ 6.62607015 x 10^-34 J s pub const PLANCK: f64 = 6.62607015e-34; -/// The mathematical constant `δs' or the silver ratio (or silver mean). -/// δs = 1+√2. One of the silver means (n+sqrt(n2+1))/2 for n>0. +/// Planck's reduced constant, which is Planck's constant divided by 2π. +/// ħ = h / (2π) ≈ 1.054571817 x 10^-34 J s +pub const PLANCK_REDUCED: f64 = PLANCK / (2.0 * PI); + +/// The silver ratio, which is one of the silver means. +/// δ_s = 1 + √2 ≈ 2.4142135623730950488016887242097 pub const SILVER_RATIO: f64 = 1.0 + SQRT2; +/// The speed of light in vacuum. +/// c ≈ 299792458 m s^-1 +pub const SPEED_OF_LIGHT: f64 = 299792458.0; + /// A set of special characters. pub const SPECIAL_CHARS: &[char] = &[ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', @@ -240,24 +379,26 @@ pub const SPECIAL_CHARS: &[char] = &[ '/', '~', '`', ]; -/// The mathematical constant `√2` or the Pythagora's constant or the -/// square root of 2. It is the diagonal of a square with unit side -/// length. -/// 2 = 1 + √2 +/// The square root of 2. +/// √2 ≈ 1.4142135623730950488016887242097 pub const SQRT2: f64 = std::f64::consts::SQRT_2; -/// The mathematical constant `√3` or the principal square root of 3. -/// It is the length of the side of an equilateral triangle with unit -/// side length. -/// 3 = 1 + √3 -pub const SQRT3: f64 = 1.732_050_807_568_877_2; +/// The square root of 3. +/// √3 ≈ 1.7320508075688772935274463415059 +pub const SQRT3: f64 = 1.7320508075688772; -/// The mathematical constant `√5` or the principal square root of 5. -/// It is the length of the diagonal of a regular pentagon with unit -/// side length. -/// 5 = 2 + 2√5 -pub const SQRT5: f64 = 2.236_067_977_499_79; +/// The square root of 5. +/// √5 ≈ 2.2360679774997896964091736687313 +pub const SQRT5: f64 = 2.2360679774997896; -/// The mathematical constant `τ` or the ratio of a circle's -/// circumference to its radius. +/// The circle constant, which is the ratio of a circle's circumference to its radius. +/// τ = 2π ≈ 6.28318530717958647692528676655900577 pub const TAU: f64 = std::f64::consts::TAU; + +/// The vacuum permeability, which relates magnetic induction to magnetic field strength. +/// μ_0 ≈ 1.25663706212 x 10^-6 N A^-2 +pub const VACUUM_PERMEABILITY: f64 = 1.25663706212e-6; + +/// The vacuum permittivity, which relates electric displacement to electric field strength. +/// ε_0 ≈ 8.8541878128 x 10^-12 F m^-1 +pub const VACUUM_PERMITTIVITY: f64 = 8.8541878128e-12; diff --git a/tests/test_constants.rs b/tests/test_constants.rs index 49bba61..94664d0 100644 --- a/tests/test_constants.rs +++ b/tests/test_constants.rs @@ -20,26 +20,38 @@ mod tests { fn test_constants() { let new_constant = Constants::new(); let constants = new_constant.constants(); - assert_eq!(constants.len(), 16); + assert_eq!(constants.len(), 28); let names = constants.iter().map(|c| c.name).collect::>(); + assert!(names.contains(&"APERY")); assert!(names.contains(&"AVOGADRO")); assert!(names.contains(&"BOLTZMANN")); + assert!(names.contains(&"CATALAN")); + assert!(names.contains(&"COULOMB")); assert!(names.contains(&"EULER")); + assert!(names.contains(&"FARADAY")); assert!(names.contains(&"GAMMA")); + assert!(names.contains(&"GAS_CONSTANT")); + assert!(names.contains(&"GLAISHER_KINKELIN")); + assert!(names.contains(&"GRAVITATIONAL_CONSTANT")); assert!(names.contains(&"HASH_ALGORITHM")); assert!(names.contains(&"HASH_COST")); assert!(names.contains(&"HASH_LENGTH")); + assert!(names.contains(&"KHINCHIN")); assert!(names.contains(&"PHI")); assert!(names.contains(&"PI")); assert!(names.contains(&"PLANCK")); + assert!(names.contains(&"PLANCK_REDUCED")); assert!(names.contains(&"SILVER_RATIO")); + assert!(names.contains(&"SPEED_OF_LIGHT")); assert!(names.contains(&"SPECIAL_CHARS")); assert!(names.contains(&"SQRT2")); assert!(names.contains(&"SQRT3")); assert!(names.contains(&"SQRT5")); assert!(names.contains(&"TAU")); + assert!(names.contains(&"VACUUM_PERMEABILITY")); + assert!(names.contains(&"VACUUM_PERMITTIVITY")); } #[test] fn test_new() { diff --git a/tests/test_lib.rs b/tests/test_lib.rs index c1dc642..82c89ee 100644 --- a/tests/test_lib.rs +++ b/tests/test_lib.rs @@ -10,7 +10,7 @@ mod tests { let constants = Constants::new(); assert!(constants.is_valid()); assert!(constants.constants.len() >= 9); - assert!(constants.constants.len() <= 16); + assert!(constants.constants.len() <= 28); } #[test] @@ -25,7 +25,7 @@ mod tests { let constants = Constants::new(); let new_constants = constants.constants(); - assert_eq!(new_constants.len(), 16); + assert_eq!(new_constants.len(), 28); assert_eq!(new_constants, constants.constants()); } @@ -41,7 +41,7 @@ mod tests { let common = Common::default(); let constants = common.constants(); - assert_eq!(constants.constants().len(), 16); + assert_eq!(constants.constants().len(), 28); assert_eq!( constants.constants(), Constants::default().constants() @@ -53,7 +53,7 @@ mod tests { let constants = Constants::new(); let new_constants = constants.constants(); - assert_eq!(new_constants.len(), 16); + assert_eq!(new_constants.len(), 28); assert_eq!(new_constants, Constants::default().constants()); } @@ -62,8 +62,8 @@ mod tests { let constants = Constants::new(); let new_constants = constants.constants().to_vec(); - assert_eq!(new_constants.len(), 16); - assert_eq!(constants.constants().len(), 16); + assert_eq!(new_constants.len(), 28); + assert_eq!(constants.constants().len(), 28); assert_eq!(new_constants, constants.constants().to_vec()); } @@ -72,7 +72,7 @@ mod tests { let constants = Constants::new(); let new_constants = constants.constants(); - assert_eq!(new_constants.len(), 16); + assert_eq!(new_constants.len(), 28); assert_eq!(new_constants, Constants::default().constants()); } @@ -82,7 +82,7 @@ mod tests { let binding = Constants::default(); let default_constants = binding.constants(); - assert_eq!(default_constants.len(), 16); + assert_eq!(default_constants.len(), 28); assert_eq!(default_constants, constants.constants()); } diff --git a/tests/test_macros.rs b/tests/test_macros.rs index 3fd1165..7b27211 100644 --- a/tests/test_macros.rs +++ b/tests/test_macros.rs @@ -3,9 +3,8 @@ mod tests { // Importing cmn crate and all of its macros use cmn::{ - cmn_assert, cmn_contains, cmn_in_range, cmn_join, cmn_max, - cmn_min, cmn_print, cmn_print_vec, cmn_split, cmn_vec, - constants::*, + cmn_assert, cmn_contains, cmn_join, cmn_max, cmn_min, + cmn_print, cmn_print_vec, cmn_split, cmn_vec, constants::*, }; #[test] @@ -73,16 +72,13 @@ mod tests { assert!(!cmn_contains!("Hello", "x")); } - #[test] - fn test_cmn_in_range() { - // Test that cmn_in_range! macro correctly checks if a number is within a range - cmn_assert!(cmn_in_range!(10, 0, 100)); - cmn_assert!(!cmn_in_range!(-10, 0, 100)); - } - #[test] fn test_cmn_constants() { // Test that each constant defined by the cmn_constants! macro has the expected value or is not empty + assert_eq!( + APERY, 1.2020569031595942, + "APERY should have a specific value" + ); assert_eq!( AVOGADRO, 6.02214076e23, "AVOGADRO should have a specific value" @@ -92,13 +88,38 @@ mod tests { "BOLTZMANN should have a specific value" ); assert_eq!( - EULER, std::f64::consts::E, + CATALAN, 0.9159655941772190, + "CATALAN should have a specific value" + ); + assert_eq!( + COULOMB, 8.9875517923e9, + "COULOMB should have a specific value" + ); + assert_eq!( + EULER, + std::f64::consts::E, "EULER should have a specific value" ); + assert_eq!( + FARADAY, 96485.33212, + "FARADAY should have a specific value" + ); assert_eq!( GAMMA, 0.5772156649015329, "GAMMA should have a specific value" ); + assert_eq!( + GAS_CONSTANT, 8.314462618, + "GAS_CONSTANT should have a specific value" + ); + assert_eq!( + GLAISHER_KINKELIN, 1.2824271291006226, + "GLAISHER_KINKELIN should have a specific value" + ); + assert_eq!( + GRAVITATIONAL_CONSTANT, 6.67430e-11, + "GRAVITATIONAL_CONSTANT should have a specific value" + ); assert_eq!( HASH_ALGORITHM, "Blake3", "HASH_ALGORITHM should have a specific value" @@ -111,6 +132,10 @@ mod tests { HASH_LENGTH, 32, "HASH_LENGTH should have a specific value" ); + assert_eq!( + KHINCHIN, 2.6854520010653064, + "KHINCHIN should have a specific value" + ); assert_eq!( PHI, (1.0 + SQRT5) / 2.0, @@ -125,11 +150,19 @@ mod tests { PLANCK, 6.62607015e-34, "PLANCK should have a specific value" ); + assert_eq!( + PLANCK_REDUCED, 1.0545718176461565e-34, + "PLANCK_REDUCED should have a specific value" + ); assert_eq!( SILVER_RATIO, 1.0 + SQRT2, "SILVER_RATIO should have a specific value" ); + assert_eq!( + SPEED_OF_LIGHT, 299_792_458.0, + "SPEED_OF_LIGHT should have a specific value" + ); assert_eq!( SPECIAL_CHARS, &[ @@ -149,9 +182,17 @@ mod tests { "SQRT3 should have a specific value" ); assert_eq!( - SQRT5, 2.23606797749979, + SQRT5, 2.2360679774997896, "SQRT5 should have a specific value" ); assert_eq!(TAU, 2.0 * PI, "TAU should have a specific value"); + assert_eq!( + VACUUM_PERMEABILITY, 1.25663706212e-6, + "VACUUM_PERMEABILITY should have a specific value" + ); + assert_eq!( + VACUUM_PERMITTIVITY, 8.8541878128e-12, + "VACUUM_PERMITTIVITY should have a specific value" + ); } }