use_chemical_formula/
formula_term.rs1use std::collections::BTreeMap;
2use std::fmt;
3
4use crate::{ElementCount, ElementSymbol, FormulaGroup};
5
6#[derive(Clone, Debug, Eq, PartialEq)]
8pub enum FormulaTerm {
9 Element {
11 symbol: ElementSymbol,
13 count: ElementCount,
15 },
16 Group(FormulaGroup),
18}
19
20impl FormulaTerm {
21 #[must_use]
23 pub const fn element(symbol: ElementSymbol, count: ElementCount) -> Self {
24 Self::Element { symbol, count }
25 }
26
27 #[must_use]
29 pub const fn group(group: FormulaGroup) -> Self {
30 Self::Group(group)
31 }
32
33 pub(crate) fn add_counts(&self, counts: &mut BTreeMap<String, u64>, multiplier: u64) {
34 match self {
35 Self::Element { symbol, count } => {
36 let amount = u64::from(count.get()).saturating_mul(multiplier);
37 let entry = counts.entry(symbol.as_str().to_owned()).or_insert(0);
38 *entry = entry.saturating_add(amount);
39 },
40 Self::Group(group) => group.add_counts(counts, multiplier),
41 }
42 }
43}
44
45impl fmt::Display for FormulaTerm {
46 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
47 match self {
48 Self::Element { symbol, count } => {
49 write!(formatter, "{symbol}")?;
50 if !count.is_one() {
51 write!(formatter, "{count}")?;
52 }
53 Ok(())
54 },
55 Self::Group(group) => write!(formatter, "{group}"),
56 }
57 }
58}