nom_bibtex/
error.rs

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