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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
use failure_derive::*; use std::cmp::Ordering; #[derive(Debug, Clone, PartialEq, Fail)] pub enum ECode { #[fail(display = "BREAK -- {}", 0)] BREAK(Box<ECode>), #[fail(display = "End of Input")] EOF, #[fail(display = "This Error Should Never Happen: {}", 0)] Never(&'static str), #[fail(display = "{}", 0)] SMess(&'static str), #[fail(display = "{}", 0)] Mess(String), #[fail(display = "{}::{}", 0, 1)] Wrap(&'static str, Box<ParseError>), #[fail(display = "Error {} or {}", 0, 1)] Or(Box<ParseError>, Box<ParseError>), #[fail(display = "Expected {}, got {:?}", 0, 1)] Char(char, Option<char>), #[fail(display = "Expected a char in {:?}, got {:?}", 0, 1)] CharInStr(&'static str, char), #[fail(display = "Expected {:?}", 0)] Tag(&'static str), #[fail(display = "Require {} repeats, got only {} -- {}", 0, 1, 2)] Count(usize, usize, Box<ParseError>), #[fail(display = "Unexpected {}", 0)] UnexpectedChar(char), #[fail(display = "Char Expected {:?} - got{:?}", 0, 1)] CharExpected(crate::chars::Expected, Option<char>), #[fail(display = "Failon {:?}", 0)] FailOn(String), } impl ECode { pub fn brk(self) -> Self { ECode::BREAK(Box::new(self)) } } #[derive(Debug, Clone, PartialEq, Fail)] #[fail(display = "Parse Error at {},{}: {}", line, col, code)] pub struct ParseError { pub code: ECode, pub line: usize, pub col: usize, } impl ParseError { pub fn new(s: &'static str, line: usize, col: usize) -> ParseError { ParseError { code: ECode::SMess(s), line, col, } } pub fn code(code: ECode, line: usize, col: usize) -> ParseError { ParseError { code, line, col } } pub fn is_break(&self) -> bool { match self.code { ECode::BREAK(_) => true, _ => false, } } pub fn brk(self) -> Self { ParseError { code: self.code.brk(), line: self.line, col: self.col, } } } impl PartialOrd for ParseError { fn partial_cmp(&self, b: &Self) -> Option<Ordering> { if self.line == b.line { return self.col.partial_cmp(&b.col); } self.line.partial_cmp(&self.line) } }