rivetkit 2.3.0-rc.12

Rust SDK for RivetKit actors, actions, events, queues, and test harnesses
use anyhow::{Context, Result};
use rivetkit_core::{ConnId, StateDelta};
use serde::Serialize;

pub fn state_delta<S: Serialize>(state: &S) -> Result<StateDelta> {
	let mut encoded = Vec::new();
	ciborium::into_writer(state, &mut encoded).context("encode actor state as cbor")?;
	Ok(StateDelta::ActorState(encoded))
}

pub fn state_deltas<S: Serialize>(state: &S) -> Result<Vec<StateDelta>> {
	Ok(vec![state_delta(state)?])
}

pub fn conn_hibernation_delta(conn: ConnId, bytes: Vec<u8>) -> StateDelta {
	StateDelta::ConnHibernation { conn, bytes }
}

pub fn conn_hibernation_removed_delta(conn: ConnId) -> StateDelta {
	StateDelta::ConnHibernationRemoved(conn)
}

#[cfg(test)]
mod tests {
	use anyhow::Result;
	use serde::{Deserialize, Serialize};

	use super::*;

	#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
	struct PersistedState {
		name: String,
		count: u32,
	}

	#[test]
	fn state_deltas_round_trip() -> Result<()> {
		let state = PersistedState {
			name: "alpha".into(),
			count: 7,
		};

		let deltas = state_deltas(&state)?;
		assert_eq!(deltas.len(), 1);

		let StateDelta::ActorState(bytes) = &deltas[0] else {
			panic!("expected actor-state delta");
		};
		let decoded: PersistedState = ciborium::from_reader(bytes.as_slice())
			.context("decode persisted state delta from cbor")?;
		assert_eq!(decoded, state);

		Ok(())
	}
}