diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2022-12-31 12:17:35 -0500 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2022-12-31 12:55:45 -0500 |
commit | 88366acba07b678466b42829887dcdda4f583686 (patch) | |
tree | e3450615a6b4b654ea7106a00cc6b551dd4ddb26 /protocol/src | |
parent | aa6d050b09dfbf3e5be112325e8e8d8a1f4dacf9 (diff) |
Add database conversion for bridge types
Diffstat (limited to 'protocol/src')
-rw-r--r-- | protocol/src/card.rs | 62 |
1 files changed, 62 insertions, 0 deletions
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<Postgres> for Rank { + fn type_info() -> PgTypeInfo { + <i16 as sqlx::Type<Postgres>>::type_info() + } +} + +impl sqlx::Decode<'_, Postgres> for Rank { + fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> { + let value = <i16 as sqlx::Decode<Postgres>>::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; + <i16 as sqlx::Encode<'_, Postgres>>::encode_by_ref(&pg_value, buf) + } +} + +impl sqlx::Type<Postgres> for Suit { + fn type_info() -> PgTypeInfo { + <&str as sqlx::Type<Postgres>>::type_info() + } +} + +impl sqlx::Decode<'_, Postgres> for Suit { + fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> { + let value = <&str as sqlx::Decode<Postgres>>::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; |