use crate::chemistry::ChemicalElement;
use crate::tokens::Element;
#[derive(Clone, Debug, PartialEq)]
pub struct Component {
chemical_element: ChemicalElement,
atoms_count: usize,
mass_percent: f32,
}
impl Component {
pub(crate) fn from(element: Element) -> Self {
Self {
chemical_element: element.chemical_element(),
atoms_count: element.subscript() as usize,
mass_percent: 0.0,
}
}
pub(crate) fn add_atoms(&mut self, atoms_count: usize) {
self.atoms_count += atoms_count;
}
pub(crate) fn calculate_mass_percent(&mut self, compound_mass: f32) {
self.mass_percent = self.mass() / compound_mass * 100.;
}
pub fn mass(&self) -> f32 {
self.chemical_element.atomic_weight() * self.atoms_count as f32
}
pub fn mass_percent(&self) -> f32 {
self.mass_percent
}
pub fn chemical_element(&self) -> ChemicalElement {
self.chemical_element
}
pub fn atoms_count(&self) -> usize {
self.atoms_count
}
}
#[cfg(test)]
mod tests {
use super::{ChemicalElement, Component, Element};
#[test]
fn mass_calculation() {
let mut component = Component::from(Element::from("S", 2));
assert_eq!(
component.mass(),
ChemicalElement::Sulfur.atomic_weight() * 2.
);
component.add_atoms(3);
assert_eq!(
component.mass(),
ChemicalElement::Sulfur.atomic_weight() * 5.
);
component.add_atoms(4);
assert_eq!(
component.mass(),
ChemicalElement::Sulfur.atomic_weight() * 9.
);
}
#[test]
fn mass_percent_calculation() {
const MAGNESIUM_SULFATE_MOLAR_MASS: f32 = 246.466;
const SULFUR_PERCENTAGE_IN_MAGNESIUM_SULFATE: f32 = 13.007879;
let mut component = Component::from(Element::from("S", 1));
component.calculate_mass_percent(MAGNESIUM_SULFATE_MOLAR_MASS);
assert_eq!(
component.mass_percent(),
SULFUR_PERCENTAGE_IN_MAGNESIUM_SULFATE
);
}
}