1use std::error;
2use std::fmt;
3use std::str;
4
5use nom::{Err, error::ErrorKind};
6
7#[derive(PartialEq, Eq, Debug, Clone)]
8#[non_exhaustive]
9pub enum Error {
10 ParseError(String),
11 GenerateError(String),
12 ValidationError(String),
13}
14
15impl fmt::Display for Error {
16 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17 match self {
18 Error::ParseError(s) | Error::GenerateError(s) | Error::ValidationError(s) => {
19 write!(f, "{s}")
20 }
21 }
22 }
23}
24
25impl error::Error for Error {}
26
27impl From<nom::error::Error<&str>> for Error {
28 fn from(err: nom::error::Error<&str>) -> Self {
29 Error::ParseError(format!("Parsing error: {err:?}"))
30 }
31}
32
33impl From<Err<nom::error::Error<&str>>> for Error {
34 fn from(err: Err<nom::error::Error<&str>>) -> Self {
35 Error::ParseError(format!("Parsing error: {err:?}"))
36 }
37}
38
39impl From<(&'_ str, ErrorKind)> for Error {
40 fn from(err: (&str, ErrorKind)) -> Self {
41 let string = format!("Parsing error: {:?}\n {:?}", err.1, err.0);
42 Error::ParseError(string)
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use crate::error::Error;
49 use nom::{Err, IResult, bytes::complete::tag};
50
51 fn give_error_kind(input: &str) -> IResult<&str, &str> {
52 let (input, _) = tag("1234")(input)?;
53 let (input, res) = tag("5678")(input)?;
54 Ok((input, res))
55 }
56
57 #[test]
58 fn gets_error_error() {
59 let nom_result = give_error_kind("12340");
60 assert!(matches!(nom_result, Err(Err::Error(_))));
61 }
62
63 #[test]
64 fn gets_error_on_incomplete() {
65 let nom_result = give_error_kind("").map_err(Error::from);
66 assert!(matches!(nom_result, Err(Error::ParseError(_))));
67 }
68
69 #[test]
70 fn uses_error_generate() {
71 let bnf_error = Error::GenerateError(String::from("error generating!"));
72 assert!(matches!(bnf_error, Error::GenerateError(_)));
73 }
74
75 #[test]
76 fn test_error_display() {
77 let parse_error = Error::ParseError(String::from("parsing error!"));
78 let generate_error = Error::GenerateError(String::from("error generating!"));
79 let validation_error = Error::ValidationError(String::from("validation error!"));
80
81 assert_eq!(parse_error.to_string(), String::from("parsing error!"));
82 assert_eq!(
83 generate_error.to_string(),
84 String::from("error generating!")
85 );
86 assert_eq!(
87 validation_error.to_string(),
88 String::from("validation error!")
89 );
90 }
91
92 #[test]
93 fn from_nom_verbose_error() {
94 let error = nom::error::Error::new("test", nom::error::ErrorKind::Tag);
95 assert!(matches!(Error::from(error), Error::ParseError(_)));
96 }
97
98 #[test]
99 fn from_str_and_nom_verbose_error_kind() {
100 let description = "anything";
101 let error_kind = nom::error::ErrorKind::Char;
102 assert!(matches!(
103 Error::from((description, error_kind)),
104 Error::ParseError(_)
105 ));
106 }
107
108 #[test]
109 fn clone_error() {
110 let error = Error::ParseError(String::from("parsing error!"));
111 let clone = error.clone();
112 assert_eq!(error, clone);
113 }
114
115 #[test]
116 fn from_nom_err_failure() {
117 let error = nom::error::Error::new("test", nom::error::ErrorKind::Tag);
118 let err = Err::Failure(error);
119 let bnf_error = Error::from(err);
120 assert!(matches!(bnf_error, Error::ParseError(_)));
121 assert!(bnf_error.to_string().contains("Parsing error:"));
122 }
123
124 #[test]
125 fn from_nom_err_incomplete() {
126 let err = Err::Incomplete(nom::Needed::Unknown);
127 let bnf_error = Error::from(err);
128 assert!(matches!(bnf_error, Error::ParseError(_)));
129 assert!(bnf_error.to_string().contains("Parsing error:"));
130 }
131
132 #[test]
133 fn error_trait_impl() {
134 let error = Error::ParseError(String::from("test"));
136 let error_ref: &dyn std::error::Error = &error;
137 assert_eq!(error_ref.to_string(), "test");
138 }
139}