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 {
27     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 /// Result of a parser operation. The `ParseError` variant includes a location.
37 pub type ParseResult<T> = Result<T, ParseError>;
38 
39 // Create an `Err` variant of `ParseResult<X>` from a location and `format!` args.
40 macro_rules! err {
41     ( $loc:expr, $msg:expr ) => {
42         Err($crate::ParseError {
43             location: $loc.clone(),
44             message: $msg.to_string(),
45             is_warning: false,
46         })
47     };
48 
49     ( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => {
50         Err($crate::ParseError {
51             location: $loc.clone(),
52             message: format!( $fmt, $( $arg ),+ ),
53             is_warning: false,
54         })
55     };
56 }
57 
58 macro_rules! warn {
59     ( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => {
60         Err($crate::ParseError {
61             location: $loc.clone(),
62             message: format!($fmt, $( $arg ),+ ),
63             is_warning: true,
64         })
65     };
66 }
67