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}