version_number/parsers/modular/
error.rs

1use crate::parsers::error::ExpectedError;
2use crate::parsers::NumericError;
3use crate::ParserError;
4
5/// Errors which may be returned during parsing, by the _modular parser_.
6#[derive(Clone, Debug, thiserror::Error, Eq, PartialEq)]
7pub enum ModularParserError {
8    // /// Expected input token(s) for currently being parsed token, but got nothing.
9    // NoInputForComponent,
10    // /// Expected end of input, but got more tokens.
11    // ExpectedEOI,
12    /// When this error variant is returned, the parser expected that no more
13    /// tokens should be present, but instead 1 or more additional tokens
14    /// were not parsed yet.
15    ///
16    #[error("Expected end of input after parsing third version number component, but got: '{}'", char::from(*.got))]
17    ExpectedEndOfInput {
18        /// An additional token still present when the parser was expected to have
19        /// reached the end-of-input for the given input.
20        got: u8,
21    },
22
23    /// When this error variant is returned, the '.' token was expected, but
24    /// a different token was present, or the end-of-input reached.
25    ///
26    /// The `got` field shows the token read.
27    #[error(
28        "Expected the dot-separator '.', but got '{}'",
29        .got.map(|c| String::from(char::from(c))).unwrap_or_else(|| "EOI".to_string()),
30    )]
31    ExpectedSeparator {
32        /// Token read, or `None` if we unexpectedly got the end-of-input.
33        got: Option<u8>,
34    },
35
36    /// When this error variant is returned, a numeric token was expected, but
37    /// a different token was present, or the end-of-input reached.
38    #[error(
39        "Expected 0-9, but got '{}'",
40        .got.map(|c| String::from(char::from(c))).unwrap_or_else(|| "EOI".to_string()),
41    )]
42    ExpectedNumericToken {
43        /// Token read, or `None` if we unexpectedly got the end-of-input.
44        got: Option<u8>,
45    },
46
47    /// An error variant for faults when parsing and constructing a number.
48    #[error(transparent)]
49    NumberError(#[from] NumberError),
50}
51
52/// An error type for faults relating to parsing and constructing numbers.
53#[derive(Clone, Debug, thiserror::Error, Eq, PartialEq)]
54pub enum NumberError {
55    /// When this error variant is returned, the parser detected that the number started with a leading
56    /// zero, which is not allowed for number components.
57    #[error("Number may not start with a leading zero, unless the complete component is '0'")]
58    LeadingZero,
59
60    /// This error variant is returned if the number would overflow.
61    ///
62    /// Each number component consists of a 64 bits unsigned integer.
63    #[error("Overflow: Found number component which would be larger than the maximum supported number (max={})", u64::MAX)]
64    Overflow,
65}
66
67impl From<ModularParserError> for ParserError {
68    fn from(value: ModularParserError) -> Self {
69        match value {
70            ModularParserError::ExpectedEndOfInput { got } => {
71                ParserError::Expected(ExpectedError::EndOfInput {
72                    at: None,
73                    got: char::from(got),
74                })
75            }
76            ModularParserError::ExpectedNumericToken { got } => {
77                ParserError::Expected(ExpectedError::Numeric {
78                    at: None,
79                    got: got.map(char::from),
80                })
81            }
82            ModularParserError::ExpectedSeparator { got } => {
83                ParserError::Expected(ExpectedError::Separator {
84                    at: None,
85                    got: got.map(char::from),
86                })
87            }
88            ModularParserError::NumberError(e) => match e {
89                NumberError::LeadingZero => ParserError::Numeric(NumericError::LeadingZero),
90                NumberError::Overflow => ParserError::Numeric(NumericError::Overflow),
91            },
92        }
93    }
94}