diff options
Diffstat (limited to 'server/src/play.rs')
-rw-r--r-- | server/src/play.rs | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/server/src/play.rs b/server/src/play.rs new file mode 100644 index 0000000..8fe1872 --- /dev/null +++ b/server/src/play.rs @@ -0,0 +1,56 @@ +use async_trait::async_trait; + +use crate::error::BridgeError; + +#[async_trait] +pub trait Journal { + // Append payload to the journal at sequence number `seq`. + async fn append(&mut self, seq: i64, payload: serde_json::Value) -> Result<(), BridgeError>; + + // Fetch all journal entries with sequence number greater or equal to `seq`. + async fn replay(&mut self, seq: i64) -> Result<Vec<serde_json::Value>, BridgeError>; +} + +pub struct Table {} + +#[cfg(test)] +mod test { + use super::*; + + #[derive(Default)] + pub struct TestJournal { + log: Vec<Option<serde_json::Value>>, + } + + #[async_trait] + impl Journal for TestJournal { + async fn append( + &mut self, + seq: i64, + payload: serde_json::Value, + ) -> Result<(), BridgeError> { + if seq != self.log.len() as i64 { + return Err(BridgeError::UpdateConflict(self.log.len() as i64, seq)); + } + self.log.push(Some(payload)); + Ok(()) + } + + async fn replay(&mut self, seq: i64) -> Result<Vec<serde_json::Value>, BridgeError> { + Ok(self.log[seq as usize..] + .into_iter() + .filter_map(|e| e.clone()) + .collect()) + } + } + + #[tokio::test] + async fn test_journal() { + use serde_json::json; + let mut jnl: TestJournal = Default::default(); + assert_eq!(jnl.append(0, json!(10)).await.unwrap(), ()); + assert!(jnl.append(0, json!(0)).await.is_err()); + assert_eq!(jnl.append(1, json!(20)).await.unwrap(), ()); + assert_eq!(jnl.replay(1).await.unwrap(), vec!(json!(20))); + } +} |