use std::error;
use std::fmt;
use std::result;
use crate::vars::*;
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
Custom(Custom),
Other(Box<dyn error::Error>),
}
unsafe impl Send for Error {}
unsafe impl Sync for Error {}
impl From<Custom> for Error {
fn from(err: Custom) -> Error {
Error::Custom(err)
}
}
impl From<::std::ffi::NulError> for Error {
fn from(err: ::std::ffi::NulError) -> Error {
Error::Other(Box::new(err))
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Custom(ref c) => write!(f, "Custom error: {}", c),
Error::Other(ref e) => write!(f, "Other error: {}", e),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Custom {
kind: ErrorKind,
raw: i32,
}
#[allow(non_camel_case_types)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ErrorKind {
OK = 0,
NOMEM,
ABORT,
IOERR,
CORRUPT,
LOCKED,
BUSY,
DONE,
PERM,
NOTIMPLEMENTED,
NOTFOUND,
NOOP,
INVALID,
EOF,
UNKNOWN,
LIMIT,
EXISTS,
EMPTY,
COMPILE_ERR,
VM_ERR,
FULL,
CANTOPEN,
READ_ONLY,
LOCKERR,
#[doc(hidden)]
__Nonexhaustive,
}
impl From<i32> for ErrorKind {
fn from(code: i32) -> ErrorKind {
match code {
UNQLITE_OK => ErrorKind::OK,
UNQLITE_NOMEM => ErrorKind::NOMEM,
UNQLITE_ABORT => ErrorKind::ABORT,
UNQLITE_IOERR => ErrorKind::IOERR,
UNQLITE_CORRUPT => ErrorKind::CORRUPT,
UNQLITE_LOCKED => ErrorKind::LOCKED,
UNQLITE_BUSY => ErrorKind::BUSY,
UNQLITE_DONE => ErrorKind::DONE,
UNQLITE_PERM => ErrorKind::PERM,
UNQLITE_NOTIMPLEMENTED => ErrorKind::NOTIMPLEMENTED,
UNQLITE_NOTFOUND => ErrorKind::NOTFOUND,
UNQLITE_NOOP => ErrorKind::NOOP,
UNQLITE_INVALID => ErrorKind::INVALID,
UNQLITE_EOF => ErrorKind::EOF,
UNQLITE_UNKNOWN => ErrorKind::UNKNOWN,
UNQLITE_LIMIT => ErrorKind::LIMIT,
UNQLITE_EXISTS => ErrorKind::EXISTS,
UNQLITE_EMPTY => ErrorKind::EMPTY,
UNQLITE_COMPILE_ERR => ErrorKind::COMPILE_ERR,
UNQLITE_VM_ERR => ErrorKind::VM_ERR,
UNQLITE_FULL => ErrorKind::FULL,
UNQLITE_CANTOPEN => ErrorKind::CANTOPEN,
UNQLITE_READ_ONLY => ErrorKind::READ_ONLY,
UNQLITE_LOCKERR => ErrorKind::LOCKERR,
_ => ErrorKind::__Nonexhaustive,
}
}
}
pub(crate) trait Wrap {
fn wrap(self) -> Result<()>;
}
impl Wrap for i32 {
fn wrap(self) -> Result<()> {
Custom::from_raw(self)
}
}
impl Custom {
pub fn from_raw(result: i32) -> Result<()> {
let kind = ErrorKind::from(result);
match kind {
ErrorKind::OK => Ok(()),
_ => Err(Custom {
kind: kind,
raw: result,
}
.into()),
}
}
pub fn error(&self) -> &str {
match self.kind {
ErrorKind::NOMEM => "Out of memory",
ErrorKind::ABORT => "Another thread have released this instance",
ErrorKind::IOERR => "IO error",
ErrorKind::CORRUPT => "Corrupt pointer",
ErrorKind::LOCKED => "Forbidden Operation",
ErrorKind::BUSY => "The database file is locked",
ErrorKind::DONE => "Operation done",
ErrorKind::PERM => "Permission error",
ErrorKind::NOTIMPLEMENTED => {
"Method not implemented by the underlying Key/Value storage engine"
}
ErrorKind::NOTFOUND => "No such record",
ErrorKind::NOOP => "No such method",
ErrorKind::INVALID => "Invalid parameter",
ErrorKind::EOF => "End Of Input",
ErrorKind::UNKNOWN => "Unknown configuration option",
ErrorKind::LIMIT => "Database limit reached",
ErrorKind::EXISTS => "Record exists",
ErrorKind::EMPTY => "Empty record",
ErrorKind::COMPILE_ERR => "Compilation error",
ErrorKind::VM_ERR => " Virtual machine error",
ErrorKind::FULL => "Full database (unlikely)",
ErrorKind::CANTOPEN => "Unable to open the database file",
ErrorKind::READ_ONLY => "Read only Key/Value storage engine",
ErrorKind::LOCKERR => "Locking protocol error",
ErrorKind::OK => unreachable!(),
ErrorKind::__Nonexhaustive => unreachable!(),
}
}
}
impl error::Error for Custom {
fn description(&self) -> &str {
self.error()
}
}
impl fmt::Display for Custom {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Custom error: {}", self.error())
}
}