use opentalk_roomserver_signaling::breakout::BREAKOUT_MODULE_ID;
use opentalk_roomserver_types::{breakout::event::BreakoutEvent, core_event::CoreEvent};
use opentalk_roomserver_types_chat::{CHAT_MODULE_ID, event::ChatEvent};
use opentalk_roomserver_types_ping::{PING_MODULE_ID, event::PingEvent};
use opentalk_roomserver_types_polls::{POLLS_MODULE_ID, event::PollsEvent};
use opentalk_roomserver_types_timer::{TIMER_MODULE_ID, TimerEvent};
use opentalk_types_common::modules::{CORE_MODULE_ID, ModuleId};
use serde::{Deserialize, Serialize};
pub use {
opentalk_roomserver_types_e2ee::{E2EE_MODULE_ID, E2eeEvent},
opentalk_roomserver_types_livekit::{
Credentials, LIVEKIT_MODULE_ID, LiveKitError, LiveKitEvent, LiveKitState,
},
};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SignalingEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction_id: Option<u64>,
#[serde(flatten)]
pub content: SignalingModuleEvent,
}
impl SignalingEvent {
pub fn namespace(&self) -> ModuleId {
self.content.namespace()
}
}
impl From<SignalingModuleEvent> for SignalingEvent {
fn from(content: SignalingModuleEvent) -> Self {
Self {
transaction_id: None,
content,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "namespace", content = "content", rename_all = "snake_case")]
pub enum SignalingModuleEvent {
Core(CoreEvent),
Breakout(BreakoutEvent),
Ping(PingEvent),
Chat(ChatEvent),
#[serde(rename = "livekit")]
LiveKit(LiveKitEvent),
E2ee(E2eeEvent),
Timer(TimerEvent),
Polls(PollsEvent),
}
impl SignalingModuleEvent {
pub fn namespace(&self) -> ModuleId {
match self {
Self::Core(_) => CORE_MODULE_ID,
Self::Breakout(_) => BREAKOUT_MODULE_ID,
Self::Ping(_) => PING_MODULE_ID,
Self::Chat(_) => CHAT_MODULE_ID,
Self::LiveKit(_) => LIVEKIT_MODULE_ID,
Self::E2ee(_) => E2EE_MODULE_ID,
Self::Timer(_) => TIMER_MODULE_ID,
Self::Polls(_) => POLLS_MODULE_ID,
}
}
}
#[cfg(test)]
mod tests {
use insta::assert_snapshot;
use opentalk_roomserver_types::{
breakout::event::BreakoutEvent, connection_id::ConnectionId, core_event::CoreEvent,
};
use opentalk_roomserver_types_chat::event::{ChatDisabled, ChatEvent};
use opentalk_roomserver_types_livekit::LiveKitEvent;
use opentalk_roomserver_types_ping::event::PingEvent;
use opentalk_roomserver_types_polls::{
ChoiceId, PollId,
command::{Choices, Vote},
event::PollsEvent,
};
use opentalk_roomserver_types_timer::{
TimerEvent, event::updated_ready_status::UpdatedReadyStatus,
};
use opentalk_types_common::modules::ModuleId;
use opentalk_types_signaling::ParticipantId;
use serde::Deserialize;
use super::SignalingModuleEvent;
use crate::api::event::SignalingEvent;
#[derive(Debug, Clone, Deserialize)]
pub struct NamespaceOnly {
pub namespace: ModuleId,
}
#[test]
fn serialize_event_core() {
let event = SignalingEvent {
transaction_id: None,
content: SignalingModuleEvent::Core(CoreEvent::ParticipantConnected {
participant_id: ParticipantId::from_u128(0x01),
connection_id: ConnectionId::from_u128(0x02),
peer_join_info: Default::default(),
}),
};
let raw = serde_json::to_string_pretty(&event).unwrap();
assert_snapshot!(raw, @r#"
{
"namespace": "core",
"content": {
"participant_connected": {
"participant_id": "00000000-0000-0000-0000-000000000001",
"connection_id": "00000000-0000-0000-0000-000000000002"
}
}
}
"#);
let namespace_only: NamespaceOnly = serde_json::from_str(&raw).unwrap();
assert_eq!(namespace_only.namespace, event.namespace());
}
#[test]
fn serialize_event_breakout() {
let event = SignalingEvent {
transaction_id: None,
content: SignalingModuleEvent::Breakout(BreakoutEvent::Closed),
};
let raw = serde_json::to_string_pretty(&event).unwrap();
assert_snapshot!(raw, @r#"
{
"namespace": "breakout",
"content": {
"message": "closed"
}
}
"#);
let namespace_only: NamespaceOnly = serde_json::from_str(&raw).unwrap();
assert_eq!(namespace_only.namespace, event.namespace());
}
#[test]
fn serialize_event_chat() {
let event = SignalingEvent {
transaction_id: None,
content: SignalingModuleEvent::Chat(ChatEvent::ChatDisabled(ChatDisabled {
issued_by: ParticipantId::from_u128(0x01),
})),
};
let raw = serde_json::to_string_pretty(&event).unwrap();
assert_snapshot!(raw, @r#"
{
"namespace": "chat",
"content": {
"message": "chat_disabled",
"issued_by": "00000000-0000-0000-0000-000000000001"
}
}
"#);
let namespace_only: NamespaceOnly = serde_json::from_str(&raw).unwrap();
assert_eq!(namespace_only.namespace, event.namespace());
}
#[test]
fn serialize_event_ping() {
let event = SignalingEvent {
transaction_id: None,
content: SignalingModuleEvent::Ping(PingEvent::Pong),
};
let raw = serde_json::to_string_pretty(&event).unwrap();
assert_snapshot!(raw, @r#"
{
"namespace": "ping",
"content": {
"message": "pong"
}
}
"#);
let namespace_only: NamespaceOnly = serde_json::from_str(&raw).unwrap();
assert_eq!(namespace_only.namespace, event.namespace());
}
#[test]
fn serialize_event_livekit() {
let event = SignalingEvent {
transaction_id: None,
content: SignalingModuleEvent::LiveKit(LiveKitEvent::MicrophoneRestrictionsDisabled),
};
let raw = serde_json::to_string_pretty(&event).unwrap();
assert_snapshot!(raw, @r#"
{
"namespace": "livekit",
"content": {
"message": "microphone_restrictions_disabled"
}
}
"#);
let namespace_only: NamespaceOnly = serde_json::from_str(&raw).unwrap();
assert_eq!(namespace_only.namespace, event.namespace());
}
#[test]
fn serialize_event_timer() {
let event = SignalingEvent {
transaction_id: None,
content: SignalingModuleEvent::Timer(TimerEvent::UpdatedReadyStatus(
UpdatedReadyStatus {
participant_id: ParticipantId::nil(),
status: true,
},
)),
};
let raw = serde_json::to_string_pretty(&event).unwrap();
assert_snapshot!(raw, @r#"
{
"namespace": "timer",
"content": {
"message": "updated_ready_status",
"participant_id": "00000000-0000-0000-0000-000000000000",
"status": true
}
}
"#);
let namespace_only: NamespaceOnly = serde_json::from_str(&raw).unwrap();
assert_eq!(namespace_only.namespace, event.namespace());
}
#[test]
fn serialize_event_polls() {
let event = SignalingEvent {
transaction_id: None,
content: SignalingModuleEvent::Polls(PollsEvent::Voted(Vote {
poll_id: PollId::nil(),
choices: Choices::Single {
choice_id: ChoiceId::from_u32(0),
},
})),
};
let raw = serde_json::to_string_pretty(&event).unwrap();
assert_snapshot!(raw, @r#"
{
"namespace": "polls",
"content": {
"message": "voted",
"poll_id": "00000000-0000-0000-0000-000000000000",
"choice_id": 0
}
}
"#);
let namespace_only: NamespaceOnly = serde_json::from_str(&raw).unwrap();
assert_eq!(namespace_only.namespace, event.namespace());
}
}