1 | use std::fmt::{self, Display}; |
2 | |
3 | pub 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)] |
27 | pub 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 | |
43 | impl 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 | |
56 | impl 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 | |
69 | impl From<fmt::Error> for Error { |
70 | fn from(err: fmt::Error) -> Self { |
71 | Error::Fmt(err) |
72 | } |
73 | } |
74 | |
75 | #[cfg (feature = "serde_json" )] |
76 | impl 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" )] |
83 | impl From<::serde_yaml::Error> for Error { |
84 | fn from(err: ::serde_yaml::Error) -> Self { |
85 | Error::Yaml(err) |
86 | } |
87 | } |
88 | |
89 | #[cfg (test)] |
90 | mod tests { |
91 | use super::Error; |
92 | |
93 | trait AssertSendSyncStatic: Send + Sync + 'static {} |
94 | impl AssertSendSyncStatic for Error {} |
95 | } |
96 | |