diff --git a/src/theme.rs b/src/theme.rs index 8153615..1d553fd 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -56,6 +56,9 @@ impl ToSql for Theme { impl FromSql for Theme { fn from_sql(value: Option<&::RawValue>) -> deserialize::Result { + // See Diesel's documentation on how to implement FromSql for Sqlite, + // especially with regards to the unsafe conversion below. + // http://docs.diesel.rs/diesel/deserialize/trait.FromSql.html let text_ptr = <*const str as FromSql>::from_sql(value)?; let text = unsafe { &*text_ptr }; text.parse().map_err(Into::into) @@ -82,9 +85,15 @@ impl Display for CssClass { #[cfg(test)] mod test { - use super::*; + use std::error::Error; + + use diesel::prelude::*; + use diesel::sql_query; + use diesel::sql_types::Text; use serde_plain; + use super::*; + #[test] fn basic_serialize() { assert_eq!(serde_plain::to_string(&Theme::Red).unwrap(), "red"); @@ -129,21 +138,36 @@ mod test { } #[test] - fn basic_db_roundtrip() { - use diesel::prelude::*; - use diesel::sql_query; - use diesel::sql_types::Text; - - let conn = SqliteConnection::establish(":memory:").unwrap(); + fn basic_db_roundtrip() -> Result<(), Box> { + let conn = SqliteConnection::establish(":memory:")?; #[derive(QueryableByName, PartialEq, Eq, Debug)] struct Row { #[sql_type = "Text"] theme: Theme } - let res: Vec = sql_query("SELECT ? as theme") + let res = sql_query("SELECT ? as theme") .bind::(DeepPurple) - .load(&conn) - .unwrap(); + .load::(&conn)?; assert_eq!(&[ Row { theme: DeepPurple } ], res.as_slice()); + + Ok(()) + } + + #[test] + fn db_invalid_value_gives_error() -> Result<(), Box> { + let conn = SqliteConnection::establish(":memory:")?; + + #[derive(QueryableByName, PartialEq, Eq, Debug)] + struct Row { #[sql_type = "Text"] theme: Theme } + + let res = sql_query("SELECT 'green' as theme") + .load::(&conn); + assert!(res.is_ok()); + + let res = sql_query("SELECT 'blueish-yellow' as theme") + .load::(&conn); + assert!(res.is_err()); + + Ok(()) } }