use bytes::Bytes;
use serde::{Deserialize, Serialize};
use crate::error::Result;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct State {
pub state_key: String,
pub name: Option<String>,
pub value: serde_json::Value,
pub ttl_ms: Option<u32>,
pub subject: Option<String>,
pub updated_at: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Presence {
pub subject: String,
pub status: String,
pub session_id: Option<String>,
pub connection_id: Option<String>,
pub ttl_ms: Option<u32>,
pub metadata: Option<serde_json::Value>,
pub updated_at: i64,
}
pub fn encode_state(s: &State) -> Result<Bytes> {
Ok(Bytes::from(serde_json::to_vec(s)?))
}
pub fn decode_state(bytes: &[u8]) -> Result<State> {
Ok(serde_json::from_slice(bytes)?)
}
pub fn encode_presence(p: &Presence) -> Result<Bytes> {
Ok(Bytes::from(serde_json::to_vec(p)?))
}
pub fn decode_presence(bytes: &[u8]) -> Result<Presence> {
Ok(serde_json::from_slice(bytes)?)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn state_round_trip() {
let s = State {
state_key: "cursor".into(),
name: Some("cursor position".into()),
value: serde_json::json!({"x": 1, "y": 2}),
ttl_ms: None,
subject: Some("user-1".into()),
updated_at: 1000,
};
let bytes = encode_state(&s).unwrap();
let back = decode_state(&bytes).unwrap();
assert_eq!(back.state_key, "cursor");
}
#[test]
fn presence_round_trip() {
let p = Presence {
subject: "user-1".into(),
status: "online".into(),
session_id: Some("s-1".into()),
connection_id: Some("c-1".into()),
ttl_ms: Some(30_000),
metadata: None,
updated_at: 1000,
};
let bytes = encode_presence(&p).unwrap();
let back = decode_presence(&bytes).unwrap();
assert_eq!(back.status, "online");
}
}