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 } 23 24 impl fmt::Display for ParseError { 25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 26 if self.location.line_number == 0 { 27 write!(f, "command-line arguments: {}", self.message) 28 } else { 29 write!(f, "{}: {}", self.location.line_number, self.message) 30 } 31 } 32 } 33 34 /// Result of a parser operation. The `ParseError` variant includes a location. 35 pub type ParseResult<T> = Result<T, ParseError>; 36 37 // Create an `Err` variant of `ParseResult<X>` from a location and `format!` args. 38 macro_rules! err { 39 ( $loc:expr, $msg:expr ) => { 40 Err($crate::ParseError { 41 location: $loc.clone(), 42 message: $msg.to_string(), 43 }) 44 }; 45 46 ( $loc:expr, $fmt:expr, $( $arg:expr ),+ ) => { 47 Err($crate::ParseError { 48 location: $loc.clone(), 49 message: format!( $fmt, $( $arg ),+ ), 50 }) 51 }; 52 } 53