summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2023-01-02 16:57:00 -0500
committerKjetil Orbekk <kj@orbekk.com>2023-01-02 16:57:00 -0500
commit0f7dacea15d6e22123c3290c52515a772fc7ee92 (patch)
tree75af47d988e6b4dca4466898bb73cc0bc30fc171 /server/src
parent29dc8af0d9e01274eb1c520ea174e8a16f316562 (diff)
Switch Table trait to use generics
Diffstat (limited to 'server/src')
-rw-r--r--server/src/table.rs41
1 files changed, 21 insertions, 20 deletions
diff --git a/server/src/table.rs b/server/src/table.rs
index 55fa8fb..1dc0fb7 100644
--- a/server/src/table.rs
+++ b/server/src/table.rs
@@ -20,14 +20,14 @@ pub trait Table {
async fn bid(
self: Box<Self>,
bid: Bid,
- ) -> Result<Box<dyn Table + Send>, BridgeError>;
+ ) -> Result<Box<Self>, BridgeError>;
async fn play(
self: Box<Self>,
card: Card,
- ) -> Result<Box<dyn Table + Send>, BridgeError>;
+ ) -> Result<Box<Self>, BridgeError>;
async fn new_deal(
self: Box<Self>,
- ) -> Result<Box<dyn Table + Send>, BridgeError>;
+ ) -> Result<Box<Self>, BridgeError>;
}
pub struct InMemoryTable {
@@ -51,7 +51,7 @@ impl Table for InMemoryTable {
async fn bid(
self: Box<Self>,
bid: Bid,
- ) -> Result<Box<dyn Table + Send>, BridgeError> {
+ ) -> Result<Box<Self>, BridgeError> {
let game = match self.state {
TableState::Game(game) => game,
_ => {
@@ -65,7 +65,7 @@ impl Table for InMemoryTable {
async fn play(
self: Box<Self>,
card: Card,
- ) -> Result<Box<dyn Table + Send>, BridgeError> {
+ ) -> Result<Box<Self>, BridgeError> {
let game = match self.state {
TableState::Game(game) => game,
_ => {
@@ -78,16 +78,16 @@ impl Table for InMemoryTable {
async fn new_deal(
self: Box<Self>,
- ) -> Result<Box<dyn Table + Send>, BridgeError> {
+ ) -> Result<Box<Self>, BridgeError> {
Ok(Box::new(Self {
state: GameState::new(random(), random()).into(),
}))
}
}
-pub async fn advance_play(
- table: Box<dyn Table>,
-) -> Result<Box<dyn Table + Send>, BridgeError> {
+pub async fn advance_play<T: Table + Send>(
+ table: Box<T>,
+) -> Result<Box<T>, BridgeError> {
let game = match table.state() {
TableState::Game(game) => game,
_ => return Err(BridgeError::InvalidRequest("no game".to_string())),
@@ -115,21 +115,21 @@ pub async fn advance_play(
table
}
-pub struct DbTable {
+pub struct DbTable<Inner: Table> {
db: PgPool,
id: Uuid,
- pub inner: Box<dyn Table + Send>,
+ pub inner: Box<Inner>,
}
-impl DbTable {
- pub async fn new(db: PgPool, id: Uuid) -> Result<Self, BridgeError> {
+impl<Inner: Table> DbTable<Inner> {
+ pub async fn new(db: PgPool, id: Uuid, inner: Inner) -> Result<Self, BridgeError> {
let mut txn = db.begin().await?;
if let Some(_) =
sqlx::query!("select id from bridge_table where id = $1", id)
.fetch_optional(&mut txn)
.await?
{
- return Self::restore(db, txn, id).await;
+ return Self::restore(db, txn, id, inner).await;
}
sqlx::query!("insert into bridge_table (id) values($1)", id)
@@ -140,7 +140,7 @@ impl DbTable {
Ok(Self {
db,
id,
- inner: Box::new(InMemoryTable::new()),
+ inner: Box::new(inner),
})
}
@@ -148,18 +148,19 @@ impl DbTable {
db: PgPool,
txn: Transaction<'_, Postgres>,
id: Uuid,
+ inner: Inner,
) -> Result<Self, BridgeError> {
txn.rollback().await?;
Ok(Self {
db,
id,
- inner: Box::new(InMemoryTable::new()),
+ inner: Box::new(inner),
})
}
}
#[async_trait]
-impl Table for DbTable {
+impl<Inner: Table + Send> Table for DbTable<Inner> {
fn state(&self) -> &TableState {
self.inner.state()
}
@@ -167,7 +168,7 @@ impl Table for DbTable {
async fn bid(
self: Box<Self>,
bid: Bid,
- ) -> Result<Box<dyn Table + Send>, BridgeError> {
+ ) -> Result<Box<Self>, BridgeError> {
Ok(Box::new(Self {
inner: self.inner.bid(bid).await?,
..*self
@@ -177,7 +178,7 @@ impl Table for DbTable {
async fn play(
self: Box<Self>,
card: Card,
- ) -> Result<Box<dyn Table + Send>, BridgeError> {
+ ) -> Result<Box<Self>, BridgeError> {
Ok(Box::new(Self {
inner: self.inner.play(card).await?,
..*self
@@ -186,7 +187,7 @@ impl Table for DbTable {
async fn new_deal(
self: Box<Self>,
- ) -> Result<Box<dyn Table + Send>, BridgeError> {
+ ) -> Result<Box<Self>, BridgeError> {
let inner = self.inner.new_deal().await?;
let deal: Deal = random();