1use std::convert::Infallible;
2use std::fmt::{self, Display};
3
4/// The [`Result`](std::result::Result) type with [`Error`] as default error type
5pub 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)]
28pub 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
38impl 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
49impl 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
60impl From<fmt::Error> for Error {
61 #[inline]
62 fn from(_: fmt::Error) -> Self {
63 Error::Fmt
64 }
65}
66
67#[cfg(feature = "serde_json")]
68impl From<serde_json::Error> for Error {
69 #[inline]
70 fn from(err: serde_json::Error) -> Self {
71 Error::Json(err)
72 }
73}
74
75impl From<Infallible> for Error {
76 #[inline]
77 fn from(value: Infallible) -> Self {
78 match value {}
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::Error;
85
86 #[allow(dead_code)]
87 trait AssertSendSyncStatic: Send + Sync + 'static {}
88 impl AssertSendSyncStatic for Error {}
89}
90