pear/
error.rs

1use crate::input::{Show, ParserInfo};
2
3pub use crate::expected::Expected;
4
5#[derive(Debug, Clone)]
6pub struct ParseError<C, E> {
7    pub error: E,
8    pub info: ErrorInfo<C>,
9    pub stack: Vec<ErrorInfo<C>>,
10}
11
12#[derive(Debug, Clone)]
13pub struct ErrorInfo<C> {
14    pub parser: ParserInfo,
15    pub context: C,
16}
17
18impl<C> ErrorInfo<C> {
19    pub fn new(parser: ParserInfo, context: C) -> Self {
20        Self { parser, context }
21    }
22}
23
24impl<C, E> ParseError<C, E> {
25    pub fn new(parser: ParserInfo, error: E, context: C) -> ParseError<C, E> {
26        ParseError { error, info: ErrorInfo::new(parser, context), stack: vec![] }
27    }
28
29    pub fn push_info(&mut self, parser: ParserInfo, context: C) {
30        self.stack.push(ErrorInfo::new(parser, context));
31    }
32
33    #[inline(always)]
34    pub fn into<E2: From<E>>(self) -> ParseError<C, E2> {
35        ParseError {
36            error: self.error.into(),
37            info: self.info,
38            stack: self.stack,
39        }
40    }
41}
42
43impl<C: Show, E: std::fmt::Display> std::fmt::Display for ParseError<C, E> {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        #[cfg(feature = "color")] yansi::disable();
46        write!(f, "{} ({})", self.error, &self.info.context as &dyn Show)?;
47        #[cfg(feature = "color")] yansi::whenever(yansi::Condition::DEFAULT);
48
49        for info in &self.stack {
50            write!(f, "\n + {}", info.parser.name)?;
51            write!(f, " {}", &info.context as &dyn Show)?;
52        }
53
54        Ok(())
55    }
56}