systemd_parser/
errors.rs

1
2use nom;
3use std::convert::From;
4use std::fmt;
5use std::error::Error;
6
7#[derive(Clone, Debug, Eq, PartialEq)]
8pub struct ParseErrorInternal(String, u32);
9
10impl From<(String, u32)> for ParseErrorInternal {
11    fn from(error_tuple: (String, u32)) -> ParseErrorInternal {
12        ParseErrorInternal(error_tuple.0, error_tuple.1)
13    }
14}
15
16impl fmt::Display for ParseErrorInternal {
17    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18        writeln!(f, "line {}: {}", self.1, self.0)
19    }
20}
21
22fn helper_format(errors: &Vec<ParseErrorInternal>) -> String {
23
24    errors.iter()
25          .map(|err| format!("* {}", err))
26          .fold(String::with_capacity(100), |mut acc, line| { acc.push_str(&line); acc })
27}
28
29quick_error!(
30    #[derive(Debug)]
31    pub enum ParserError {
32        ParseError(errors: Vec<ParseErrorInternal>) {
33            from()
34            description("Failed to parse the unit file")
35            display(error) -> ("{}, errors:\n{}", error.description(), helper_format(errors))
36        }
37        UnitGrammarError(err: String) {
38            from()
39            description("The unit file doesn't make sense")
40            display(error) -> ("{}: {}", error.description(), err)
41        }
42    }
43);
44
45// TODO: understand why blanket implem does not work
46impl<'a> From<Vec<(nom::IError<&'a str>, u32)>> for ParserError {
47    fn from(errors: Vec<(nom::IError<&'a str>, u32)>) -> ParserError {
48
49        let mut res = vec!();
50        for (err, line) in errors {
51            res.push((format!("{:?}", err), line).into())
52        }
53        ParserError::ParseError(res)
54    }
55}