1use std::fmt::{self, Display};
2
3pub type Result<I, E = Error> = ::std::result::Result<I, E>;
4
5/// askama error type
6///
7/// # Feature Interaction
8///
9/// If the feature `serde_json` is enabled an
10/// additional error variant `Json` is added.
11///
12/// # Why not `failure`/`error-chain`?
13///
14/// Error from `error-chain` are not `Sync` which
15/// can lead to problems e.g. when this is used
16/// by a crate which use `failure`. Implementing
17/// `Fail` on the other hand prevents the implementation
18/// of `std::error::Error` until specialization lands
19/// on stable. While errors impl. `Fail` can be
20/// converted to a type impl. `std::error::Error`
21/// using a adapter the benefits `failure` would
22/// bring to this crate are small, which is why
23/// `std::error::Error` was used.
24///
25#[non_exhaustive]
26#[derive(Debug)]
27pub enum Error {
28 /// formatting error
29 Fmt(fmt::Error),
30
31 /// an error raised by using `?` in a template
32 Custom(Box<dyn std::error::Error + Send + Sync>),
33
34 /// json conversion error
35 #[cfg(feature = "serde_json")]
36 Json(::serde_json::Error),
37
38 /// yaml conversion error
39 #[cfg(feature = "serde_yaml")]
40 Yaml(::serde_yaml::Error),
41}
42
43impl std::error::Error for Error {
44 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
45 match *self {
46 Error::Fmt(ref err: &Error) => Some(err),
47 Error::Custom(ref err: &Box) => Some(err.as_ref()),
48 #[cfg(feature = "serde_json")]
49 Error::Json(ref err) => Some(err),
50 #[cfg(feature = "serde_yaml")]
51 Error::Yaml(ref err) => Some(err),
52 }
53 }
54}
55
56impl Display for Error {
57 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self {
59 Error::Fmt(err: &Error) => write!(formatter, "formatting error: {err}"),
60 Error::Custom(err: &Box) => write!(formatter, "{err}"),
61 #[cfg(feature = "serde_json")]
62 Error::Json(err) => write!(formatter, "json conversion error: {err}"),
63 #[cfg(feature = "serde_yaml")]
64 Error::Yaml(err) => write!(formatter, "yaml conversion error: {}", err),
65 }
66 }
67}
68
69impl From<fmt::Error> for Error {
70 fn from(err: fmt::Error) -> Self {
71 Error::Fmt(err)
72 }
73}
74
75#[cfg(feature = "serde_json")]
76impl From<::serde_json::Error> for Error {
77 fn from(err: ::serde_json::Error) -> Self {
78 Error::Json(err)
79 }
80}
81
82#[cfg(feature = "serde_yaml")]
83impl From<::serde_yaml::Error> for Error {
84 fn from(err: ::serde_yaml::Error) -> Self {
85 Error::Yaml(err)
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::Error;
92
93 trait AssertSendSyncStatic: Send + Sync + 'static {}
94 impl AssertSendSyncStatic for Error {}
95}
96