Skip to main content

use_stoichiometry/
term.rs

1use std::fmt;
2
3use use_chemical_formula::ChemicalFormula;
4
5use crate::{StoichiometricCoefficient, StoichiometryValidationError};
6
7/// A stoichiometric coefficient paired with a formula.
8#[derive(Clone, Debug, Eq, PartialEq)]
9pub struct StoichiometricTerm {
10    coefficient: StoichiometricCoefficient,
11    formula: ChemicalFormula,
12}
13
14impl StoichiometricTerm {
15    /// Creates a stoichiometric term from validated parts.
16    ///
17    /// # Errors
18    ///
19    /// Returns [`StoichiometryValidationError::ZeroCoefficient`] if the coefficient is
20    /// structurally invalid.
21    pub fn new(
22        coefficient: StoichiometricCoefficient,
23        formula: ChemicalFormula,
24    ) -> Result<Self, StoichiometryValidationError> {
25        if coefficient.value() == 0 {
26            Err(StoichiometryValidationError::ZeroCoefficient)
27        } else {
28            Ok(Self {
29                coefficient,
30                formula,
31            })
32        }
33    }
34
35    /// Creates a stoichiometric term from a raw coefficient value.
36    ///
37    /// # Errors
38    ///
39    /// Returns [`StoichiometryValidationError::ZeroCoefficient`] when `coefficient` is zero.
40    pub fn from_value(
41        coefficient: u32,
42        formula: ChemicalFormula,
43    ) -> Result<Self, StoichiometryValidationError> {
44        Self::new(StoichiometricCoefficient::new(coefficient)?, formula)
45    }
46
47    /// Returns the coefficient.
48    #[must_use]
49    pub const fn coefficient(&self) -> StoichiometricCoefficient {
50        self.coefficient
51    }
52
53    /// Returns the formula.
54    #[must_use]
55    pub const fn formula(&self) -> &ChemicalFormula {
56        &self.formula
57    }
58
59    /// Consumes the term and returns its parts.
60    #[must_use]
61    pub fn into_parts(self) -> (StoichiometricCoefficient, ChemicalFormula) {
62        (self.coefficient, self.formula)
63    }
64}
65
66impl fmt::Display for StoichiometricTerm {
67    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
68        if self.coefficient.is_one() {
69            write!(formatter, "{}", self.formula)
70        } else {
71            write!(formatter, "{}{}", self.coefficient, self.formula)
72        }
73    }
74}