use std::borrow::Cow;
use std::fmt;
use std::io;
use std::path::PathBuf;
use horrorshow;
use crate::model::index::SortError;
use crate::yaml::ScanError;
use std::error::Error;
macro_rules! try_annotate {
($e:expr, $l:expr) => {
match $e {
Ok(v) => v,
Err(e) => {
return Err($crate::error::AnnotatedError::new(
($l).to_owned(),
From::from(e),
));
}
}
};
}
#[derive(Debug)]
pub enum SourceError {
Parse(ScanError),
Read(io::Error),
Config(Cow<'static, str>),
}
impl Error for SourceError {
fn description(&self) -> &str {
use self::SourceError::*;
match *self {
Parse(..) => "yaml parse error",
Read(..) => "read error",
Config(..) => "config error",
}
}
fn source(&self) -> Option<&(dyn Error + 'static)> {
use self::SourceError::*;
match *self {
Read(ref e) => Some(e),
_ => None,
}
}
}
impl fmt::Display for SourceError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::SourceError::*;
match *self {
Parse(ref e) => write!(f, "yaml parse error '{e:?}'"),
Read(ref e) => write!(f, "read error '{e}'"),
Config(ref e) => write!(f, "config error '{e}'"),
}
}
}
#[derive(Debug, Clone)]
pub struct AnnotatedError<E>
where
E: Error + 'static,
{
pub location: PathBuf,
pub error: E,
}
impl From<AnnotatedError<io::Error>> for AnnotatedError<RenderError> {
fn from(e: AnnotatedError<io::Error>) -> AnnotatedError<RenderError> {
AnnotatedError {
location: e.location,
error: From::from(e.error),
}
}
}
impl<E> Error for AnnotatedError<E>
where
E: Error + 'static,
{
fn description(&self) -> &str {
#[allow(deprecated)]
self.error.description()
}
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.error)
}
}
impl<E> fmt::Display for AnnotatedError<E>
where
E: Error,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"when processing {}: {}",
self.location.display(),
self.error
)
}
}
impl<E> AnnotatedError<E>
where
E: Error,
{
pub fn new(location: PathBuf, error: E) -> AnnotatedError<E> {
AnnotatedError { location, error }
}
}
impl From<io::Error> for SourceError {
fn from(e: io::Error) -> SourceError {
SourceError::Read(e)
}
}
impl From<::url::ParseError> for SourceError {
fn from(e: ::url::ParseError) -> SourceError {
SourceError::Config(Cow::Owned(format!("{e}")))
}
}
impl From<ScanError> for SourceError {
fn from(e: ScanError) -> SourceError {
SourceError::Parse(e)
}
}
impl From<&'static str> for SourceError {
fn from(e: &'static str) -> SourceError {
SourceError::Config(Cow::Borrowed(e))
}
}
impl From<String> for SourceError {
fn from(e: String) -> SourceError {
SourceError::Config(Cow::Owned(e))
}
}
impl From<SortError> for SourceError {
fn from(value: SortError) -> Self {
value.to_string().into()
}
}
pub type RenderError = horrorshow::Error;