eat_nom/
error.rs

1pub type EatResult<I> = std::result::Result<I, ErrorKind>;
2
3use std::num::ParseIntError;
4
5#[derive(Debug)]
6pub enum ErrorKind {
7    StringError(String),
8    NomError(String),
9    ParseIntError(ParseIntError),
10}
11
12impl std::fmt::Display for ErrorKind {
13    #[cfg_attr(tarpaulin, skip)]
14    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15        match &self {
16            ErrorKind::StringError(ref e) => e.fmt(f),
17            ErrorKind::NomError(ref e) => e.fmt(f),
18            ErrorKind::ParseIntError(ref e) => e.fmt(f),
19        }
20    }
21}
22
23impl std::error::Error for ErrorKind {
24    #[cfg_attr(tarpaulin, skip)]
25    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
26        match &self {
27            ErrorKind::StringError(ref _e) => None,
28            ErrorKind::NomError(ref _e) => None,
29            ErrorKind::ParseIntError(ref e) => Some(e),
30        }
31    }
32}
33
34impl From<std::net::AddrParseError> for ErrorKind {
35    #[cfg_attr(tarpaulin, skip)]
36    fn from(s: std::net::AddrParseError) -> Self {
37        ErrorKind::StringError(s.to_string())
38    }
39}
40
41impl From<ParseIntError> for ErrorKind {
42    #[cfg_attr(tarpaulin, skip)]
43    fn from(s: ParseIntError) -> Self {
44        ErrorKind::ParseIntError(s)
45    }
46}
47
48impl nom::error::ParseError<&str> for ErrorKind {
49    #[cfg_attr(tarpaulin, skip)]
50    fn from_error_kind(input: &str, kind: nom::error::ErrorKind) -> Self {
51        ErrorKind::NomError(format!("input:[{}],kind:[{:?}]", input, kind))
52    }
53
54    #[cfg_attr(tarpaulin, skip)]
55    fn append(_input: &str, _kind: nom::error::ErrorKind, other: Self) -> Self {
56        other
57    }
58}
59
60impl From<nom::Err<(&str, nom::error::ErrorKind)>> for ErrorKind {
61    #[cfg_attr(tarpaulin, skip)]
62    fn from(i: nom::Err<(&str, nom::error::ErrorKind)>) -> Self {
63        match i {
64            nom::Err::Error(err) | nom::Err::Failure(err) => {
65                ErrorKind::NomError(format!("input:[{}],kind:[{:?}]", err.0, err.1))
66            }
67            nom::Err::Incomplete(i) => {
68                ErrorKind::StringError(format!("nom parser Incomplete error: {:?}", i))
69            }
70        }
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use nom::bytes::complete::take_until;
78
79    #[test]
80    fn test_until_eof_ok() -> EatResult<()> {
81        fn until_eof(s: &str) -> nom::IResult<&str, &str> {
82            take_until("eof")(s)
83        }
84
85        let (x, y) = until_eof("hello, worldeof")?;
86        assert_eq!(x, "eof");
87        assert_eq!(y, "hello, world");
88        Ok(())
89    }
90
91    #[test]
92    fn test_until_eof_error() -> EatResult<()> {
93        fn until_eof(s: &str) -> nom::IResult<&str, &str> {
94            take_until("e1of")(s)
95        }
96
97        match until_eof("hello, worldeof") {
98            Err(_) => assert!(true),
99            _ => assert!(false),
100        }
101        Ok(())
102    }
103}