From 88366acba07b678466b42829887dcdda4f583686 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Sat, 31 Dec 2022 12:17:35 -0500 Subject: Add database conversion for bridge types --- protocol/src/card.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'protocol/src') diff --git a/protocol/src/card.rs b/protocol/src/card.rs index 771d5e9..31d389a 100644 --- a/protocol/src/card.rs +++ b/protocol/src/card.rs @@ -1,6 +1,13 @@ use anyhow::anyhow; pub(crate) use serde::{Deserialize, Serialize}; +use sqlx::encode::IsNull; +use sqlx::error::BoxDynError; +use sqlx::postgres::PgArgumentBuffer; +use sqlx::postgres::PgTypeInfo; +use sqlx::Postgres; +use sqlx::postgres::PgValueRef; +use strum_macros::FromRepr; use std::fmt; use strum::EnumCount; use strum::IntoEnumIterator; @@ -18,7 +25,9 @@ use strum_macros::EnumIter; EnumCount, Serialize, Deserialize, + FromRepr, )] +#[repr(u8)] pub enum Suit { Club, Diamond, @@ -36,7 +45,9 @@ pub enum Suit { EnumIter, Serialize, Deserialize, + FromRepr, )] +#[repr(u8)] pub enum Rank { Two = 2, Three, @@ -67,6 +78,57 @@ impl fmt::Display for Suit { } } +impl sqlx::Type for Rank { + fn type_info() -> PgTypeInfo { + >::type_info() + } +} + +impl sqlx::Decode<'_, Postgres> for Rank { + fn decode(value: PgValueRef<'_>) -> Result { + let value = >::decode(value)?; + Ok(Rank::from_repr(u8::try_from(value).expect("domain check")).expect("domain check")) + } +} + +impl sqlx::Encode<'_, Postgres> for Rank { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { + let pg_value = *self as i16; + >::encode_by_ref(&pg_value, buf) + } +} + +impl sqlx::Type for Suit { + fn type_info() -> PgTypeInfo { + <&str as sqlx::Type>::type_info() + } +} + +impl sqlx::Decode<'_, Postgres> for Suit { + fn decode(value: PgValueRef<'_>) -> Result { + let value = <&str as sqlx::Decode>::decode(value)?; + match value { + "club" => Ok(Suit::Club), + "diamond" => Ok(Suit::Diamond), + "heart" => Ok(Suit::Heart), + "spade" => Ok(Suit::Spade), + _ => panic!("invalid suit enum value"), + } + } +} + +impl sqlx::Encode<'_, Postgres> for Suit { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { + let pg_value = match *self { + Suit::Club => "club", + Suit::Diamond => "diamond", + Suit::Heart => "heart", + Suit::Spade => "spade", + }; + <&str as sqlx::Encode<'_, Postgres>>::encode_by_ref(&pg_value, buf) + } +} + impl std::str::FromStr for Suit { type Err = anyhow::Error; -- cgit v1.2.3