1use crate::parser::Span;
2use nom::Err;
3use nom::error::ErrorKind;
4use nom_language::error::{VerboseError, convert_error};
5use quick_error::quick_error;
6
7quick_error! {
8 #[derive(Debug, PartialEq, Eq)]
9 pub enum BibtexError {
10 Parsing (descr: String) {
11 display(me) -> ("Parsing error. Reason: {}", descr)
12 }
13 StringVariableNotFound (var: String) {
14 display(me) -> ("String variable not found: {}", var)
15 }
16 }
17}
18
19impl From<Err<(&str, ErrorKind)>> for BibtexError {
22 fn from(err: Err<(&str, ErrorKind)>) -> BibtexError {
23 let descr = match err {
24 Err::Incomplete(e) => format!("Incomplete: {:?}", e),
25 Err::Error((_, e)) | Err::Failure((_, e)) => e.description().into(),
26 };
27 BibtexError::Parsing(descr)
28 }
29}
30
31impl BibtexError {
32 pub fn with_context(input: &str, err: Err<VerboseError<Span>>) -> BibtexError {
33 let descr = match err {
34 Err::Incomplete(e) => format!("Incomplete: {:?}", e),
35 Err::Error(e) | Err::Failure(e) => {
36 let e_ = VerboseError {
39 errors: e
40 .errors
41 .into_iter()
42 .map(|(span, kind)| (*span.fragment(), kind))
43 .collect(),
44 };
45 convert_error(input, e_)
46 }
47 };
48 BibtexError::Parsing(descr)
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn test_display_impls() {
58 let err = BibtexError::Parsing("<some reason>".into());
59 assert_eq!(format!("{}", err), "Parsing error. Reason: <some reason>");
60
61 let err = BibtexError::StringVariableNotFound("<variable>".into());
62 assert_eq!(format!("{}", err), "String variable not found: <variable>");
63 }
64}