summaryrefslogtreecommitdiff
path: root/protocol/src
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2022-12-31 12:17:35 -0500
committerKjetil Orbekk <kj@orbekk.com>2022-12-31 12:55:45 -0500
commit88366acba07b678466b42829887dcdda4f583686 (patch)
treee3450615a6b4b654ea7106a00cc6b551dd4ddb26 /protocol/src
parentaa6d050b09dfbf3e5be112325e8e8d8a1f4dacf9 (diff)
Add database conversion for bridge types
Diffstat (limited to 'protocol/src')
-rw-r--r--protocol/src/card.rs62
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;