use crate::parser::Span;
use nom::Err;
use nom::error::ErrorKind;
use nom_language::error::{VerboseError, convert_error};
use quick_error::quick_error;
quick_error! {
#[derive(Debug, PartialEq, Eq)]
pub enum BibtexError {
Parsing (descr: String) {
display(me) -> ("Parsing error. Reason: {}", descr)
}
StringVariableNotFound (var: String) {
display(me) -> ("String variable not found: {}", var)
}
}
}
impl From<Err<(&str, ErrorKind)>> for BibtexError {
fn from(err: Err<(&str, ErrorKind)>) -> BibtexError {
let descr = match err {
Err::Incomplete(e) => format!("Incomplete: {:?}", e),
Err::Error((_, e)) | Err::Failure((_, e)) => e.description().into(),
};
BibtexError::Parsing(descr)
}
}
impl BibtexError {
pub fn with_context(input: &str, err: Err<VerboseError<Span>>) -> BibtexError {
let descr = match err {
Err::Incomplete(e) => format!("Incomplete: {:?}", e),
Err::Error(e) | Err::Failure(e) => {
let e_ = VerboseError {
errors: e
.errors
.into_iter()
.map(|(span, kind)| (*span.fragment(), kind))
.collect(),
};
convert_error(input, e_)
}
};
BibtexError::Parsing(descr)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_display_impls() {
let err = BibtexError::Parsing("<some reason>".into());
assert_eq!(format!("{}", err), "Parsing error. Reason: <some reason>");
let err = BibtexError::StringVariableNotFound("<variable>".into());
assert_eq!(format!("{}", err), "String variable not found: <variable>");
}
}