use std::error::Error as ErrorBase;
use std::fmt;
use std::io;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ErrorKind {
Reserved,
OutOfRange,
IoError,
UnsupportedSystem,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ErrorKind::Reserved => f.write_str(
"That item has already been reserved."
),
ErrorKind::OutOfRange => f.write_str(
"That identifier is out of range."
),
ErrorKind::IoError => f.write_str(
"An I/O error has occurred."
),
ErrorKind::UnsupportedSystem => f.write_str(
"The detected system is not supported by this crate."
),
}
}
}
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
cause: Option<Box<ErrorBase>>,
}
impl Error {
pub(crate) fn new(kind: ErrorKind) -> Error {
Error {
kind,
cause: None,
}
}
pub(crate) fn with_cause<E>(kind: ErrorKind, cause: E) -> Error
where
E: ErrorBase + 'static,
{
Error {
kind,
cause: Some(Box::new(cause) as Box<ErrorBase>),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<ErrorKind as fmt::Display>::fmt(&self.kind, f)
}
}
impl ErrorBase for Error {
fn cause(&self) -> Option<&ErrorBase> {
self.cause.as_ref()
.map(Box::as_ref)
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::with_cause(ErrorKind::IoError, e)
}
}