2018-02-02 20:35:04 +00:00
|
|
|
extern crate image;
|
2018-10-09 12:33:43 +00:00
|
|
|
extern crate syntect;
|
2018-10-31 07:18:57 +00:00
|
|
|
extern crate tera;
|
|
|
|
extern crate toml;
|
2017-07-01 07:47:41 +00:00
|
|
|
|
2019-01-11 19:29:46 +00:00
|
|
|
use std::convert::Into;
|
|
|
|
use std::error::Error as StdError;
|
|
|
|
use std::fmt;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ErrorKind {
|
|
|
|
Msg(String),
|
|
|
|
Tera(tera::Error),
|
|
|
|
Io(::std::io::Error),
|
|
|
|
Toml(toml::de::Error),
|
|
|
|
Image(image::ImageError),
|
|
|
|
Syntect(syntect::LoadingError),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The Error type
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Error {
|
|
|
|
/// Kind of error
|
|
|
|
pub kind: ErrorKind,
|
|
|
|
pub source: Option<Box<dyn StdError>>,
|
|
|
|
}
|
|
|
|
unsafe impl Sync for Error {}
|
|
|
|
unsafe impl Send for Error {}
|
|
|
|
|
|
|
|
impl StdError for Error {
|
|
|
|
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
2019-01-30 19:42:53 +00:00
|
|
|
let mut source = self.source.as_ref().map(|c| &**c);
|
|
|
|
if source.is_none() {
|
Fix clippy warnings (#744)
Clippy is returning some warnings. Let's fix or explicitly ignore
them. In particular:
- In `components/imageproc/src/lib.rs`, we implement `Hash` explicitly
but derive `PartialEq`. We need to maintain the property that two
keys being equal implies the hashes of those two keys are equal.
Our `Hash` implementations preserve this, so we'll explicitly ignore
the warnings.
- In `components/site/src/lib.rs`, we were calling `.into()` on some
values that are already of the correct type.
- In `components/site/src/lib.rs`, we were using `.map(|x| *x)` in
iterator chains to remove a level of indirection; we can instead say
`.copied()` (introduced in Rust v1.36) or `.cloned()`. Using
`.copied` here is better from a type-checking point of view, but
we'll use `.cloned` for now as Rust v1.36 was only recently
released.
- In `components/templates/src/filters.rs` and
`components/utils/src/site.rs`, we were taking `HashMap`s as
function arguments but not generically accepting alternate `Hasher`
implementations.
- In `src/cmd/check.rs`, we use `env::current_dir()` as a default
value, but our use of `unwrap_or` meant that we would always
retrieve the current directory even when not needed.
- In `components/errors/src/lib.rs`, we can use `if let` rather than
`match`.
- In `components/library/src/content/page.rs`, we can collapse a
nested conditional into `else if let ...`.
- In `components/library/src/sorting.rs`, a function takes `&&Page`
arguments. Clippy warns about this for efficiency reasons, but
we're doing it here to match a particular sorting API, so we'll
explicitly ignore the warning.
2019-07-12 08:29:44 +00:00
|
|
|
if let ErrorKind::Tera(ref err) = self.kind {
|
|
|
|
source = err.source();
|
|
|
|
}
|
2019-01-30 19:42:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
source
|
2019-01-11 19:29:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self.kind {
|
|
|
|
ErrorKind::Msg(ref message) => write!(f, "{}", message),
|
|
|
|
ErrorKind::Tera(ref e) => write!(f, "{}", e),
|
|
|
|
ErrorKind::Io(ref e) => write!(f, "{}", e),
|
|
|
|
ErrorKind::Toml(ref e) => write!(f, "{}", e),
|
|
|
|
ErrorKind::Image(ref e) => write!(f, "{}", e),
|
|
|
|
ErrorKind::Syntect(ref e) => write!(f, "{}", e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-07-01 07:47:41 +00:00
|
|
|
|
2019-01-11 19:29:46 +00:00
|
|
|
impl Error {
|
|
|
|
/// Creates generic error
|
|
|
|
pub fn msg(value: impl ToString) -> Self {
|
|
|
|
Self { kind: ErrorKind::Msg(value.to_string()), source: None }
|
2017-07-01 07:47:41 +00:00
|
|
|
}
|
|
|
|
|
2019-01-11 19:29:46 +00:00
|
|
|
/// Creates generic error with a cause
|
|
|
|
pub fn chain(value: impl ToString, source: impl Into<Box<dyn StdError>>) -> Self {
|
|
|
|
Self { kind: ErrorKind::Msg(value.to_string()), source: Some(source.into()) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&str> for Error {
|
|
|
|
fn from(e: &str) -> Self {
|
|
|
|
Self::msg(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl From<String> for Error {
|
|
|
|
fn from(e: String) -> Self {
|
|
|
|
Self::msg(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl From<toml::de::Error> for Error {
|
|
|
|
fn from(e: toml::de::Error) -> Self {
|
|
|
|
Self { kind: ErrorKind::Toml(e), source: None }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl From<syntect::LoadingError> for Error {
|
|
|
|
fn from(e: syntect::LoadingError) -> Self {
|
|
|
|
Self { kind: ErrorKind::Syntect(e), source: None }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl From<tera::Error> for Error {
|
|
|
|
fn from(e: tera::Error) -> Self {
|
|
|
|
Self { kind: ErrorKind::Tera(e), source: None }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl From<::std::io::Error> for Error {
|
|
|
|
fn from(e: ::std::io::Error) -> Self {
|
|
|
|
Self { kind: ErrorKind::Io(e), source: None }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl From<image::ImageError> for Error {
|
|
|
|
fn from(e: image::ImageError) -> Self {
|
|
|
|
Self { kind: ErrorKind::Image(e), source: None }
|
2017-07-01 07:47:41 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-11 19:29:46 +00:00
|
|
|
/// Convenient wrapper around std::Result.
|
|
|
|
pub type Result<T> = ::std::result::Result<T, Error>;
|
2017-07-01 07:47:41 +00:00
|
|
|
|
|
|
|
// So we can use bail! in all other crates
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! bail {
|
|
|
|
($e:expr) => {
|
|
|
|
return Err($e.into());
|
|
|
|
};
|
|
|
|
($fmt:expr, $($arg:tt)+) => {
|
|
|
|
return Err(format!($fmt, $($arg)+).into());
|
|
|
|
};
|
|
|
|
}
|