Skip to main content

use_stoichiometry/
ratio.rs

1use std::fmt;
2
3use crate::{StoichiometricCoefficient, StoichiometryValidationError};
4
5/// A ratio between two stoichiometric coefficients.
6#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub struct StoichiometricRatio {
8    numerator: StoichiometricCoefficient,
9    denominator: StoichiometricCoefficient,
10}
11
12impl StoichiometricRatio {
13    /// Creates a stoichiometric ratio from validated coefficients.
14    ///
15    /// # Errors
16    ///
17    /// Returns [`StoichiometryValidationError::ZeroRatioDenominator`] if the denominator
18    /// is structurally invalid.
19    pub const fn new(
20        numerator: StoichiometricCoefficient,
21        denominator: StoichiometricCoefficient,
22    ) -> Result<Self, StoichiometryValidationError> {
23        if denominator.value() == 0 {
24            Err(StoichiometryValidationError::ZeroRatioDenominator)
25        } else {
26            Ok(Self {
27                numerator,
28                denominator,
29            })
30        }
31    }
32
33    /// Creates a stoichiometric ratio from raw coefficient values.
34    ///
35    /// # Errors
36    ///
37    /// Returns [`StoichiometryValidationError::ZeroRatioDenominator`] when `denominator`
38    /// is zero, or [`StoichiometryValidationError::ZeroCoefficient`] when `numerator` is
39    /// zero.
40    pub const fn from_values(
41        numerator: u32,
42        denominator: u32,
43    ) -> Result<Self, StoichiometryValidationError> {
44        if denominator == 0 {
45            return Err(StoichiometryValidationError::ZeroRatioDenominator);
46        }
47
48        let numerator = match StoichiometricCoefficient::new(numerator) {
49            Ok(numerator) => numerator,
50            Err(error) => return Err(error),
51        };
52        let denominator = match StoichiometricCoefficient::new(denominator) {
53            Ok(denominator) => denominator,
54            Err(error) => return Err(error),
55        };
56
57        Self::new(numerator, denominator)
58    }
59
60    /// Returns the numerator coefficient.
61    #[must_use]
62    pub const fn numerator(self) -> StoichiometricCoefficient {
63        self.numerator
64    }
65
66    /// Returns the denominator coefficient.
67    #[must_use]
68    pub const fn denominator(self) -> StoichiometricCoefficient {
69        self.denominator
70    }
71}
72
73impl fmt::Display for StoichiometricRatio {
74    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
75        write!(formatter, "{}:{}", self.numerator, self.denominator)
76    }
77}