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