1 //! Define the `Location`, `ParseError`, and `ParseResult` types.
2 
3 #![macro_use]
4 
5 use std::fmt;
6 
7 /// The location of a `Token` or `Error`.
8 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9 pub struct Location {
10     /// Line number. Command-line arguments are line 0 and source file
11     /// lines start from 1.
12     pub line_number: usize,
13 }
14 
15 /// A parse error is returned when the parse failed.
16 #[derive(Debug)]
17 pub struct ParseError {
18     /// Location of the error.
19     pub location: Location,
20     /// Error message.
21     pub message: String,
22     /// Whether it's a warning or a plain error.
23     pub is_warning: bool,
24 }
25 
26 impl fmt::Display for ParseError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result27     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28         if self.location.line_number == 0 {
29             write!(f, "command-line arguments: {}", self.message)
30         } else {
31             write!(f, "{}: {}", self.location.line_number, self.message)
32         }
33     }
34 }
35 
36 impl std::error::Error for ParseError {}
37 
38 /// Result of a parser operation. The `ParseError` variant includes a location.
39 pub type ParseResult<T> = Result<T, ParseError>;
40 
41 // Create an `Err` variant of `ParseResult<X>` from a location and `format!` args.
42 macro_rules! err {
43     ( $loc:expr, $msg:expr ) => {
44         Err($crate::ParseError {
45             location: $loc.clone(),
46             message: $msg.to_string(),
47             is_warning: false,
48         })
49     };
50 
51     ( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => {
52         Err($crate::ParseError {
53             location: $loc.clone(),
54             message: format!( $fmt, $( $arg ),+ ),
55             is_warning: false,
56         })
57     };
58 }
59 
60 macro_rules! warn {
61     ( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => {
62         Err($crate::ParseError {
63             location: $loc.clone(),
64             message: format!($fmt, $( $arg ),+ ),
65             is_warning: true,
66         })
67     };
68 }
69