1use std::error;
2use std::fmt;
3use std::result;
4use crate::vars::*;
5
6pub type Result<T> = result::Result<T, Error>;
8
9#[derive(Debug)]
11pub enum Error {
12 Custom(Custom),
14 Other(Box<dyn error::Error>),
16}
17
18unsafe impl Send for Error {}
19unsafe impl Sync for Error {}
20
21impl From<Custom> for Error {
22 fn from(err: Custom) -> Error {
23 Error::Custom(err)
24 }
25}
26
27impl From<::std::ffi::NulError> for Error {
28 fn from(err: ::std::ffi::NulError) -> Error {
29 Error::Other(Box::new(err))
30 }
31}
32
33impl fmt::Display for Error {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 match *self {
36 Error::Custom(ref c) => write!(f, "Custom error: {}", c),
37 Error::Other(ref e) => write!(f, "Other error: {}", e),
38 }
39 }
40}
41
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub struct Custom {
44 kind: ErrorKind,
45 raw: i32,
46}
47
48#[allow(non_camel_case_types)]
50#[derive(Clone, Debug, PartialEq, Eq)]
51pub enum ErrorKind {
52 OK = 0,
54 NOMEM,
56 ABORT,
58 IOERR,
60 CORRUPT,
62 LOCKED,
64 BUSY,
66 DONE,
68 PERM,
70 NOTIMPLEMENTED,
72 NOTFOUND,
74 NOOP,
76 INVALID,
78 EOF,
80 UNKNOWN,
82 LIMIT,
84 EXISTS,
86 EMPTY,
88 COMPILE_ERR,
90 VM_ERR,
92 FULL,
94 CANTOPEN,
96 READ_ONLY,
98 LOCKERR,
100 #[doc(hidden)]
101 __Nonexhaustive,
102}
103
104impl From<i32> for ErrorKind {
105 fn from(code: i32) -> ErrorKind {
106 match code {
107 UNQLITE_OK => ErrorKind::OK,
108 UNQLITE_NOMEM => ErrorKind::NOMEM,
109 UNQLITE_ABORT => ErrorKind::ABORT,
110 UNQLITE_IOERR => ErrorKind::IOERR,
111 UNQLITE_CORRUPT => ErrorKind::CORRUPT,
112 UNQLITE_LOCKED => ErrorKind::LOCKED,
113 UNQLITE_BUSY => ErrorKind::BUSY,
114 UNQLITE_DONE => ErrorKind::DONE,
115 UNQLITE_PERM => ErrorKind::PERM,
116 UNQLITE_NOTIMPLEMENTED => ErrorKind::NOTIMPLEMENTED,
117 UNQLITE_NOTFOUND => ErrorKind::NOTFOUND,
118 UNQLITE_NOOP => ErrorKind::NOOP,
119 UNQLITE_INVALID => ErrorKind::INVALID,
120 UNQLITE_EOF => ErrorKind::EOF,
121 UNQLITE_UNKNOWN => ErrorKind::UNKNOWN,
122 UNQLITE_LIMIT => ErrorKind::LIMIT,
123 UNQLITE_EXISTS => ErrorKind::EXISTS,
124 UNQLITE_EMPTY => ErrorKind::EMPTY,
125 UNQLITE_COMPILE_ERR => ErrorKind::COMPILE_ERR,
126 UNQLITE_VM_ERR => ErrorKind::VM_ERR,
127 UNQLITE_FULL => ErrorKind::FULL,
128 UNQLITE_CANTOPEN => ErrorKind::CANTOPEN,
129 UNQLITE_READ_ONLY => ErrorKind::READ_ONLY,
130 UNQLITE_LOCKERR => ErrorKind::LOCKERR,
131 _ => ErrorKind::__Nonexhaustive,
132 }
133 }
134}
135
136pub(crate) trait Wrap {
151 fn wrap(self) -> Result<()>;
152}
153
154impl Wrap for i32 {
155 fn wrap(self) -> Result<()> {
156 Custom::from_raw(self)
157 }
158}
159
160impl Custom {
161 pub fn from_raw(result: i32) -> Result<()> {
162 let kind = ErrorKind::from(result);
163 match kind {
164 ErrorKind::OK => Ok(()),
165 _ => Err(Custom {
166 kind: kind,
167 raw: result,
168 }
169 .into()),
170 }
171 }
172
173 pub fn error(&self) -> &str {
174 match self.kind {
175 ErrorKind::NOMEM => "Out of memory",
176 ErrorKind::ABORT => "Another thread have released this instance",
177 ErrorKind::IOERR => "IO error",
178 ErrorKind::CORRUPT => "Corrupt pointer",
179 ErrorKind::LOCKED => "Forbidden Operation",
180 ErrorKind::BUSY => "The database file is locked",
181 ErrorKind::DONE => "Operation done",
182 ErrorKind::PERM => "Permission error",
183 ErrorKind::NOTIMPLEMENTED => {
184 "Method not implemented by the underlying Key/Value storage engine"
185 }
186 ErrorKind::NOTFOUND => "No such record",
187 ErrorKind::NOOP => "No such method",
188 ErrorKind::INVALID => "Invalid parameter",
189 ErrorKind::EOF => "End Of Input",
190 ErrorKind::UNKNOWN => "Unknown configuration option",
191 ErrorKind::LIMIT => "Database limit reached",
192 ErrorKind::EXISTS => "Record exists",
193 ErrorKind::EMPTY => "Empty record",
194 ErrorKind::COMPILE_ERR => "Compilation error",
195 ErrorKind::VM_ERR => " Virtual machine error",
196 ErrorKind::FULL => "Full database (unlikely)",
197 ErrorKind::CANTOPEN => "Unable to open the database file",
198 ErrorKind::READ_ONLY => "Read only Key/Value storage engine",
199 ErrorKind::LOCKERR => "Locking protocol error",
200 ErrorKind::OK => unreachable!(),
201 ErrorKind::__Nonexhaustive => unreachable!(),
202 }
203 }
204}
205
206impl error::Error for Custom {
207 fn description(&self) -> &str {
208 self.error()
209 }
210}
211
212impl fmt::Display for Custom {
213 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
214 write!(f, "Custom error: {}", self.error())
215 }
216}