1use std::borrow::Cow;
18use std::fmt;
19use std::io;
20use std::path::PathBuf;
21
22use glob::PatternError;
23use horrorshow;
24
25use crate::model::index::SortError;
26use crate::yaml::ScanError;
27
28use std::error::Error;
29
30macro_rules! try_annotate {
31 ($e:expr, $l:expr) => {
32 match $e {
33 Ok(v) => v,
34 Err(e) => {
35 return Err($crate::error::AnnotatedError::new(
36 ($l).to_owned(),
37 From::from(e),
38 ));
39 }
40 }
41 };
42}
43
44#[derive(Debug)]
45pub enum SourceError {
46 Parse(ScanError),
47 Read(io::Error),
48 Config(Cow<'static, str>),
49}
50
51impl Error for SourceError {
52 fn description(&self) -> &str {
53 use self::SourceError::*;
54 match *self {
55 Parse(..) => "yaml parse error",
56 Read(..) => "read error",
57 Config(..) => "config error",
58 }
59 }
60 fn source(&self) -> Option<&(dyn Error + 'static)> {
61 use self::SourceError::*;
62 match *self {
63 Read(ref e) => Some(e),
64 _ => None,
66 }
67 }
68}
69
70impl fmt::Display for SourceError {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 use self::SourceError::*;
73 match *self {
74 Parse(ref e) => write!(f, "yaml parse error '{:?}'", e),
75 Read(ref e) => write!(f, "read error '{}'", e),
76 Config(ref e) => write!(f, "config error '{}'", e),
77 }
78 }
79}
80
81#[derive(Debug, Clone)]
82pub struct AnnotatedError<E>
83where
84 E: Error + 'static,
85{
86 pub location: PathBuf,
87 pub error: E,
88}
89
90impl From<AnnotatedError<io::Error>> for AnnotatedError<RenderError> {
92 fn from(e: AnnotatedError<io::Error>) -> AnnotatedError<RenderError> {
93 AnnotatedError {
94 location: e.location,
95 error: From::from(e.error),
96 }
97 }
98}
99
100impl<E> Error for AnnotatedError<E>
101where
102 E: Error + 'static,
103{
104 fn description(&self) -> &str {
105 #[allow(deprecated)]
106 self.error.description()
107 }
108 fn source(&self) -> Option<&(dyn Error + 'static)> {
109 Some(&self.error)
110 }
111}
112
113impl<E> fmt::Display for AnnotatedError<E>
114where
115 E: Error,
116{
117 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
118 write!(
119 f,
120 "when processing {}: {}",
121 self.location.display(),
122 self.error
123 )
124 }
125}
126
127impl<E> AnnotatedError<E>
128where
129 E: Error,
130{
131 pub fn new(location: PathBuf, error: E) -> AnnotatedError<E> {
132 AnnotatedError { location, error }
133 }
134}
135
136impl From<io::Error> for SourceError {
137 fn from(e: io::Error) -> SourceError {
138 SourceError::Read(e)
139 }
140}
141
142impl From<::url::ParseError> for SourceError {
143 fn from(e: ::url::ParseError) -> SourceError {
144 SourceError::Config(Cow::Owned(format!("{}", e)))
145 }
146}
147
148impl From<ScanError> for SourceError {
149 fn from(e: ScanError) -> SourceError {
150 SourceError::Parse(e)
151 }
152}
153
154impl From<PatternError> for SourceError {
155 fn from(_: PatternError) -> SourceError {
156 SourceError::from("invalid index directory pattern")
157 }
158}
159
160impl From<&'static str> for SourceError {
161 fn from(e: &'static str) -> SourceError {
162 SourceError::Config(Cow::Borrowed(e))
163 }
164}
165
166impl From<String> for SourceError {
167 fn from(e: String) -> SourceError {
168 SourceError::Config(Cow::Owned(e))
169 }
170}
171
172impl From<SortError> for SourceError {
173 fn from(value: SortError) -> Self {
174 value.to_string().into()
175 }
176}
177
178pub type RenderError = horrorshow::Error;