1use std::error;
2use std::fmt;
3use std::io;
4use std::str;
5
6#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
8pub struct ErrorLine {
9 pub number: usize,
11 pub line: String,
13}
14
15impl ErrorLine {
16 pub fn new<S: Into<String>>(number: usize, line: S) -> ErrorLine {
20 ErrorLine {
21 number,
22 line: line.into(),
23 }
24 }
25}
26
27#[derive(Debug)]
29pub enum ErrorKind {
30 NoSection(String),
33 MissingValue(String, String),
36 InvalidValue(String, String, String),
39 UnknownKey(String, String),
42 Runtime(String),
45 Utf8(str::Utf8Error),
47 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#[derive(Debug)]
83pub struct Error {
84 pub kind: ErrorKind,
86 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}