use std::fmt::{self, Display, Formatter};
use sys::errcode_t;
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Error(Repr);
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
enum Repr {
Simple(ErrorKind),
Raw(errcode_t),
}
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum ErrorKind {
TypeError = 1,
RankError,
DimensionError,
NumericalError,
MemoryError,
FunctionError,
VersionError,
}
impl Error {
#[inline]
pub fn from_raw_error(code: errcode_t) -> Option<Self> {
if code == sys::LIBRARY_NO_ERROR {
None
} else {
Some(Error(Repr::Raw(code)))
}
}
#[inline]
pub fn to_raw_error(&self) -> errcode_t {
match self.0 {
Repr::Simple(kind) => kind.to_raw_error(),
Repr::Raw(code) => code,
}
}
#[inline]
pub fn kind(&self) -> Option<ErrorKind> {
match self.0 {
Repr::Simple(kind) => Some(kind),
Repr::Raw(code) => ErrorKind::from_raw_error(code),
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
use Repr::*;
match self.0 {
Simple(kind) => write!(f, "{}", kind),
Raw(code) => {
if let Some(kind) = ErrorKind::from_raw_error(code) {
write!(f, "{}", kind)
} else {
write!(f, "unknown error code: {}", code)
}
}
}
}
}
impl std::error::Error for Error {}
impl From<ErrorKind> for Error {
#[inline]
fn from(e: ErrorKind) -> Self {
Error(Repr::Simple(e))
}
}
impl ErrorKind {
#[inline]
pub(crate) fn to_raw_error(&self) -> errcode_t {
use ErrorKind::*;
match *self {
TypeError => sys::LIBRARY_TYPE_ERROR,
RankError => sys::LIBRARY_RANK_ERROR,
DimensionError => sys::LIBRARY_DIMENSION_ERROR,
NumericalError => sys::LIBRARY_NUMERICAL_ERROR,
MemoryError => sys::LIBRARY_MEMORY_ERROR,
FunctionError => sys::LIBRARY_FUNCTION_ERROR,
VersionError => sys::LIBRARY_VERSION_ERROR,
}
}
#[inline]
pub(crate) fn from_raw_error(code: errcode_t) -> Option<Self> {
use ErrorKind::*;
match code {
sys::LIBRARY_NO_ERROR => unreachable!(),
sys::LIBRARY_TYPE_ERROR => Some(TypeError),
sys::LIBRARY_RANK_ERROR => Some(RankError),
sys::LIBRARY_DIMENSION_ERROR => Some(DimensionError),
sys::LIBRARY_NUMERICAL_ERROR => Some(NumericalError),
sys::LIBRARY_MEMORY_ERROR => Some(MemoryError),
sys::LIBRARY_FUNCTION_ERROR => Some(FunctionError),
sys::LIBRARY_VERSION_ERROR => Some(VersionError),
_ => None,
}
}
}
impl Display for ErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
use ErrorKind::*;
match *self {
TypeError => write!(f, "unexpected type encountered"),
RankError => write!(f, "unexpected rank encountered "),
DimensionError => write!(f, "inconsistent dimensions encountered"),
NumericalError => write!(f, "error in numerical computation"),
MemoryError => write!(f, "problem allocating memory"),
FunctionError => write!(f, "generic error from a function"),
VersionError => write!(f, "incompatible version"),
}
}
}