Skip to main content

use_chemical_formula/
error.rs

1use std::error::Error;
2use std::fmt;
3
4/// Errors returned while parsing a formula string.
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub enum FormulaParseError {
7    /// The input is empty or whitespace only.
8    EmptyFormula,
9    /// A formula part has no terms.
10    EmptyPart,
11    /// A parenthesized group has no terms.
12    EmptyGroup,
13    /// An element symbol does not match the supported shape.
14    InvalidSymbol(String),
15    /// A numeric count or multiplier could not be represented.
16    InvalidNumber(String),
17    /// An element count was zero.
18    ZeroCount,
19    /// A group or hydrate multiplier was zero.
20    ZeroMultiplier,
21    /// The parser encountered an unexpected character.
22    UnexpectedCharacter(char),
23    /// The input ended while a construct was still open.
24    UnexpectedEnd,
25    /// A group was opened but not closed.
26    UnmatchedOpenGroup,
27    /// A closing parenthesis appeared without a matching opening parenthesis.
28    UnmatchedCloseGroup,
29    /// A hydrate separator appeared at the end of the formula.
30    TrailingSeparator,
31}
32
33impl fmt::Display for FormulaParseError {
34    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
35        match self {
36            Self::EmptyFormula => formatter.write_str("formula is empty"),
37            Self::EmptyPart => formatter.write_str("formula part is empty"),
38            Self::EmptyGroup => formatter.write_str("formula group is empty"),
39            Self::InvalidSymbol(symbol) => write!(formatter, "invalid element symbol: {symbol}"),
40            Self::InvalidNumber(number) => write!(formatter, "invalid formula number: {number}"),
41            Self::ZeroCount => formatter.write_str("element count must be greater than zero"),
42            Self::ZeroMultiplier => {
43                formatter.write_str("formula multiplier must be greater than zero")
44            },
45            Self::UnexpectedCharacter(character) => {
46                write!(formatter, "unexpected character in formula: {character}")
47            },
48            Self::UnexpectedEnd => formatter.write_str("unexpected end of formula"),
49            Self::UnmatchedOpenGroup => {
50                formatter.write_str("formula group is missing a closing parenthesis")
51            },
52            Self::UnmatchedCloseGroup => {
53                formatter.write_str("formula has an unmatched closing parenthesis")
54            },
55            Self::TrailingSeparator => {
56                formatter.write_str("hydrate separator must be followed by a formula part")
57            },
58        }
59    }
60}
61
62impl Error for FormulaParseError {}
63
64/// Errors returned when constructing formula values directly.
65#[derive(Clone, Debug, Eq, PartialEq)]
66pub enum FormulaValidationError {
67    /// A term list is empty.
68    EmptyTerms,
69    /// A formula part has no terms.
70    EmptyPart,
71    /// A group has no terms.
72    EmptyGroup,
73    /// An element symbol does not match the supported shape.
74    InvalidSymbol(String),
75    /// An element count was zero.
76    ZeroCount,
77    /// A group or hydrate multiplier was zero.
78    ZeroMultiplier,
79}
80
81impl fmt::Display for FormulaValidationError {
82    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
83        match self {
84            Self::EmptyTerms => formatter.write_str("formula term list is empty"),
85            Self::EmptyPart => formatter.write_str("formula part is empty"),
86            Self::EmptyGroup => formatter.write_str("formula group is empty"),
87            Self::InvalidSymbol(symbol) => write!(formatter, "invalid element symbol: {symbol}"),
88            Self::ZeroCount => formatter.write_str("element count must be greater than zero"),
89            Self::ZeroMultiplier => {
90                formatter.write_str("formula multiplier must be greater than zero")
91            },
92        }
93    }
94}
95
96impl Error for FormulaValidationError {}
97
98impl From<FormulaValidationError> for FormulaParseError {
99    fn from(error: FormulaValidationError) -> Self {
100        match error {
101            FormulaValidationError::EmptyTerms | FormulaValidationError::EmptyPart => {
102                Self::EmptyPart
103            },
104            FormulaValidationError::EmptyGroup => Self::EmptyGroup,
105            FormulaValidationError::InvalidSymbol(symbol) => Self::InvalidSymbol(symbol),
106            FormulaValidationError::ZeroCount => Self::ZeroCount,
107            FormulaValidationError::ZeroMultiplier => Self::ZeroMultiplier,
108        }
109    }
110}