use_molar_mass/
mass_contribution_set.rs1use std::fmt;
2
3use crate::{ElementMassContribution, MolarMass, MolarMassValidationError};
4
5#[derive(Clone, Debug, Default, PartialEq)]
7pub struct MassContributionSet {
8 contributions: Vec<ElementMassContribution>,
9}
10
11impl MassContributionSet {
12 #[must_use]
14 pub const fn new() -> Self {
15 Self {
16 contributions: Vec::new(),
17 }
18 }
19
20 #[must_use]
22 pub fn from_contributions(
23 contributions: impl IntoIterator<Item = ElementMassContribution>,
24 ) -> Self {
25 Self {
26 contributions: contributions.into_iter().collect(),
27 }
28 }
29
30 pub fn push(&mut self, contribution: ElementMassContribution) {
32 self.contributions.push(contribution);
33 }
34
35 #[must_use]
37 pub fn as_slice(&self) -> &[ElementMassContribution] {
38 &self.contributions
39 }
40
41 pub fn iter(&self) -> impl Iterator<Item = &ElementMassContribution> {
43 self.contributions.iter()
44 }
45
46 #[must_use]
48 pub fn len(&self) -> usize {
49 self.contributions.len()
50 }
51
52 #[must_use]
54 pub fn is_empty(&self) -> bool {
55 self.contributions.is_empty()
56 }
57
58 #[must_use]
60 pub fn total_mass_value(&self) -> f64 {
61 self.contributions
62 .iter()
63 .map(ElementMassContribution::total_mass_value)
64 .sum()
65 }
66
67 pub fn molar_mass(&self) -> Result<MolarMass, MolarMassValidationError> {
73 MolarMass::grams_per_mole(self.total_mass_value())
74 }
75}
76
77impl fmt::Display for MassContributionSet {
78 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
79 for (index, contribution) in self.contributions.iter().enumerate() {
80 if index > 0 {
81 formatter.write_str(", ")?;
82 }
83
84 write!(formatter, "{contribution}")?;
85 }
86
87 Ok(())
88 }
89}