use serde::{Deserialize, Serialize};
pub const ROOMS_TOPIC: &str = "huddle-rooms-v1";
pub const ROOM_TOPIC_PREFIX: &str = "huddle-room-";
pub fn room_topic(room_id: &str) -> String {
format!("{ROOM_TOPIC_PREFIX}{room_id}")
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RoomAnnouncement {
pub room_id: String,
pub name: String,
pub encrypted: bool,
pub passphrase_salt: Option<Vec<u8>>,
pub member_count: u32,
pub creator_fingerprint: String,
pub announced_at: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RoomMessage {
MemberAnnounce {
sender_fingerprint: String,
wrapped_session_key: Option<String>,
},
SessionKeyRequest {
requester_fingerprint: String,
},
Encrypted {
sender_fingerprint: String,
session_id: String,
ciphertext_b64: String,
},
Plain {
sender_fingerprint: String,
body: String,
},
MemberLeave {
sender_fingerprint: String,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn room_announcement_round_trip() {
let ann = RoomAnnouncement {
room_id: "rid".into(),
name: "general".into(),
encrypted: true,
passphrase_salt: Some(vec![1, 2, 3, 4]),
member_count: 3,
creator_fingerprint: "creator-fp".into(),
announced_at: 100,
};
let json = serde_json::to_vec(&ann).unwrap();
let back: RoomAnnouncement = serde_json::from_slice(&json).unwrap();
assert_eq!(back.name, "general");
assert_eq!(back.passphrase_salt, Some(vec![1, 2, 3, 4]));
}
#[test]
fn room_message_variants_round_trip() {
let msgs = vec![
RoomMessage::MemberAnnounce {
sender_fingerprint: "fp".into(),
wrapped_session_key: Some("base64data".into()),
},
RoomMessage::Plain {
sender_fingerprint: "fp".into(),
body: "hi".into(),
},
RoomMessage::Encrypted {
sender_fingerprint: "fp".into(),
session_id: "sid".into(),
ciphertext_b64: "ct".into(),
},
RoomMessage::SessionKeyRequest {
requester_fingerprint: "fp".into(),
},
RoomMessage::MemberLeave {
sender_fingerprint: "fp".into(),
},
];
for m in msgs {
let json = serde_json::to_vec(&m).unwrap();
let back: RoomMessage = serde_json::from_slice(&json).unwrap();
assert_eq!(format!("{m:?}"), format!("{back:?}"));
}
}
#[test]
fn room_topic_format() {
assert_eq!(room_topic("abc123"), "huddle-room-abc123");
}
}