version_number/parsers/error.rs
1//! A module for a common error API.
2//! Individual parsers may implement their own, more detailed error type.
3//! This error type may be used with the convenience parse traits, [`ParseVersion`],
4//! [`ParseBase`] and [`ParseFull`].
5//!
6//! [`ParseVersion`]: crate::VersionParser
7//! [`ParseBase`]: crate::BaseVersionParser
8//! [`ParseFull`]: crate::FullVersionParser
9
10type Index = usize;
11
12///
13#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
14pub enum ParserError {
15 /// An error variant for fault when a some type of input, or none at all,
16 /// was expected next.
17 #[error(transparent)]
18 Expected(#[from] ExpectedError),
19
20 /// An error variant for faults when parsing and constructing a number.
21 #[error(transparent)]
22 Numeric(#[from] NumericError),
23}
24
25/// An error type for faults relating to parsing and expecting a certain type of
26/// token.
27#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
28pub enum ExpectedError {
29 /// When this error variant is returned, the `.` token, i.e. the separator, was expected, but
30 /// a different token was present. The `got` field shows the token read.
31 #[error("Expected dot token '.', but got '{}'{}.",
32 .got.map(String::from).unwrap_or_else(|| "EOI".to_string()),
33 .at.map(|i| format!(" at {}", i)).unwrap_or_default())
34 ]
35 Separator {
36 /// Place where the token was expected.
37 ///
38 /// May be `None` if the respective parser does not store the index.
39 at: Option<Index>,
40 /// Token found instead, or `None` if we unexpectedly got the end-of-input.
41 got: Option<char>,
42 },
43
44 /// When this error variant is returned, the parser expected that no more
45 /// tokens should be present, but instead 1 or more additional tokens
46 /// were not parsed yet.
47 ///
48 /// The `got` field contains the next token received, where
49 /// it expected none to be remaining.
50 #[error("Expected end of input, but got '{got}'{}.", .at.map(|i| format!(" at {}", i)).unwrap_or_default())]
51 EndOfInput {
52 /// Place where the end-of-input was expected.
53 ///
54 /// May be `None` if the respective parser does not store the index.
55 at: Option<Index>,
56 /// Character found at the expected end-of-input.
57 got: char,
58 },
59
60 /// When this error variant is returned, a numeric token was expected, but
61 /// a different token was present.
62 ///
63 /// The `got` field shows the token read.
64 #[error("Expected numeric token (0-9), but got '{}'{}.",
65 .got.map(String::from).unwrap_or_else(|| "EOI".to_string()),
66 .at.map(|i| format!(" at {}", i)).unwrap_or_default())
67 ]
68 Numeric {
69 /// Place where the token was expected.
70 ///
71 /// May be `None` if the respective parser does not store the index.
72 at: Option<Index>,
73 /// Token found instead, or `None` if we unexpectedly got the end-of-input.
74 got: Option<char>,
75 },
76}
77
78/// An error type for faults relating to parsing and constructing numbers.
79#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
80pub enum NumericError {
81 /// When this error variant is returned, the parser detected that the number started with a leading
82 /// zero, which is not allowed for number components.
83 #[error("Number may not start with a leading zero, unless the complete component is '0'")]
84 LeadingZero,
85
86 /// This error variant is returned if the number would overflow.
87 ///
88 /// Each number component consists of a 64 bits unsigned integer.
89 #[error("Overflow: Found number component which would be larger than the maximum supported number (max={})", u64::MAX)]
90 Overflow,
91}