nom_bibtex/
error.rs

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
19// We cannot use the from() from quick_error, because we need to put lifetimes that we didn't
20// define.
21impl 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                // Convert_error does not like spans, so we need to
37                // convert the error
38                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}