From 0fe1990d34329c61b07f2c728546a27a26f2ddd6 Mon Sep 17 00:00:00 2001 From: gwenn Date: Sun, 14 Feb 2016 16:11:59 +0100 Subject: [PATCH 1/4] Fix clippy warnings --- Cargo.toml | 1 + src/error.rs | 100 ++++++++++++++++++++++----------------------- src/functions.rs | 15 ++++--- src/lib.rs | 22 ++++------ src/transaction.rs | 2 +- src/types.rs | 17 ++++---- 6 files changed, 80 insertions(+), 77 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3555180..378eee1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ trace = [] time = "~0.1.0" bitflags = "~0.1" libc = "~0.2" +clippy = {version = "~0.0.41", optional = true} [dev-dependencies] tempdir = "~0.3.4" diff --git a/src/error.rs b/src/error.rs index 3f356f6..8348dcc 100644 --- a/src/error.rs +++ b/src/error.rs @@ -82,84 +82,84 @@ impl From<::std::ffi::NulError> for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - &Error::SqliteFailure(ref err, None) => err.fmt(f), - &Error::SqliteFailure(_, Some(ref s)) => write!(f, "{}", s), - &Error::SqliteSingleThreadedMode => { + match *self { + Error::SqliteFailure(ref err, None) => err.fmt(f), + Error::SqliteFailure(_, Some(ref s)) => write!(f, "{}", s), + Error::SqliteSingleThreadedMode => { write!(f, "SQLite was compiled or configured for single-threaded use only") } - &Error::FromSqlConversionFailure(ref err) => err.fmt(f), - &Error::Utf8Error(ref err) => err.fmt(f), - &Error::NulError(ref err) => err.fmt(f), - &Error::InvalidParameterName(ref name) => write!(f, "Invalid parameter name: {}", name), - &Error::InvalidPath(ref p) => write!(f, "Invalid path: {}", p.to_string_lossy()), - &Error::ExecuteReturnedResults => { + Error::FromSqlConversionFailure(ref err) => err.fmt(f), + Error::Utf8Error(ref err) => err.fmt(f), + Error::NulError(ref err) => err.fmt(f), + Error::InvalidParameterName(ref name) => write!(f, "Invalid parameter name: {}", name), + Error::InvalidPath(ref p) => write!(f, "Invalid path: {}", p.to_string_lossy()), + Error::ExecuteReturnedResults => { write!(f, "Execute returned results - did you mean to call query?") } - &Error::QueryReturnedNoRows => write!(f, "Query returned no rows"), - &Error::GetFromStaleRow => write!(f, "Attempted to get a value from a stale row"), - &Error::InvalidColumnIndex(i) => write!(f, "Invalid column index: {}", i), - &Error::InvalidColumnName(ref name) => write!(f, "Invalid column name: {}", name), - &Error::InvalidColumnType => write!(f, "Invalid column type"), + Error::QueryReturnedNoRows => write!(f, "Query returned no rows"), + Error::GetFromStaleRow => write!(f, "Attempted to get a value from a stale row"), + Error::InvalidColumnIndex(i) => write!(f, "Invalid column index: {}", i), + Error::InvalidColumnName(ref name) => write!(f, "Invalid column name: {}", name), + Error::InvalidColumnType => write!(f, "Invalid column type"), #[cfg(feature = "functions")] - &Error::InvalidFunctionParameterType => write!(f, "Invalid function parameter type"), + Error::InvalidFunctionParameterType => write!(f, "Invalid function parameter type"), #[cfg(feature = "functions")] - &Error::UserFunctionError(ref err) => err.fmt(f), + Error::UserFunctionError(ref err) => err.fmt(f), } } } impl error::Error for Error { fn description(&self) -> &str { - match self { - &Error::SqliteFailure(ref err, None) => err.description(), - &Error::SqliteFailure(_, Some(ref s)) => s, - &Error::SqliteSingleThreadedMode => { + match *self { + Error::SqliteFailure(ref err, None) => err.description(), + Error::SqliteFailure(_, Some(ref s)) => s, + Error::SqliteSingleThreadedMode => { "SQLite was compiled or configured for single-threaded use only" } - &Error::FromSqlConversionFailure(ref err) => err.description(), - &Error::Utf8Error(ref err) => err.description(), - &Error::InvalidParameterName(_) => "invalid parameter name", - &Error::NulError(ref err) => err.description(), - &Error::InvalidPath(_) => "invalid path", - &Error::ExecuteReturnedResults => { + Error::FromSqlConversionFailure(ref err) => err.description(), + Error::Utf8Error(ref err) => err.description(), + Error::InvalidParameterName(_) => "invalid parameter name", + Error::NulError(ref err) => err.description(), + Error::InvalidPath(_) => "invalid path", + Error::ExecuteReturnedResults => { "execute returned results - did you mean to call query?" } - &Error::QueryReturnedNoRows => "query returned no rows", - &Error::GetFromStaleRow => "attempted to get a value from a stale row", - &Error::InvalidColumnIndex(_) => "invalid column index", - &Error::InvalidColumnName(_) => "invalid column name", - &Error::InvalidColumnType => "invalid column type", + Error::QueryReturnedNoRows => "query returned no rows", + Error::GetFromStaleRow => "attempted to get a value from a stale row", + Error::InvalidColumnIndex(_) => "invalid column index", + Error::InvalidColumnName(_) => "invalid column name", + Error::InvalidColumnType => "invalid column type", #[cfg(feature = "functions")] - &Error::InvalidFunctionParameterType => "invalid function parameter type", + Error::InvalidFunctionParameterType => "invalid function parameter type", #[cfg(feature = "functions")] - &Error::UserFunctionError(ref err) => err.description(), + Error::UserFunctionError(ref err) => err.description(), } } fn cause(&self) -> Option<&error::Error> { - match self { - &Error::SqliteFailure(ref err, _) => Some(err), - &Error::SqliteSingleThreadedMode => None, - &Error::FromSqlConversionFailure(ref err) => Some(&**err), - &Error::Utf8Error(ref err) => Some(err), - &Error::NulError(ref err) => Some(err), - &Error::InvalidParameterName(_) => None, - &Error::InvalidPath(_) => None, - &Error::ExecuteReturnedResults => None, - &Error::QueryReturnedNoRows => None, - &Error::GetFromStaleRow => None, - &Error::InvalidColumnIndex(_) => None, - &Error::InvalidColumnName(_) => None, - &Error::InvalidColumnType => None, + match *self { + Error::SqliteFailure(ref err, _) => Some(err), + Error::SqliteSingleThreadedMode => None, + Error::FromSqlConversionFailure(ref err) => Some(&**err), + Error::Utf8Error(ref err) => Some(err), + Error::NulError(ref err) => Some(err), + Error::InvalidParameterName(_) => None, + Error::InvalidPath(_) => None, + Error::ExecuteReturnedResults => None, + Error::QueryReturnedNoRows => None, + Error::GetFromStaleRow => None, + Error::InvalidColumnIndex(_) => None, + Error::InvalidColumnName(_) => None, + Error::InvalidColumnType => None, #[cfg(feature = "functions")] - &Error::InvalidFunctionParameterType => None, + Error::InvalidFunctionParameterType => None, #[cfg(feature = "functions")] - &Error::UserFunctionError(ref err) => Some(&**err), + Error::UserFunctionError(ref err) => Some(&**err), } } } diff --git a/src/functions.rs b/src/functions.rs index 49e0032..e00221a 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -88,9 +88,10 @@ raw_to_impl!(c_double, sqlite3_result_double); impl<'a> ToResult for bool { unsafe fn set_result(&self, ctx: *mut sqlite3_context) { - match *self { - true => ffi::sqlite3_result_int(ctx, 1), - _ => ffi::sqlite3_result_int(ctx, 0), + if *self { + ffi::sqlite3_result_int(ctx, 1) + } else { + ffi::sqlite3_result_int(ctx, 0) } } } @@ -214,7 +215,7 @@ impl FromValue for String { unsafe fn parameter_value(v: *mut sqlite3_value) -> Result { let c_text = ffi::sqlite3_value_text(v); if c_text.is_null() { - Ok("".to_string()) + Ok("".to_owned()) } else { let c_slice = CStr::from_ptr(c_text as *const c_char).to_bytes(); let utf8_str = try!(str::from_utf8(c_slice)); @@ -250,7 +251,7 @@ impl FromValue for Option { if sqlite3_value_type(v) == ffi::SQLITE_NULL { Ok(None) } else { - FromValue::parameter_value(v).map(|t| Some(t)) + FromValue::parameter_value(v).map(Some) } } @@ -274,6 +275,10 @@ impl<'a> Context<'a> { pub fn len(&self) -> usize { self.args.len() } + /// Returns `true` when there is no argument. + pub fn is_empty(&self) -> bool { + self.args.is_empty() + } /// Returns the `idx`th argument as a `T`. /// diff --git a/src/lib.rs b/src/lib.rs index f81926b..9d1c7d6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,9 @@ //! } //! } //! ``` +#![cfg_attr(feature="clippy", feature(plugin))] +#![cfg_attr(feature="clippy", plugin(clippy))] + extern crate libc; extern crate libsqlite3_sys as ffi; #[macro_use] @@ -99,7 +102,7 @@ pub type Result = result::Result; unsafe fn errmsg_to_string(errmsg: *const c_char) -> String { let c_slice = CStr::from_ptr(errmsg).to_bytes(); let utf8_str = str::from_utf8(c_slice); - utf8_str.unwrap_or("Invalid string encoding").to_string() + utf8_str.unwrap_or("Invalid string encoding").to_owned() } fn str_to_cstring(s: &str) -> Result { @@ -127,9 +130,9 @@ pub enum DatabaseName<'a> { // impl to avoid dead code warnings. #[cfg(any(feature = "backup", feature = "blob"))] impl<'a> DatabaseName<'a> { - fn to_cstring(self) -> Result { + fn to_cstring(&self) -> Result { use self::DatabaseName::{Main, Temp, Attached}; - match self { + match *self { Main => str_to_cstring("main"), Temp => str_to_cstring("temp"), Attached(s) => str_to_cstring(s), @@ -234,7 +237,7 @@ impl Connection { /// # Failure /// /// Will return `Err` if the underlying SQLite call fails. - pub fn transaction<'a>(&'a self) -> Result> { + pub fn transaction(&self) -> Result { Transaction::new(self, TransactionBehavior::Deferred) } @@ -245,9 +248,7 @@ impl Connection { /// # Failure /// /// Will return `Err` if the underlying SQLite call fails. - pub fn transaction_with_behavior<'a>(&'a self, - behavior: TransactionBehavior) - -> Result> { + pub fn transaction_with_behavior(&self, behavior: TransactionBehavior) -> Result { Transaction::new(self, behavior) } @@ -572,11 +573,7 @@ impl InnerConnection { // https://github.com/mackyle/sqlite/blob/master/src/mutex_noop.c). const SQLITE_SINGLETHREADED_MUTEX_MAGIC: usize = 8; let mutex_ptr = ffi::sqlite3_mutex_alloc(0); - let is_singlethreaded = if mutex_ptr as usize == SQLITE_SINGLETHREADED_MUTEX_MAGIC { - true - } else { - false - }; + let is_singlethreaded = mutex_ptr as usize == SQLITE_SINGLETHREADED_MUTEX_MAGIC; ffi::sqlite3_mutex_free(mutex_ptr); if is_singlethreaded { return Err(Error::SqliteSingleThreadedMode); @@ -1173,7 +1170,6 @@ impl<'a> RowIndex for &'a str { #[cfg(test)] mod test { - extern crate libsqlite3_sys as ffi; extern crate tempdir; pub use super::*; use self::tempdir::TempDir; diff --git a/src/transaction.rs b/src/transaction.rs index ea09cef..5ef4909 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -89,7 +89,7 @@ impl<'conn> Transaction<'conn> { /// tx.commit() /// } /// ``` - pub fn savepoint<'a>(&'a self) -> Result> { + pub fn savepoint(&self) -> Result { self.conn.execute_batch("SAVEPOINT sp").map(|_| { Transaction { conn: self.conn, diff --git a/src/types.rs b/src/types.rs index c458e01..aca7fad 100644 --- a/src/types.rs +++ b/src/types.rs @@ -102,9 +102,10 @@ raw_to_impl!(c_double, sqlite3_bind_double); impl ToSql for bool { unsafe fn bind_parameter(&self, stmt: *mut sqlite3_stmt, col: c_int) -> c_int { - match *self { - true => ffi::sqlite3_bind_int(stmt, col, 1), - _ => ffi::sqlite3_bind_int(stmt, col, 0), + if *self { + ffi::sqlite3_bind_int(stmt, col, 1) + } else { + ffi::sqlite3_bind_int(stmt, col, 0) } } } @@ -229,7 +230,7 @@ impl FromSql for String { unsafe fn column_result(stmt: *mut sqlite3_stmt, col: c_int) -> Result { let c_text = ffi::sqlite3_column_text(stmt, col); if c_text.is_null() { - Ok("".to_string()) + Ok("".to_owned()) } else { let c_slice = CStr::from_ptr(c_text as *const c_char).to_bytes(); let utf8_str = try!(str::from_utf8(c_slice)); @@ -283,7 +284,7 @@ impl FromSql for Option { if sqlite3_column_type(stmt, col) == ffi::SQLITE_NULL { Ok(None) } else { - FromSql::column_result(stmt, col).map(|t| Some(t)) + FromSql::column_result(stmt, col).map(Some) } } @@ -312,11 +313,11 @@ pub enum Value { impl FromSql for Value { unsafe fn column_result(stmt: *mut sqlite3_stmt, col: c_int) -> Result { match sqlite3_column_type(stmt, col) { - ffi::SQLITE_TEXT => FromSql::column_result(stmt, col).map(|t| Value::Text(t)), + ffi::SQLITE_TEXT => FromSql::column_result(stmt, col).map(Value::Text), ffi::SQLITE_INTEGER => Ok(Value::Integer(ffi::sqlite3_column_int64(stmt, col))), ffi::SQLITE_FLOAT => Ok(Value::Real(ffi::sqlite3_column_double(stmt, col))), ffi::SQLITE_NULL => Ok(Value::Null), - ffi::SQLITE_BLOB => FromSql::column_result(stmt, col).map(|t| Value::Blob(t)), + ffi::SQLITE_BLOB => FromSql::column_result(stmt, col).map(Value::Blob), _ => Err(Error::InvalidColumnType), } } @@ -355,7 +356,7 @@ mod test { let db = checked_memory_handle(); let s = "hello, world!"; - db.execute("INSERT INTO foo(t) VALUES (?)", &[&s.to_string()]).unwrap(); + db.execute("INSERT INTO foo(t) VALUES (?)", &[&s.to_owned()]).unwrap(); let from: String = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap(); assert_eq!(from, s); From aea2f876d53b068d086112395300935aeaf8224e Mon Sep 17 00:00:00 2001 From: gwenn Date: Sun, 14 Feb 2016 16:24:35 +0100 Subject: [PATCH 2/4] Try to fix regression with Rust stable. --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 9d1c7d6..9c0f322 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1172,6 +1172,7 @@ impl<'a> RowIndex for &'a str { mod test { extern crate tempdir; pub use super::*; + use ffi; use self::tempdir::TempDir; pub use std::error::Error as StdError; pub use std::fmt; From 2bd54578f5070c74660035d034e146d7daddddaa Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Tue, 29 Mar 2016 11:54:02 -0400 Subject: [PATCH 3/4] Update clippy version and address new warnings --- Cargo.toml | 2 +- src/error.rs | 17 +++++++++-------- src/lib.rs | 9 ++++++--- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 378eee1..1eb6cd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ trace = [] time = "~0.1.0" bitflags = "~0.1" libc = "~0.2" -clippy = {version = "~0.0.41", optional = true} +clippy = {version = "~0.0.58", optional = true} [dev-dependencies] tempdir = "~0.3.4" diff --git a/src/error.rs b/src/error.rs index 8348dcc..3662d37 100644 --- a/src/error.rs +++ b/src/error.rs @@ -143,18 +143,19 @@ impl error::Error for Error { fn cause(&self) -> Option<&error::Error> { match *self { Error::SqliteFailure(ref err, _) => Some(err), - Error::SqliteSingleThreadedMode => None, Error::FromSqlConversionFailure(ref err) => Some(&**err), Error::Utf8Error(ref err) => Some(err), Error::NulError(ref err) => Some(err), - Error::InvalidParameterName(_) => None, + + Error::SqliteSingleThreadedMode | + Error::InvalidParameterName(_) | + Error::ExecuteReturnedResults | + Error::QueryReturnedNoRows | + Error::GetFromStaleRow | + Error::InvalidColumnIndex(_) | + Error::InvalidColumnName(_) | + Error::InvalidColumnType | Error::InvalidPath(_) => None, - Error::ExecuteReturnedResults => None, - Error::QueryReturnedNoRows => None, - Error::GetFromStaleRow => None, - Error::InvalidColumnIndex(_) => None, - Error::InvalidColumnName(_) => None, - Error::InvalidColumnType => None, #[cfg(feature = "functions")] Error::InvalidFunctionParameterType => None, diff --git a/src/lib.rs b/src/lib.rs index 9c0f322..952ebe0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,9 @@ #![cfg_attr(feature="clippy", feature(plugin))] #![cfg_attr(feature="clippy", plugin(clippy))] +// Clippy complains about SQLite in our doc comments, but they're fine. +#![cfg_attr(feature="clippy", allow(doc_markdown))] + extern crate libc; extern crate libsqlite3_sys as ffi; #[macro_use] @@ -791,10 +794,10 @@ impl<'conn> Statement<'conn> { ffi::sqlite3_reset(self.stmt); match r { ffi::SQLITE_DONE => { - if self.column_count != 0 { - Err(Error::ExecuteReturnedResults) - } else { + if self.column_count == 0 { Ok(self.conn.changes()) + } else { + Err(Error::ExecuteReturnedResults) } } ffi::SQLITE_ROW => Err(Error::ExecuteReturnedResults), From 41fe698cecdda72250d411bb7f78d811db1304b2 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Tue, 29 Mar 2016 14:18:56 -0400 Subject: [PATCH 4/4] Address additional clippy warnings --- src/error.rs | 2 ++ src/functions.rs | 11 ++++++----- src/lib.rs | 10 +++------- src/transaction.rs | 1 + src/types.rs | 10 ++++++++-- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/error.rs b/src/error.rs index 3662d37..ebc79b7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -140,6 +140,7 @@ impl error::Error for Error { } } + #[allow(match_same_arms)] fn cause(&self) -> Option<&error::Error> { match *self { Error::SqliteFailure(ref err, _) => Some(err), @@ -159,6 +160,7 @@ impl error::Error for Error { #[cfg(feature = "functions")] Error::InvalidFunctionParameterType => None, + #[cfg(feature = "functions")] Error::UserFunctionError(ref err) => Some(&**err), } diff --git a/src/functions.rs b/src/functions.rs index e00221a..8fd78f0 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -307,7 +307,7 @@ impl<'a> Context<'a> { ffi::sqlite3_set_auxdata(self.ctx, arg, mem::transmute(boxed), - Some(mem::transmute(free_boxed_value::))) + Some(free_boxed_value::)) }; } @@ -480,7 +480,7 @@ impl InnerConnection { Some(call_boxed_closure::), None, None, - Some(mem::transmute(free_boxed_value::))) + Some(free_boxed_value::)) }; self.decode_result(r) } @@ -597,7 +597,7 @@ impl InnerConnection { None, Some(call_boxed_step::), Some(call_boxed_final::), - Some(mem::transmute(free_boxed_value::))) + Some(free_boxed_value::)) }; self.decode_result(r) } @@ -626,6 +626,7 @@ mod test { use std::collections::HashMap; use libc::c_double; use self::regex::Regex; + use std::f64::EPSILON; use {Connection, Error, Result}; use functions::{Aggregate, Context}; @@ -642,7 +643,7 @@ mod test { db.create_scalar_function("half", 1, true, half).unwrap(); let result: Result = db.query_row("SELECT half(6)", &[], |r| r.get(0)); - assert_eq!(3f64, result.unwrap()); + assert!((3f64 - result.unwrap()).abs() < EPSILON); } #[test] @@ -650,7 +651,7 @@ mod test { let db = Connection::open_in_memory().unwrap(); db.create_scalar_function("half", 1, true, half).unwrap(); let result: Result = db.query_row("SELECT half(6)", &[], |r| r.get(0)); - assert_eq!(3f64, result.unwrap()); + assert!((3f64 - result.unwrap()).abs() < EPSILON); db.remove_function("half", 1).unwrap(); let result: Result = db.query_row("SELECT half(6)", &[], |r| r.get(0)); diff --git a/src/lib.rs b/src/lib.rs index 952ebe0..930e1c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,9 +53,6 @@ #![cfg_attr(feature="clippy", feature(plugin))] #![cfg_attr(feature="clippy", plugin(clippy))] -// Clippy complains about SQLite in our doc comments, but they're fine. -#![cfg_attr(feature="clippy", allow(doc_markdown))] - extern crate libc; extern crate libsqlite3_sys as ffi; #[macro_use] @@ -1224,10 +1221,9 @@ mod test { #[test] fn test_open_with_flags() { - for bad_flags in [OpenFlags::empty(), - SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_READ_WRITE, - SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_CREATE] - .iter() { + for bad_flags in &[OpenFlags::empty(), + SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_READ_WRITE, + SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_CREATE] { assert!(Connection::open_in_memory_with_flags(*bad_flags).is_err()); } } diff --git a/src/transaction.rs b/src/transaction.rs index 5ef4909..e72add4 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -174,6 +174,7 @@ impl<'conn> Drop for Transaction<'conn> { } #[cfg(test)] +#[cfg_attr(feature="clippy", allow(similar_names))] mod test { use Connection; diff --git a/src/types.rs b/src/types.rs index aca7fad..4a92d72 100644 --- a/src/types.rs +++ b/src/types.rs @@ -328,11 +328,13 @@ impl FromSql for Value { } #[cfg(test)] +#[cfg_attr(feature="clippy", allow(similar_names))] mod test { use Connection; use super::time; use Error; use libc::{c_int, c_double}; + use std::f64::EPSILON; fn checked_memory_handle() -> Connection { let db = Connection::open_in_memory().unwrap(); @@ -403,6 +405,7 @@ mod test { } #[test] + #[cfg_attr(feature="clippy", allow(cyclomatic_complexity))] fn test_mismatched_types() { fn is_invalid_column_type(err: Error) -> bool { match err { @@ -426,7 +429,7 @@ mod test { assert_eq!(vec![1, 2], row.get_checked::>(0).unwrap()); assert_eq!("text", row.get_checked::(1).unwrap()); assert_eq!(1, row.get_checked::(2).unwrap()); - assert_eq!(1.5, row.get_checked::(3).unwrap()); + assert!((1.5 - row.get_checked::(3).unwrap()).abs() < EPSILON); assert!(row.get_checked::>(4).unwrap().is_none()); assert!(row.get_checked::>(4).unwrap().is_none()); assert!(row.get_checked::>(4).unwrap().is_none()); @@ -491,7 +494,10 @@ mod test { assert_eq!(Value::Text(String::from("text")), row.get_checked::(1).unwrap()); assert_eq!(Value::Integer(1), row.get_checked::(2).unwrap()); - assert_eq!(Value::Real(1.5), row.get_checked::(3).unwrap()); + match row.get_checked::(3).unwrap() { + Value::Real(val) => assert!((1.5 - val).abs() < EPSILON), + x => panic!("Invalid Value {:?}", x), + } assert_eq!(Value::Null, row.get_checked::(4).unwrap()); } }