askama/
error.rs

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) => Some(err),
47            Error::Custom(ref err) => 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) => write!(formatter, "formatting error: {err}"),
60            Error::Custom(err) => 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}