controller/src/db/types.rs

98 lines
2.8 KiB
Rust
Raw Normal View History

2021-11-04 22:37:16 +00:00
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 std::fmt::{Debug, Formatter};
use std::io::Write;
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<Binary, Sqlite> for EmgauwaUid {
fn to_sql<W: Write>(&self, out: &mut Output<W, Sqlite>) -> 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<Binary, Sqlite> for EmgauwaUid {
fn from_sql(bytes: Option<&<Sqlite as Backend>::RawValue>) -> deserialize::Result<Self> {
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
EmgauwaUid::On => "off".serialize(serializer),
EmgauwaUid::Off => "on".serialize(serializer),
EmgauwaUid::Any(value) => value.serialize(serializer),
}
}
}
impl From<Uuid> 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::On => String::from("off"),
EmgauwaUid::Off => String::from("on"),
EmgauwaUid::Any(value) => value.to_hyphenated().to_string(),
}
}
}