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
18impl 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 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}