use std::fmt;
use std::io;
use std::path::PathBuf;
use serde_yaml;
use gitignore;
#[derive(Debug)]
pub enum Error {
BadLink(
PathBuf, PathBuf, io::Error, ),
BadHeader(
PathBuf, serde_yaml::Error, ),
IgnoreFile(gitignore::Error),
Io(io::Error),
NormalizePath(std::path::StripPrefixError),
Yaml(serde_yaml::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::BadHeader(ref filepath, ref err)
=> display_bad_header(f, filepath, err),
Error::BadLink(ref source, ref link, ref _err)
=> write!(f, "Bad link from {:?} to\n\
{:?},\n\
which doesn't exist.", source, link),
Error::IgnoreFile(ref err) => write!(f, "{}", err),
Error::Io(ref err) => write!(f, "{}", err),
Error::NormalizePath(ref err) => write!(f, "{}", err),
Error::Yaml(ref err) => write!(f, "{}", err),
}
}
}
fn display_bad_header(f: &mut fmt::Formatter,
filepath: &PathBuf,
yaml_error: &serde_yaml::Error) -> fmt::Result {
write!(f, "Bad YAML header in {:?}:\n", filepath)?;
let message = yaml_error.to_string();
write!(f, "The error reads: \"{}\".\n", yaml_error)?;
if message.contains("simple key expected") {
write!(f, "Hint: That usually means that you need to indent the \
suggested line.")?;
}
Ok(())
}
impl std::error::Error for Error {
fn cause(&self) -> Option<&dyn std::error::Error> {
match *self {
Error::BadHeader(_, ref err) => Some(err),
Error::BadLink(_, _, ref err) => Some(err),
Error::IgnoreFile(ref err) => Some(err),
Error::Io(ref err) => Some(err),
Error::NormalizePath(ref err) => Some(err),
Error::Yaml(ref err) => Some(err),
}
}
}
impl From<gitignore::Error> for Error {
fn from(err: gitignore::Error) -> Error {
Error::IgnoreFile(err)
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::Io(err)
}
}
impl From<std::path::StripPrefixError> for Error {
fn from(err: std::path::StripPrefixError) -> Error {
Error::NormalizePath(err)
}
}
impl From<serde_yaml::Error> for Error {
fn from(err: serde_yaml::Error) -> Error {
Error::Yaml(err)
}
}