mirror of
https://github.com/fluencelabs/sqlite-wasm-connector
synced 2025-03-16 06:50:49 +00:00
136 lines
3.4 KiB
Rust
136 lines
3.4 KiB
Rust
use ffi;
|
|
use std::convert::{From, Into};
|
|
use std::{error, fmt};
|
|
|
|
/// An error.
|
|
#[derive(Debug)]
|
|
pub struct Error {
|
|
pub kind: ErrorKind,
|
|
pub message: Option<String>,
|
|
}
|
|
|
|
macro_rules! declare(
|
|
($($left:ident => $right:ident,)*) => (
|
|
/// An error kind.
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub enum ErrorKind {
|
|
$($left = ffi::$right as isize,)*
|
|
Unknown,
|
|
}
|
|
|
|
impl From<isize> for ErrorKind {
|
|
fn from(code: isize) -> ErrorKind {
|
|
match code as ::libc::c_int {
|
|
$(ffi::$right => ErrorKind::$left,)*
|
|
_ => ErrorKind::Unknown,
|
|
}
|
|
}
|
|
}
|
|
);
|
|
);
|
|
|
|
declare!(
|
|
Abort => SQLITE_ABORT,
|
|
Authorization => SQLITE_AUTH,
|
|
Busy => SQLITE_BUSY,
|
|
CantOpen => SQLITE_CANTOPEN,
|
|
Constraint => SQLITE_CONSTRAINT,
|
|
Corruption => SQLITE_CORRUPT,
|
|
Done => SQLITE_DONE,
|
|
Empty => SQLITE_EMPTY,
|
|
Error => SQLITE_ERROR,
|
|
Format => SQLITE_FORMAT,
|
|
Full => SQLITE_FULL,
|
|
Internal => SQLITE_INTERNAL,
|
|
Interruption => SQLITE_INTERRUPT,
|
|
IOError => SQLITE_IOERR,
|
|
Locked => SQLITE_LOCKED,
|
|
Mismatch => SQLITE_MISMATCH,
|
|
Misuse => SQLITE_MISUSE,
|
|
NoLargeFileSupport => SQLITE_NOLFS,
|
|
NoMemory => SQLITE_NOMEM,
|
|
NotDatabase => SQLITE_NOTADB,
|
|
NotFound => SQLITE_NOTFOUND,
|
|
Notice => SQLITE_NOTICE,
|
|
OK => SQLITE_OK,
|
|
Permission => SQLITE_PERM,
|
|
Protocol => SQLITE_PROTOCOL,
|
|
Range => SQLITE_RANGE,
|
|
ReadOnly => SQLITE_READONLY,
|
|
Row => SQLITE_ROW,
|
|
Schema => SQLITE_SCHEMA,
|
|
TooBig => SQLITE_TOOBIG,
|
|
Warning => SQLITE_WARNING,
|
|
);
|
|
|
|
impl<T> From<T> for Error where T: Into<String> {
|
|
#[inline]
|
|
fn from(message: T) -> Error {
|
|
Error { kind: ErrorKind::Unknown, message: Some(message.into()) }
|
|
}
|
|
}
|
|
|
|
impl From<ErrorKind> for Error {
|
|
#[inline]
|
|
fn from(kind: ErrorKind) -> Error {
|
|
Error { kind: kind, message: None }
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Error {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
match self.message {
|
|
Some(ref message) => message.fmt(formatter),
|
|
_ => self.kind.fmt(formatter),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl error::Error for Error {
|
|
fn description(&self) -> &str {
|
|
match self.message {
|
|
Some(ref message) => message,
|
|
_ => "an SQLite error",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ErrorKind {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
match *self {
|
|
ErrorKind::Unknown => write!(formatter, "an unknown SQLite result code"),
|
|
_ => write!(formatter, "SQLite result code {}", *self as isize),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn last(raw: *mut ffi::sqlite3) -> Option<Error> {
|
|
unsafe {
|
|
let code = ffi::sqlite3_errcode(raw);
|
|
if code == ffi::SQLITE_OK {
|
|
return None;
|
|
}
|
|
let message = ffi::sqlite3_errmsg(raw);
|
|
if message.is_null() {
|
|
return None;
|
|
}
|
|
Some(Error {
|
|
kind: ErrorKind::from(code as isize),
|
|
message: Some(c_str_to_string!(message)),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::ErrorKind;
|
|
|
|
#[test]
|
|
fn fmt() {
|
|
assert_eq!(format!("{}", ErrorKind::OK),
|
|
String::from("SQLite result code 0"));
|
|
assert_eq!(format!("{}", ErrorKind::from(777)),
|
|
String::from("an unknown SQLite result code"));
|
|
}
|
|
}
|