Skip to main content

nbf/parser/
error.rs

1//! Module containing the error definitions of the parser.
2
3use std::error::Error;
4use std::fmt::{
5    Display,
6    Formatter,
7    Result,
8};
9
10/// A parsing error which indicates its line of origin in the text as well as
11/// the type of error.
12#[ derive( Debug ) ]
13pub struct ParsingError<ExternalErrorType>
14where
15    ExternalErrorType: Display + Error {
16
17    line: usize,
18    keyword: ParsingErrorType<ExternalErrorType>
19}
20
21impl<ExternalErrorType> ParsingError<ExternalErrorType>
22where
23    ExternalErrorType: Display + Error {
24
25    pub fn new(
26        line: usize,
27        keyword: ParsingErrorType<ExternalErrorType>
28    ) -> ParsingError<ExternalErrorType> {
29        ParsingError {
30            line,
31            keyword
32        }
33    }
34}
35
36impl<ExternalErrorType> Error for ParsingError<ExternalErrorType>
37where
38    ExternalErrorType: Display + Error + 'static {
39
40    fn source( &self ) -> Option< &( dyn Error + 'static ) > {
41        if let ParsingErrorType::External( external_error ) = &self.keyword {
42            Some( external_error )
43        } else {
44            None
45        }
46    }
47}
48
49/// Allows for simple printing of error information.
50impl<ExternalErrorType> Display for ParsingError<ExternalErrorType>
51where
52    ExternalErrorType: Display + Error {
53
54    fn fmt( &self, f: &mut Formatter<'_> ) -> Result {
55        write!( f,
56            "Error in line {}: {}",
57            // Convert zero-based line to line counting common in text editors.
58            self.line + 1,
59            self.keyword,
60        )
61    }
62}
63
64/// The type of a parsing error.
65#[ derive( Debug ) ]
66pub enum ParsingErrorType<ExternalErrorType>
67where
68    ExternalErrorType: Display + Error {
69
70    /// Only one kind of curly brakets is allowed per line, which has been
71    /// violated when this variant occurs.
72    BothBraketsInLine,
73    /// A closing braket has been found where it was not expected.
74    IsolatedClosingBraket,
75    /// A colon is missing between type and name of an element.
76    MissingColon,
77    /// Type unknown to its parent.
78    UnknownKeyword( String ),
79    /// Missing child keyword.
80    MissingChild( String ),
81    /// Failed to parse a value.
82    FailedParsingValue,
83    /// A custom type for handling parsing errors.
84    External( ExternalErrorType ),
85}
86
87/// Allows for simple printing of error information.
88impl<ExternalErrorType> Display for ParsingErrorType<ExternalErrorType>
89where
90    ExternalErrorType: Display + Error {
91
92    fn fmt( &self, f: &mut Formatter<'_> ) -> Result {
93        
94        if let ParsingErrorType::External( custom_error ) = self {
95            Display::fmt( custom_error, f )?
96        }
97
98        write!( f, "{}",
99            match self {
100                ParsingErrorType::BothBraketsInLine =>
101                    "Only an opening or a closing braket is allowed in a single line."
102                        .to_owned(),
103                ParsingErrorType::IsolatedClosingBraket =>
104                    "Found an orphaned closing braket, for which no opening braket exists."
105                        .to_owned(),
106                ParsingErrorType::MissingColon =>
107                    "A colon between the keyword and value is missing."
108                        .to_owned(),
109                ParsingErrorType::UnknownKeyword( keyword ) =>
110                    format!(
111                        "Unknown keyword: \"{}\"",
112                        keyword,
113                    ),
114                ParsingErrorType::MissingChild( keyword ) =>
115                    format!(
116                        "The keyword \"{}\" is missing.",
117                        keyword,
118                    ),
119                ParsingErrorType::FailedParsingValue =>
120                    "Failed to parse the given value."
121                        .to_owned(),
122                // Handled above already, because writing to the already mutably
123                // borrowed formatter `f` here is not possible.
124                ParsingErrorType::External( _ ) =>
125                    "".to_owned(),
126            }
127        )
128    }
129}
130