use std::collections::BTreeMap;
use std::fmt;
use crate::{ElementCount, ElementSymbol, FormulaGroup};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum FormulaTerm {
Element {
symbol: ElementSymbol,
count: ElementCount,
},
Group(FormulaGroup),
}
impl FormulaTerm {
#[must_use]
pub const fn element(symbol: ElementSymbol, count: ElementCount) -> Self {
Self::Element { symbol, count }
}
#[must_use]
pub const fn group(group: FormulaGroup) -> Self {
Self::Group(group)
}
pub(crate) fn add_counts(&self, counts: &mut BTreeMap<String, u64>, multiplier: u64) {
match self {
Self::Element { symbol, count } => {
let amount = u64::from(count.get()).saturating_mul(multiplier);
let entry = counts.entry(symbol.as_str().to_owned()).or_insert(0);
*entry = entry.saturating_add(amount);
},
Self::Group(group) => group.add_counts(counts, multiplier),
}
}
}
impl fmt::Display for FormulaTerm {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Element { symbol, count } => {
write!(formatter, "{symbol}")?;
if !count.is_one() {
write!(formatter, "{count}")?;
}
Ok(())
},
Self::Group(group) => write!(formatter, "{group}"),
}
}
}