1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
use std::{error::Error, fmt, io}; type NomError<'a> = nom::Err<nom::types::CompleteStr<'a>>; #[derive(Debug)] pub enum ParseError { Generic, FileNotFound, Syntax { line_num: usize, message: String }, } impl fmt::Display for ParseError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { ParseError::Syntax { line_num, message } => { write!(f, "{} on line {}: {}", self.as_str(), line_num, message) } _ => write!(f, "{}", self.as_str()), } } } impl Error for ParseError { fn description(&self) -> &str { self.as_str() } } impl From<io::Error> for ParseError { fn from(e: io::Error) -> Self { match e.kind() { io::ErrorKind::NotFound => ParseError::FileNotFound, _ => ParseError::Generic, } } } impl ParseError { pub(crate) fn from_nom(line_num: usize, err: NomError) -> ParseError { ParseError::Syntax { line_num, message: err.to_string(), } } fn as_str(&self) -> &str { match self { ParseError::Generic => "parser error", ParseError::FileNotFound => "no such file or directory", ParseError::Syntax { .. } => "syntax error", } } }