use std::fmt::{Debug, Formatter}; use std::io::Write; use diesel::backend::Backend; use diesel::deserialize::FromSql; use diesel::serialize::{IsNull, Output, ToSql}; use diesel::sql_types::Binary; use diesel::sqlite::Sqlite; use diesel::{deserialize, serialize}; use serde::{Serialize, Serializer}; use uuid::Uuid; #[derive(AsExpression, FromSqlRow, PartialEq, Clone)] #[sql_type = "Binary"] pub enum EmgauwaUid { On, Off, Any(Uuid), } impl Default for EmgauwaUid { fn default() -> Self { EmgauwaUid::Any(Uuid::new_v4()) } } impl Debug for EmgauwaUid { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { EmgauwaUid::On => "on".fmt(f), EmgauwaUid::Off => "off".fmt(f), EmgauwaUid::Any(value) => value.fmt(f), } } } impl ToSql for EmgauwaUid { fn to_sql(&self, out: &mut Output) -> serialize::Result { match self { EmgauwaUid::On => out.write_all(&[1])?, EmgauwaUid::Off => out.write_all(&[0])?, EmgauwaUid::Any(_) => out.write_all(Uuid::from(self).as_bytes())?, } Ok(IsNull::No) } } impl FromSql for EmgauwaUid { fn from_sql(bytes: Option<&::RawValue>) -> deserialize::Result { match bytes { None => Ok(EmgauwaUid::default()), Some(value) => match value.read_blob() { [0] => Ok(EmgauwaUid::Off), [1] => Ok(EmgauwaUid::On), value_bytes => Ok(EmgauwaUid::Any(Uuid::from_slice(value_bytes).unwrap())), }, } } } impl Serialize for EmgauwaUid { fn serialize(&self, serializer: S) -> Result where S: Serializer, { String::from(self).serialize(serializer) } } impl From for EmgauwaUid { fn from(uid: Uuid) -> EmgauwaUid { match uid.as_u128() { 0 => EmgauwaUid::Off, 1 => EmgauwaUid::On, _ => EmgauwaUid::Any(uid), } } } impl From<&EmgauwaUid> for Uuid { fn from(emgauwa_uid: &EmgauwaUid) -> Uuid { match emgauwa_uid { EmgauwaUid::On => uuid::Uuid::from_u128(1), EmgauwaUid::Off => uuid::Uuid::from_u128(0), EmgauwaUid::Any(value) => *value, } } } impl From<&EmgauwaUid> for String { fn from(emgauwa_uid: &EmgauwaUid) -> String { match emgauwa_uid { EmgauwaUid::Off => String::from("off"), EmgauwaUid::On => String::from("on"), EmgauwaUid::Any(value) => value.to_hyphenated().to_string(), } } }