diff options
Diffstat (limited to 'askama_shared/src/error.rs')
-rw-r--r-- | askama_shared/src/error.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/askama_shared/src/error.rs b/askama_shared/src/error.rs new file mode 100644 index 0000000..cdd6b55 --- /dev/null +++ b/askama_shared/src/error.rs @@ -0,0 +1,95 @@ +use std::fmt::{self, Display}; +use std::error::{Error as ErrorTrait}; + +pub type Result<I> = ::std::result::Result<I, Error>; + +/// askama error type +/// +/// # Feature Interaction +/// +/// If the feature `serde-json` is enabled an +/// additional error variant `Json` is added. +/// +/// # Why not `failure`/`error-chain`? +/// +/// Error from `error-chain` are not `Sync` which +/// can lead to problems e.g. when this is used +/// by a crate which use `failure`. Implementing +/// `Fail` on the other hand prevents the implementation +/// of `std::error::Error` until specialization lands +/// on stable. While errors impl. `Fail` can be +/// converted to a type impl. `std::error::Error` +/// using a adapter the benefits `failure` would +/// bring to this crate are small, which is why +/// `std::error::Error` was used. +/// +#[derive(Debug, )] +pub enum Error { + /// formatting error + Fmt(fmt::Error), + + /// json conversion error + #[cfg(feature = "serde-json")] + Json(::serde_json::Error), + + /// This error needs to be non-exhaustive as + /// the `Json` variants existence depends on + /// a feature. + #[doc(hidden)] + __Nonexhaustive, +} + +impl ErrorTrait for Error { + + fn description(&self) -> &str { + match *self { + Error::Fmt(ref err) => err.description(), + #[cfg(feature = "serde-json")] + Error::Json(ref err) => err.description(), + _ => "unknown error: __Nonexhaustive" + } + } + + fn cause(&self) -> Option<&ErrorTrait> { + match *self { + Error::Fmt(ref err) => err.cause(), + #[cfg(feature = "serde-json")] + Error::Json(ref err) => err.cause(), + _ => None + } + } +} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self { + Error::Fmt(ref err) => write!(formatter, "formatting error: {}", err), + + #[cfg(feature = "serde-json")] + Error::Json(ref err) => write!(formatter, "json conversion error: {}", err), + _ => write!(formatter, "unknown error: __Nonexhaustive") + } + } +} + +impl From<fmt::Error> for Error { + fn from(err: fmt::Error) -> Self { + Error::Fmt(err) + } +} + +#[cfg(feature = "serde-json")] +impl From<::serde_json::Error> for Error { + fn from(err: ::serde_json::Error) -> Self { + Error::Json(err) + } +} + + +#[cfg(test)] +mod tests { + use super::Error; + + trait AssertSendSyncStatic: Send + Sync + 'static {} + impl AssertSendSyncStatic for Error {} +}
\ No newline at end of file |