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}