1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4pub use use_atomic_mass;
5pub use use_atomic_number;
6pub use use_bond;
7pub use use_chemical_formula;
8pub use use_compound;
9pub use use_electron_shell;
10pub use use_element;
11pub use use_ion;
12pub use use_isotope;
13pub use use_molar_mass;
14pub use use_molecule;
15pub use use_oxidation_state;
16pub use use_periodic_table;
17pub use use_reaction;
18pub use use_stoichiometry;
19
20pub mod prelude;
21
22#[cfg(test)]
23mod tests {
24 use super::prelude::{
25 AtomicMassEntry, AtomicMassLookup, Bond, BondKind, BondOrder, ChemicalFormula,
26 ChemicalReaction, Compound, CompoundKind, ElementOxidationState, Ion, IonCharge,
27 MolarMassCalculation, MoleRatio, Molecule, MoleculeKind, OxidationState, ReactionEntry,
28 ReactionSide, ReactionTerm, StoichiometricCoefficient, atomic_mass_by_symbol,
29 atomic_number_from_symbol, electron_shells, element_by_symbol, isotope_by_symbol,
30 period_for_atomic_number,
31 };
32
33 #[test]
34 fn facade_exposes_focused_crates() {
35 let oxygen = element_by_symbol("O").expect("oxygen should exist");
36 let formula = ChemicalFormula::parse("Ca(OH)2").expect("formula should parse");
37 let counts = formula.element_counts();
38 let water = Compound::new(
39 "water",
40 ChemicalFormula::parse("H2O").expect("water should parse"),
41 )
42 .expect("compound should be valid")
43 .with_kind(CompoundKind::Molecular);
44 let water_molecule = Molecule::new(
45 "water",
46 ChemicalFormula::parse("H2O").expect("water should parse"),
47 )
48 .expect("molecule should be valid")
49 .with_kind(MoleculeKind::Neutral);
50 let covalent_bond = Bond::new(BondKind::Covalent).with_order(BondOrder::Single);
51 let sodium_ion = Ion::new(
52 ChemicalFormula::parse("Na").expect("sodium should parse"),
53 IonCharge::positive(1).expect("charge should be valid"),
54 );
55 let iron_three = ElementOxidationState::new(
56 "Fe",
57 OxidationState::positive(3).expect("oxidation state should be valid"),
58 )
59 .expect("element oxidation state should be valid");
60 let water_entry = ReactionEntry::new(
61 StoichiometricCoefficient::new(2).expect("coefficient should be valid"),
62 ChemicalFormula::parse("H2O").expect("water should parse"),
63 ReactionSide::Product,
64 )
65 .expect("reaction entry should be valid");
66 let water_reaction = ChemicalReaction::new()
67 .with_reactant(
68 ReactionTerm::new(ChemicalFormula::parse("H2").expect("hydrogen should parse"))
69 .with_coefficient(2)
70 .expect("coefficient should be valid"),
71 )
72 .with_reactant(ReactionTerm::new(
73 ChemicalFormula::parse("O2").expect("oxygen should parse"),
74 ))
75 .with_product(
76 ReactionTerm::new(ChemicalFormula::parse("H2O").expect("water should parse"))
77 .with_coefficient(2)
78 .expect("coefficient should be valid"),
79 );
80 let water_ratio = MoleRatio::from_values(2, 1).expect("ratio should be valid");
81 let molar_mass_lookup = AtomicMassLookup::from_entries([
82 AtomicMassEntry::new("H", 1.008).expect("hydrogen mass should be valid"),
83 AtomicMassEntry::new("O", 15.999).expect("oxygen mass should be valid"),
84 ]);
85 let water_molar_mass = MolarMassCalculation::new(
86 ChemicalFormula::parse("H2O").expect("water should parse"),
87 molar_mass_lookup,
88 )
89 .calculate()
90 .expect("molar mass should calculate");
91
92 assert_eq!(oxygen.atomic_number, 8);
93 assert_eq!(covalent_bond.order(), Some(BondOrder::Single));
94 assert!(sodium_ion.is_cation());
95 assert_eq!(sodium_ion.to_string(), "Na+");
96 assert_eq!(iron_three.to_string(), "Fe(III)");
97 assert_eq!(water_entry.to_string(), "2H2O");
98 assert_eq!(water_reaction.to_string(), "2H2 + O2 -> 2H2O");
99 assert_eq!(water_ratio.to_string(), "2:1");
100 assert_eq!(water.name().as_str(), "water");
101 assert_eq!(water.formula().to_string(), "H2O");
102 assert_eq!(water_molecule.formula().to_string(), "H2O");
103 assert!((water_molar_mass.molar_mass().value() - 18.015).abs() < 0.001);
104 assert_eq!(counts.get("Ca"), Some(&1));
105 assert_eq!(counts.get("O"), Some(&2));
106 assert_eq!(counts.get("H"), Some(&2));
107 assert_eq!(atomic_number_from_symbol("Na"), Some(11));
108 assert!((atomic_mass_by_symbol("O").unwrap_or_default() - 15.999).abs() < 0.01);
109 assert_eq!(electron_shells(11), Some(vec![2, 8, 1]));
110 assert_eq!(
111 isotope_by_symbol("C", 14).map(|value| value.neutron_count()),
112 Some(8)
113 );
114 assert_eq!(period_for_atomic_number(11), Some(3));
115 }
116}