pacmanconf/
error.rs

1use std::error;
2use std::fmt;
3use std::io;
4use std::str;
5
6/// Error Line holds a line of text and the line number the line is from.
7#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
8pub struct ErrorLine {
9    /// The line number that the  error occurred at
10    pub number: usize,
11    /// The full line containing the error
12    pub line: String,
13}
14
15impl ErrorLine {
16    /// Create a new Error from a given ErrorKind and ErrorLine.
17    ///
18    /// If the line is none then Errors can be created using the the From/Into traits.
19    pub fn new<S: Into<String>>(number: usize, line: S) -> ErrorLine {
20        ErrorLine {
21            number,
22            line: line.into(),
23        }
24    }
25}
26
27/// A list of possible errors that may occur when parsing a pacman.conf
28#[derive(Debug)]
29pub enum ErrorKind {
30    /// A directive was specified outside of a section.
31    /// The variant holds the key name.
32    NoSection(String),
33    /// A directive that requires a value was specified without a value.
34    /// The variant holds the section and key.
35    MissingValue(String, String),
36    /// A directive was given with an invalid value.
37    /// The variant holds the section, key and value.
38    InvalidValue(String, String, String),
39    /// A directive was given with an unknown key.
40    /// The variant holds the section and key.
41    UnknownKey(String, String),
42    /// An error occurred while executing pacman-conf.
43    /// This variant hold the stdout of pacman-coonf
44    Runtime(String),
45    /// A utf8 error occurred.
46    Utf8(str::Utf8Error),
47    /// An IO error occurred.
48    Io(io::Error),
49}
50
51impl From<io::Error> for ErrorKind {
52    fn from(e: io::Error) -> ErrorKind {
53        ErrorKind::Io(e)
54    }
55}
56
57impl From<str::Utf8Error> for ErrorKind {
58    fn from(e: str::Utf8Error) -> ErrorKind {
59        ErrorKind::Utf8(e)
60    }
61}
62
63impl fmt::Display for ErrorKind {
64    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
65        match self {
66            ErrorKind::NoSection(k) => write!(fmt, "Key '{}' must appear in a section", k),
67            ErrorKind::MissingValue(s, k) => {
68                write!(fmt, "Key '{}' in section '{}' requires a value", k, s)
69            }
70            ErrorKind::InvalidValue(s, k, v) => {
71                write!(fmt, "Invalid value for '{}' in section '{}': '{}'", k, s, v)
72            }
73            ErrorKind::Runtime(s) => write!(fmt, "Failed to execute pacman-conf: {}", s),
74            ErrorKind::UnknownKey(s, k) => write!(fmt, "Unknown key: '{}' in section '{}'", s, k),
75            ErrorKind::Io(err) => err.fmt(fmt),
76            ErrorKind::Utf8(err) => err.fmt(fmt),
77        }
78    }
79}
80
81/// The error type for pacman.conf parsing.
82#[derive(Debug)]
83pub struct Error {
84    /// The kind of Error that occurred
85    pub kind: ErrorKind,
86    /// The line where the error occurred
87    pub line: Option<ErrorLine>,
88}
89
90impl error::Error for Error {}
91
92impl From<ErrorKind> for Error {
93    fn from(kind: ErrorKind) -> Error {
94        Error { kind, line: None }
95    }
96}
97
98impl From<io::Error> for Error {
99    fn from(err: io::Error) -> Error {
100        ErrorKind::Io(err).into()
101    }
102}
103
104impl From<str::Utf8Error> for Error {
105    fn from(err: str::Utf8Error) -> Error {
106        ErrorKind::Utf8(err).into()
107    }
108}
109
110impl fmt::Display for Error {
111    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
112        match self.line {
113            Some(ref line) => write!(fmt, "Line {}: {}: {}", line.number, self.kind, line.line),
114            None => write!(fmt, "{}", self.kind),
115        }
116    }
117}