1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::error;
use std::fmt;
use std::io;
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ErrorLine {
pub number: usize,
pub line: String,
}
#[derive(Debug)]
pub enum ErrorKind {
DuplicatePkgbase,
UndeclaredArch(String, String),
KeyAfterPkgname(String),
KeyBeforePkgbase(String),
MissingField(String),
EmptyKey,
EmptyValue(String),
NotArchSpecific(String),
IoError(io::Error),
}
impl fmt::Display for ErrorKind {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
ErrorKind::DuplicatePkgbase => write!(fmt, "pkgbase already set"),
ErrorKind::UndeclaredArch(k, a) => {
write!(fmt, "undeclared architecture '{}' in key '{}'", a, k)
}
ErrorKind::KeyAfterPkgname(k) => write!(fmt, "key '{}' used after pkgname", k),
ErrorKind::KeyBeforePkgbase(k) => write!(fmt, "key '{}' used before pkgbase", k),
ErrorKind::MissingField(f) => write!(fmt, "field '{}' is required", f),
ErrorKind::EmptyKey => write!(fmt, "field has no key"),
ErrorKind::EmptyValue(k) => write!(fmt, "key '{}' requires a value", k),
ErrorKind::NotArchSpecific(k) => {
write!(fmt, "key '{}' can not be architecture specific", k)
}
ErrorKind::IoError(err) => err.fmt(fmt),
}
}
}
#[derive(Debug)]
pub struct Error {
pub kind: ErrorKind,
pub line: Option<ErrorLine>,
}
impl error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.line {
Some(ref line) => write!(fmt, "{}: Line {}: {}", self.kind, line.number, line.line),
None => write!(fmt, "{}", self.kind),
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
ErrorKind::IoError(err).into()
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error { kind, line: None }
}
}
impl Error {
pub fn new<S: Into<String>>(kind: ErrorKind, line: S, number: usize) -> Error {
let line = line.into();
let line = Some(ErrorLine { number, line });
Error {
line,
..Error::from(kind)
}
}
}