archetect_core/vendor/tera/
errors.rs1use std::convert::Into;
2use std::error::Error as StdError;
3use std::fmt;
4
5#[derive(Debug)]
7pub enum ErrorKind {
8 Msg(String),
10 CircularExtend {
12 tpl: String,
14 inheritance_chain: Vec<String>,
16 },
17 MissingParent {
19 current: String,
21 parent: String,
23 },
24 TemplateNotFound(String),
26 FilterNotFound(String),
28 TestNotFound(String),
30 InvalidMacroDefinition(String),
32 FunctionNotFound(String),
34 Json(serde_json::Error),
36 CallFunction(String),
38 CallFilter(String),
40 CallTest(String),
42 Io(std::io::ErrorKind),
44 Utf8Conversion {
48 context: String,
50 },
51 #[doc(hidden)]
55 __Nonexhaustive,
56}
57
58#[derive(Debug)]
60pub struct Error {
61 pub kind: ErrorKind,
63 source: Option<Box<dyn StdError + Sync + Send>>,
64}
65
66impl fmt::Display for Error {
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 match self.kind {
69 ErrorKind::Msg(ref message) => write!(f, "{}", message),
70 ErrorKind::CircularExtend { ref tpl, ref inheritance_chain } => write!(
71 f,
72 "Circular extend detected for template '{}'. Inheritance chain: `{:?}`",
73 tpl, inheritance_chain
74 ),
75 ErrorKind::MissingParent { ref current, ref parent } => write!(
76 f,
77 "Template '{}' is inheriting from '{}', which doesn't exist or isn't loaded.",
78 current, parent
79 ),
80 ErrorKind::TemplateNotFound(ref name) => write!(f, "Template '{}' not found", name),
81 ErrorKind::FilterNotFound(ref name) => write!(f, "Filter '{}' not found", name),
82 ErrorKind::TestNotFound(ref name) => write!(f, "Test '{}' not found", name),
83 ErrorKind::FunctionNotFound(ref name) => write!(f, "Function '{}' not found", name),
84 ErrorKind::InvalidMacroDefinition(ref info) => {
85 write!(f, "Invalid macro definition: `{}`", info)
86 }
87 ErrorKind::Json(ref e) => write!(f, "{}", e),
88 ErrorKind::CallFunction(ref name) => write!(f, "Function call '{}' failed", name),
89 ErrorKind::CallFilter(ref name) => write!(f, "Filter call '{}' failed", name),
90 ErrorKind::CallTest(ref name) => write!(f, "Test call '{}' failed", name),
91 ErrorKind::Io(ref io_error) => {
92 write!(f, "Io error while writing rendered value to output: {:?}", io_error)
93 }
94 ErrorKind::Utf8Conversion { ref context } => {
95 write!(f, "UTF-8 conversion error occured while rendering template: {}", context)
96 }
97 ErrorKind::__Nonexhaustive => write!(f, "Nonexhaustive"),
98 }
99 }
100}
101
102impl StdError for Error {
103 fn source(&self) -> Option<&(dyn StdError + 'static)> {
104 self.source.as_ref().map(|c| &**c as &(dyn StdError + 'static))
105 }
106}
107
108impl Error {
109 pub fn msg(value: impl ToString) -> Self {
111 Self { kind: ErrorKind::Msg(value.to_string()), source: None }
112 }
113
114 pub fn circular_extend(tpl: impl ToString, inheritance_chain: Vec<String>) -> Self {
116 Self {
117 kind: ErrorKind::CircularExtend { tpl: tpl.to_string(), inheritance_chain },
118 source: None,
119 }
120 }
121
122 pub fn missing_parent(current: impl ToString, parent: impl ToString) -> Self {
124 Self {
125 kind: ErrorKind::MissingParent {
126 current: current.to_string(),
127 parent: parent.to_string(),
128 },
129 source: None,
130 }
131 }
132
133 pub fn template_not_found(tpl: impl ToString) -> Self {
135 Self { kind: ErrorKind::TemplateNotFound(tpl.to_string()), source: None }
136 }
137
138 pub fn filter_not_found(name: impl ToString) -> Self {
140 Self { kind: ErrorKind::FilterNotFound(name.to_string()), source: None }
141 }
142
143 pub fn test_not_found(name: impl ToString) -> Self {
145 Self { kind: ErrorKind::TestNotFound(name.to_string()), source: None }
146 }
147
148 pub fn function_not_found(name: impl ToString) -> Self {
150 Self { kind: ErrorKind::FunctionNotFound(name.to_string()), source: None }
151 }
152
153 pub fn chain(value: impl ToString, source: impl Into<Box<dyn StdError + Send + Sync>>) -> Self {
155 Self { kind: ErrorKind::Msg(value.to_string()), source: Some(source.into()) }
156 }
157
158 pub fn call_function(
160 name: impl ToString,
161 source: impl Into<Box<dyn StdError + Send + Sync>>,
162 ) -> Self {
163 Self { kind: ErrorKind::CallFunction(name.to_string()), source: Some(source.into()) }
164 }
165
166 pub fn call_filter(
168 name: impl ToString,
169 source: impl Into<Box<dyn StdError + Send + Sync>>,
170 ) -> Self {
171 Self { kind: ErrorKind::CallFilter(name.to_string()), source: Some(source.into()) }
172 }
173
174 pub fn call_test(
176 name: impl ToString,
177 source: impl Into<Box<dyn StdError + Send + Sync>>,
178 ) -> Self {
179 Self { kind: ErrorKind::CallTest(name.to_string()), source: Some(source.into()) }
180 }
181
182 pub fn json(value: serde_json::Error) -> Self {
184 Self { kind: ErrorKind::Json(value), source: None }
185 }
186
187 pub fn invalid_macro_def(name: impl ToString) -> Self {
189 Self { kind: ErrorKind::InvalidMacroDefinition(name.to_string()), source: None }
190 }
191
192 pub fn io_error(error: std::io::Error) -> Self {
194 Self { kind: ErrorKind::Io(error.kind()), source: Some(Box::new(error)) }
195 }
196
197 pub fn utf8_conversion_error(error: std::string::FromUtf8Error, context: String) -> Self {
199 Self { kind: ErrorKind::Utf8Conversion { context }, source: Some(Box::new(error)) }
200 }
201}
202
203impl From<std::io::Error> for Error {
204 fn from(error: std::io::Error) -> Self {
205 Self::io_error(error)
206 }
207}
208impl From<&str> for Error {
209 fn from(e: &str) -> Self {
210 Self::msg(e)
211 }
212}
213impl From<String> for Error {
214 fn from(e: String) -> Self {
215 Self::msg(e)
216 }
217}
218impl From<serde_json::Error> for Error {
219 fn from(e: serde_json::Error) -> Self {
220 Self::json(e)
221 }
222}
223pub type Result<T> = ::std::result::Result<T, Error>;
225
226#[cfg(test)]
227mod tests {
228 #[test]
229 fn test_error_is_send_and_sync() {
230 fn test_send_sync<T: Send + Sync>() {}
231
232 test_send_sync::<super::Error>();
233 }
234}