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