From 985cde931f95aa0a7b081f8128ece378ebd51535 Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Mon, 8 Jun 2015 18:05:17 -0400 Subject: [PATCH] Treat SQLite result codes as error kinds --- src/error.rs | 97 +++++++++++++++++++++++++++++++++++++++++++-------- src/lib.rs | 11 +++--- src/result.rs | 83 ------------------------------------------- 3 files changed, 88 insertions(+), 103 deletions(-) delete mode 100644 src/result.rs diff --git a/src/error.rs b/src/error.rs index 03e26b2..ddcb6e2 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,33 +1,78 @@ +use libc::c_int; use raw; use std::convert::{From, Into}; use std::fmt::{self, Display, Formatter}; -use ResultCode; - /// An error. #[derive(Debug)] pub struct Error { - pub code: ResultCode, + pub kind: ErrorKind, pub message: Option, } +macro_rules! declare( + ($($left:ident => $right:ident,)*) => ( + /// An error kind. + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + pub enum ErrorKind { + $($left = raw::$right as isize,)* + Unknown, + } + + pub fn kind_from_code(code: c_int) -> ErrorKind { + match code { + $(raw::$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 From for Error where T: Into { #[inline] fn from(message: T) -> Error { - Error { - code: ResultCode::Error, - message: Some(message.into()), - } + Error { kind: ErrorKind::Error, message: Some(message.into()) } } } -impl From for Error { +impl From for Error { #[inline] - fn from(code: ResultCode) -> Error { - Error { - code: code, - message: None, - } + fn from(kind: ErrorKind) -> Error { + Error { kind: kind, message: None } } } @@ -35,7 +80,16 @@ impl Display for Error { fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { match self.message { Some(ref message) => Display::fmt(message, formatter), - None => Display::fmt(&self.code, formatter), + None => Display::fmt(&self.kind, formatter), + } + } +} + +impl Display for ErrorKind { + fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { + match *self { + ErrorKind::Unknown => write!(formatter, "an unknown SQLite result code"), + _ => write!(formatter, "SQLite result code {}", *self as isize), } } } @@ -51,8 +105,21 @@ pub fn last(raw: *mut raw::sqlite3) -> Option { return None; } Some(Error { - code: ::result::code_from_raw(code), + kind: kind_from_code(code), message: Some(c_str_to_string!(message)), }) } } + +#[cfg(test)] +mod tests { + use super::{ErrorKind, kind_from_code}; + + #[test] + fn fmt() { + assert_eq!(format!("{}", ErrorKind::OK), + String::from("SQLite result code 0")); + assert_eq!(format!("{}", kind_from_code(777)), + String::from("an unknown SQLite result code")); + } +} diff --git a/src/lib.rs b/src/lib.rs index 960a787..a423889 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ macro_rules! failure( ($database:expr, $code:expr) => ( match ::error::last($database) { Some(error) => return Err(error), - None => return Err(::Error::from(::result::code_from_raw($code))), + None => return Err(::Error::from(::error::kind_from_code($code))), } ); ); @@ -29,7 +29,7 @@ macro_rules! success( ($result:expr) => ( match $result { ::raw::SQLITE_OK => {}, - code => return Err(::Error::from(::result::code_from_raw(code))), + code => return Err(::Error::from(::error::kind_from_code(code))), } ); ); @@ -64,14 +64,15 @@ macro_rules! c_str_to_string( mod database; mod error; -mod result; mod statement; -pub use error::Error; pub use database::Database; -pub use result::{Result, ResultCode}; +pub use error::{Error, ErrorKind}; pub use statement::{Statement, Binding, Value, State}; +/// A result. +pub type Result = ::std::result::Result; + /// Open a database. #[inline] pub fn open<'l>(path: &std::path::Path) -> Result> { diff --git a/src/result.rs b/src/result.rs deleted file mode 100644 index f84affd..0000000 --- a/src/result.rs +++ /dev/null @@ -1,83 +0,0 @@ -use libc::c_int; -use std::fmt::{self, Display, Formatter}; - -use raw; -use Error; - -/// A result. -pub type Result = ::std::result::Result; - -macro_rules! declare( - ($($left:ident => $right:ident,)*) => ( - /// A result code. - #[derive(Clone, Copy, Debug, PartialEq, Eq)] - pub enum ResultCode { - $($left = raw::$right as isize,)* - Unknown, - } - - pub fn code_from_raw(code: c_int) -> ResultCode { - match code { - $(raw::$right => ResultCode::$left,)* - _ => ResultCode::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 Display for ResultCode { - fn fmt(&self, formatter: &mut Formatter) -> fmt::Result { - match *self { - ResultCode::Unknown => write!(formatter, "an unknown SQLite result code"), - _ => write!(formatter, "SQLite result code {}", *self as isize), - } - } -} - -#[cfg(test)] -mod tests { - use ResultCode; - use super::code_from_raw; - - #[test] - fn fmt() { - assert_eq!(format!("{}", ResultCode::OK), - String::from("SQLite result code 0")); - assert_eq!(format!("{}", code_from_raw(777)), - String::from("an unknown SQLite result code")); - } -}