diff options
author | Kjetil Orbekk <kj@orbekk.com> | 2023-01-02 16:57:00 -0500 |
---|---|---|
committer | Kjetil Orbekk <kj@orbekk.com> | 2023-01-02 16:57:00 -0500 |
commit | 0f7dacea15d6e22123c3290c52515a772fc7ee92 (patch) | |
tree | 75af47d988e6b4dca4466898bb73cc0bc30fc171 /server/src | |
parent | 29dc8af0d9e01274eb1c520ea174e8a16f316562 (diff) |
Switch Table trait to use generics
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/table.rs | 41 |
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(); |