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
// This is free and unencumbered software released into the public domain.

use crate::prelude::{fmt, String, ToString, Vec};
use crate::{SyntaxError, SyntaxErrorKind};

#[cfg(feature = "std")]
extern crate std;

pub type ParseResult<T, E = ParseError> = Result<T, E>;

#[derive(Clone, Debug, PartialEq)]
pub enum ParseError {
    #[cfg(feature = "std")]
    Io(std::io::ErrorKind),
    Syntax(Vec<(SyntaxErrorKind, String)>),
    Other(String),
}

impl fmt::Display for ParseError {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ParseError::Io(kind) => write!(fmt, "IO error: {:?}", kind),
            ParseError::Syntax(error) => write!(fmt, "Syntax error: {:?}", error),
            ParseError::Other(error) => write!(fmt, "Other error: {:?}", error),
        }
    }
}

#[cfg(feature = "std")]
impl From<std::io::Error> for ParseError {
    fn from(error: std::io::Error) -> Self {
        ParseError::Io(error.kind())
    }
}

impl<'a> From<nom::Err<SyntaxError<'a>>> for ParseError {
    fn from(err: nom::Err<SyntaxError<'a>>) -> Self {
        match err {
            nom::Err::Error(error) | nom::Err::Failure(error) => ParseError::from(error),
            nom::Err::Incomplete(_) => unreachable!(),
        }
    }
}

impl<'a> From<SyntaxError<'a>> for ParseError {
    fn from(error: SyntaxError<'a>) -> Self {
        ParseError::Syntax(
            error
                .errors
                .iter()
                .map(|(kind, span)| (kind.clone(), span.to_string()))
                .collect(),
        )
    }
}