102 lines
2.2 KiB
Rust
102 lines
2.2 KiB
Rust
|
use std::error::Error as StdError;
|
||
|
use std::fmt;
|
||
|
use std::mem;
|
||
|
use std::result;
|
||
|
|
||
|
pub type Result<T> = result::Result<T, Error>;
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct Error {
|
||
|
repr: Repr,
|
||
|
}
|
||
|
|
||
|
enum Repr {
|
||
|
Simple(ErrorKind),
|
||
|
Custom(Box<Custom>),
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
struct Custom {
|
||
|
kind: ErrorKind,
|
||
|
error: Box<dyn StdError + Send + Sync>,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone)]
|
||
|
pub enum ErrorKind {
|
||
|
MissedEnvVar(String),
|
||
|
}
|
||
|
|
||
|
impl fmt::Display for ErrorKind {
|
||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||
|
match *self {
|
||
|
ErrorKind::MissedEnvVar(ref name) => {
|
||
|
write!(fmt, r#"Missed "{}" environment variable"#, name)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl PartialEq for ErrorKind {
|
||
|
fn eq(&self, other: &Self) -> bool {
|
||
|
mem::discriminant(self) == mem::discriminant(other)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<ErrorKind> for Error {
|
||
|
#[inline]
|
||
|
fn from(kind: ErrorKind) -> Error {
|
||
|
Error {
|
||
|
repr: Repr::Simple(kind),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Error {
|
||
|
pub fn new<E>(kind: ErrorKind, error: E) -> Error
|
||
|
where
|
||
|
E: Into<Box<dyn StdError + Send + Sync>>,
|
||
|
{
|
||
|
Self::_new(kind, error.into())
|
||
|
}
|
||
|
|
||
|
fn _new(kind: ErrorKind, error: Box<dyn StdError + Send + Sync>) -> Error {
|
||
|
Error {
|
||
|
repr: Repr::Custom(Box::new(Custom { kind, error })),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn kind(&self) -> &ErrorKind {
|
||
|
match &self.repr {
|
||
|
Repr::Custom(ref c) => &c.kind,
|
||
|
Repr::Simple(kind) => &kind,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl fmt::Debug for Repr {
|
||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||
|
match self {
|
||
|
Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
|
||
|
Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl fmt::Display for Error {
|
||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||
|
match &self.repr {
|
||
|
Repr::Custom(ref c) => c.error.fmt(fmt),
|
||
|
Repr::Simple(kind) => write!(fmt, "{}", kind),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl StdError for Error {
|
||
|
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||
|
match self.repr {
|
||
|
Repr::Simple(..) => None,
|
||
|
Repr::Custom(ref c) => c.error.source(),
|
||
|
}
|
||
|
}
|
||
|
}
|