use core::{convert::From, fmt, result};
pub type Result<T> = result::Result<T, Error>;
pub struct Error {
repr: Repr,
}
impl crate::error::Error for Error {}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.repr, f)
}
}
enum Repr {
Simple(ErrorKind),
Custom(Custom),
}
#[derive(Debug)]
struct Custom {
kind: ErrorKind,
error: &'static str,
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[non_exhaustive]
pub enum ErrorKind {
NotFound,
PermissionDenied,
ConnectionRefused,
ConnectionReset,
ConnectionAborted,
NotConnected,
AddrInUse,
AddrNotAvailable,
BrokenPipe,
AlreadyExists,
WouldBlock,
InvalidInput,
InvalidData,
TimedOut,
WriteZero,
Interrupted,
Other,
UnexpectedEof,
#[doc(hidden)]
Uncategorized,
}
impl ErrorKind {
pub(crate) fn as_str(&self) -> &'static str {
match *self {
ErrorKind::NotFound => "entity not found",
ErrorKind::PermissionDenied => "permission denied",
ErrorKind::ConnectionRefused => "connection refused",
ErrorKind::ConnectionReset => "connection reset",
ErrorKind::ConnectionAborted => "connection aborted",
ErrorKind::NotConnected => "not connected",
ErrorKind::AddrInUse => "address in use",
ErrorKind::AddrNotAvailable => "address not available",
ErrorKind::BrokenPipe => "broken pipe",
ErrorKind::AlreadyExists => "entity already exists",
ErrorKind::WouldBlock => "operation would block",
ErrorKind::InvalidInput => "invalid input parameter",
ErrorKind::InvalidData => "invalid data",
ErrorKind::TimedOut => "timed out",
ErrorKind::WriteZero => "write zero",
ErrorKind::Interrupted => "operation interrupted",
ErrorKind::Other => "other os error",
ErrorKind::UnexpectedEof => "unexpected end of file",
ErrorKind::Uncategorized => "uncategorized",
}
}
}
#[cfg(feature = "std")]
impl From<std::io::ErrorKind> for ErrorKind {
fn from(k: std::io::ErrorKind) -> Self {
match k {
std::io::ErrorKind::NotFound => ErrorKind::NotFound,
std::io::ErrorKind::PermissionDenied => ErrorKind::PermissionDenied,
std::io::ErrorKind::ConnectionRefused => ErrorKind::ConnectionRefused,
std::io::ErrorKind::ConnectionReset => ErrorKind::ConnectionReset,
std::io::ErrorKind::ConnectionAborted => ErrorKind::ConnectionAborted,
std::io::ErrorKind::NotConnected => ErrorKind::NotConnected,
std::io::ErrorKind::AddrInUse => ErrorKind::AddrInUse,
std::io::ErrorKind::AddrNotAvailable => ErrorKind::AddrNotAvailable,
std::io::ErrorKind::BrokenPipe => ErrorKind::BrokenPipe,
std::io::ErrorKind::AlreadyExists => ErrorKind::AlreadyExists,
std::io::ErrorKind::WouldBlock => ErrorKind::WouldBlock,
std::io::ErrorKind::InvalidInput => ErrorKind::InvalidInput,
std::io::ErrorKind::InvalidData => ErrorKind::InvalidData,
std::io::ErrorKind::TimedOut => ErrorKind::TimedOut,
std::io::ErrorKind::WriteZero => ErrorKind::WriteZero,
std::io::ErrorKind::Interrupted => ErrorKind::Interrupted,
std::io::ErrorKind::Other => ErrorKind::Other,
std::io::ErrorKind::UnexpectedEof => ErrorKind::UnexpectedEof,
_ => ErrorKind::Uncategorized,
}
}
}
impl From<ErrorKind> for Error {
#[inline]
fn from(kind: ErrorKind) -> Error {
Error {
repr: Repr::Simple(kind),
}
}
}
#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
#[inline]
fn from(err: std::io::Error) -> Self {
Self::from(ErrorKind::from(err.kind()))
}
}
impl Error {
pub fn new(kind: ErrorKind, error: &'static str) -> Error {
Self::_new(kind, error.into())
}
fn _new(kind: ErrorKind, error: &'static str) -> Error {
Error {
repr: Repr::Custom(Custom { kind, error }),
}
}
pub fn get_ref(&self) -> Option<&&'static str> {
match self.repr {
Repr::Simple(..) => None,
Repr::Custom(ref c) => Some(&c.error),
}
}
pub fn into_inner(self) -> Option<&'static str> {
match self.repr {
Repr::Simple(..) => None,
Repr::Custom(c) => Some(c.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.as_str()),
}
}
}
fn _assert_error_is_sync_send() {
fn _is_sync_send<T: Sync + Send>() {}
_is_sync_send::<Error>();
}