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}