From df066c611d91e6cfc28a3d2b7b794e6c58bdb90b Mon Sep 17 00:00:00 2001 From: Magnus Hovland Hoff Date: Wed, 19 Sep 2018 22:56:12 +0200 Subject: [PATCH] Add support for using Theme with the database --- src/theme.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/src/theme.rs b/src/theme.rs index 9def318..8153615 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -1,6 +1,15 @@ +use std::io::Write; + +use diesel::backend::Backend; +use diesel::deserialize::{self, FromSql}; +use diesel::serialize::{self, Output, ToSql}; +use diesel::sql_types::Text; +use diesel::sqlite::Sqlite; use seahash; -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Serialize, Deserialize)] // Serde +#[derive(AsExpression, FromSqlRow)] // Diesel #[serde(rename_all="kebab-case")] pub enum Theme { Red, @@ -24,10 +33,11 @@ pub enum Theme { BlueGray, } -forward_display_to_serde!(Theme); - use self::Theme::*; +forward_display_to_serde!(Theme); +forward_from_str_to_serde!(Theme); + pub const THEMES: [Theme; 19] = [Red, Pink, Purple, DeepPurple, Indigo, Blue, LightBlue, Cyan, Teal, Green, LightGreen, Lime, Yellow, Amber, Orange, DeepOrange, Brown, Gray, BlueGray]; @@ -38,6 +48,21 @@ pub fn theme_from_str_hash(x: &str) -> Theme { THEMES[choice] } +impl ToSql for Theme { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + ToSql::::to_sql(&self.to_string(), out) + } +} + +impl FromSql for Theme { + fn from_sql(value: Option<&::RawValue>) -> deserialize::Result { + let text_ptr = <*const str as FromSql>::from_sql(value)?; + let text = unsafe { &*text_ptr }; + text.parse().map_err(Into::into) + } +} + + pub struct CssClass(Theme); impl Theme { @@ -54,6 +79,7 @@ impl Display for CssClass { } } + #[cfg(test)] mod test { use super::*; @@ -79,6 +105,12 @@ mod test { assert_eq!(&Theme::LightGreen.to_string(), "light-green"); } + #[test] + fn basic_from_str() { + let indigo: Theme = "indigo".parse().unwrap(); + assert_eq!(indigo, Theme::Indigo); + } + #[test] fn to_number() { assert_eq!(Theme::Red as i32, 0); @@ -87,7 +119,7 @@ mod test { } #[test] - fn from_str() { + fn from_str_hash() { assert_eq!(theme_from_str_hash("Bartefjes"), Theme::Orange); } @@ -95,4 +127,23 @@ mod test { fn css_class_display() { assert_eq!(&Theme::Red.css_class().to_string(), "theme-red"); } + + #[test] + fn basic_db_roundtrip() { + use diesel::prelude::*; + use diesel::sql_query; + use diesel::sql_types::Text; + + let conn = SqliteConnection::establish(":memory:").unwrap(); + + #[derive(QueryableByName, PartialEq, Eq, Debug)] + struct Row { #[sql_type = "Text"] theme: Theme } + + let res: Vec = sql_query("SELECT ? as theme") + .bind::(DeepPurple) + .load(&conn) + .unwrap(); + + assert_eq!(&[ Row { theme: DeepPurple } ], res.as_slice()); + } }