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