use std::ffi::OsString;
use std::fmt::{self, Display};
use std::io;
use std::result;
use failure::{self, Backtrace, Context, Fail};
use ffi_support::{handle_map::HandleError, ExternError};
use rkv::error::StoreError;
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug, Fail)]
pub enum ErrorKind {
#[fail(display = "Lifetime conversion from {} failed", _0)]
Lifetime(i32),
#[fail(display = "Invalid handle: {}", _0)]
Handle(HandleError),
#[fail(display = "An I/O error occurred: {}", _0)]
IoError(io::Error),
#[fail(display = "An Rkv error occurred: {}", _0)]
Rkv(StoreError),
#[fail(display = "A JSON error occurred: {}", _0)]
Json(serde_json::error::Error),
#[fail(display = "TimeUnit conversion from {} failed", _0)]
TimeUnit(i32),
#[fail(display = "MemoryUnit conversion from {} failed", _0)]
MemoryUnit(i32),
#[fail(display = "HistogramType conversion from {} failed", _0)]
HistogramType(i32),
#[fail(display = "OsString conversion from {:?} failed", _0)]
OsString(OsString),
#[fail(display = "Invalid UTF-8 byte sequence in string.")]
Utf8Error,
}
#[derive(Debug)]
pub struct Error {
inner: Context<ErrorKind>,
}
impl Error {
pub fn kind(&self) -> &ErrorKind {
&*self.inner.get_context()
}
pub fn utf8_error() -> Error {
Error {
inner: Context::new(ErrorKind::Utf8Error),
}
}
}
impl Fail for Error {
fn cause(&self) -> Option<&dyn Fail> {
self.inner.cause()
}
fn backtrace(&self) -> Option<&Backtrace> {
self.inner.backtrace()
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
let inner = Context::new(kind);
Error { inner }
}
}
impl From<Context<ErrorKind>> for Error {
fn from(inner: Context<ErrorKind>) -> Error {
Error { inner }
}
}
impl From<HandleError> for Error {
fn from(error: HandleError) -> Error {
Error {
inner: Context::new(ErrorKind::Handle(error)),
}
}
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error {
inner: Context::new(ErrorKind::IoError(error)),
}
}
}
impl From<StoreError> for Error {
fn from(error: StoreError) -> Error {
Error {
inner: Context::new(ErrorKind::Rkv(error)),
}
}
}
impl From<Error> for ExternError {
fn from(error: Error) -> ExternError {
ffi_support::ExternError::new_error(ffi_support::ErrorCode::new(42), format!("{}", error))
}
}
impl From<serde_json::error::Error> for Error {
fn from(error: serde_json::error::Error) -> Error {
Error {
inner: Context::new(ErrorKind::Json(error)),
}
}
}
impl From<OsString> for Error {
fn from(error: OsString) -> Error {
Error {
inner: Context::new(ErrorKind::OsString(error)),
}
}
}
impl From<std::convert::Infallible> for Error {
fn from(_: std::convert::Infallible) -> Error {
unreachable!()
}
}