use std::fmt;
use std::error::Error as StdError;
use std::io::ErrorKind as IoErrorKind;
use std::io::Error as IoError;
use std::path::StripPrefixError;
use std::ffi::OsString;
#[derive(Debug)]
pub enum ErrorKind {
NotFound,
PermissionDenied,
AlreadyExists,
Interrupted,
InvalidFolder,
InvalidFile,
InvalidFileName,
InvalidPath,
Io(IoError),
StripPrefix(StripPrefixError),
OsString(OsString),
Other,
}
impl ErrorKind {
fn as_str(&self) -> &str {
match *self {
ErrorKind::NotFound => "entity not found",
ErrorKind::PermissionDenied => "permission denied",
ErrorKind::AlreadyExists => "entity already exists",
ErrorKind::Interrupted => "operation interrupted",
ErrorKind::Other => "other os error",
ErrorKind::InvalidFolder => "invalid folder error",
ErrorKind::InvalidFile => "invalid file error",
ErrorKind::InvalidFileName => "invalid file name error",
ErrorKind::InvalidPath => "invalid path error",
ErrorKind::Io(_) => "Io error",
ErrorKind::StripPrefix(_) => "Strip prefix error",
ErrorKind::OsString(_) => "OsString error",
}
}
}
pub type Result<T> = ::std::result::Result<T, Error>;
#[derive(Debug)]
pub struct Error {
pub kind: ErrorKind,
message: String,
}
impl Error {
pub fn new(kind: ErrorKind, message: &str) -> Error {
Error {
kind: kind,
message: message.to_string(),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl StdError for Error {
fn description(&self) -> &str {
self.kind.as_str()
}
}
impl From<StripPrefixError> for Error {
fn from(err: StripPrefixError) -> Error {
Error::new(ErrorKind::StripPrefix(err),
"StripPrefixError. Look inside for more details")
}
}
impl From<OsString> for Error {
fn from(err: OsString) -> Error {
Error::new(ErrorKind::OsString(err),
"OsString. Look inside for more details")
}
}
impl From<IoError> for Error {
fn from(err: IoError) -> Error {
let err_kind: ErrorKind;
match err.kind() {
IoErrorKind::NotFound => err_kind = ErrorKind::NotFound,
IoErrorKind::PermissionDenied => err_kind = ErrorKind::PermissionDenied,
IoErrorKind::AlreadyExists => err_kind = ErrorKind::AlreadyExists,
IoErrorKind::Interrupted => err_kind = ErrorKind::Interrupted,
IoErrorKind::Other => err_kind = ErrorKind::Other,
_ => {
err_kind = ErrorKind::Io(err);
return Error::new(err_kind, "Io error. Look inside err_kind for more details.");
}
}
Error::new(err_kind, err.description())
}
}