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