o_sfu_protocol/
host_bridge.rs1use std::{borrow::Cow, collections::BTreeMap};
2
3use serde::{Serialize, Serializer};
4
5use crate::{
6 bundle_api::{
7 BundleBroadcastUpdate, BundleDisconnectUpdate, BundleRemoteMediaUpdate,
8 BundleSessionInfoSnapshotById, BundleUpdate, bundle_session_info_key,
9 },
10 core::ProtocolEvent,
11 shared::{JsonPayload, RecordingStateUpdate, UserId, UserInfo},
12 signaling::TrackBinding,
13};
14
15#[derive(Serialize)]
16#[serde(tag = "name", content = "payload", rename_all = "snake_case")]
17enum BundleUpdateRef<'a> {
18 RemoteMedia {
19 bindings: &'a [TrackBinding],
20 },
21 Broadcast {
22 #[serde(rename = "senderId")]
23 sender_id: &'a UserId,
24 message: &'a JsonPayload,
25 },
26 Disconnect {
27 #[serde(rename = "sessionId")]
28 user_id: &'a UserId,
29 },
30 #[serde(rename = "info_change")]
31 SessionInfoChange(BTreeMap<Cow<'a, str>, &'a UserInfo>),
32 ChannelInfoChange(&'a RecordingStateUpdate),
33}
34
35#[must_use]
36pub fn project_protocol_event(event: ProtocolEvent) -> BundleUpdate {
37 match event {
38 ProtocolEvent::TrackSnapshot { bindings } => {
39 BundleUpdate::RemoteMedia(BundleRemoteMediaUpdate { bindings })
40 }
41 ProtocolEvent::PeerSnapshot { peers } => BundleUpdate::SessionInfoChange(
42 peers
43 .into_iter()
44 .map(|peer| (bundle_session_info_key(&peer.user_id), peer.info))
45 .collect::<BundleSessionInfoSnapshotById>(),
46 ),
47 ProtocolEvent::PeerInfo { user_id, info } => BundleUpdate::SessionInfoChange(
48 BundleSessionInfoSnapshotById::from([(bundle_session_info_key(&user_id), info)]),
49 ),
50 ProtocolEvent::PeerLeft { user_id } => {
51 BundleUpdate::Disconnect(BundleDisconnectUpdate { user_id })
52 }
53 ProtocolEvent::Broadcast { sender_id, message } => {
54 BundleUpdate::Broadcast(BundleBroadcastUpdate { sender_id, message })
55 }
56 ProtocolEvent::RecordingStateChanged { state } => BundleUpdate::ChannelInfoChange(state),
57 }
58}
59
60pub(crate) fn serialize_protocol_event<S>(
61 event: &ProtocolEvent,
62 serializer: S,
63) -> Result<S::Ok, S::Error>
64where
65 S: Serializer,
66{
67 let update = match event {
68 ProtocolEvent::TrackSnapshot { bindings } => BundleUpdateRef::RemoteMedia { bindings },
69 ProtocolEvent::PeerSnapshot { peers } => BundleUpdateRef::SessionInfoChange(
70 peers
71 .iter()
72 .map(|peer| (peer.user_id.path_segment(), &peer.info))
73 .collect(),
74 ),
75 ProtocolEvent::PeerInfo { user_id, info } => {
76 BundleUpdateRef::SessionInfoChange(BTreeMap::from([(user_id.path_segment(), info)]))
77 }
78 ProtocolEvent::PeerLeft { user_id } => BundleUpdateRef::Disconnect { user_id },
79 ProtocolEvent::Broadcast { sender_id, message } => {
80 BundleUpdateRef::Broadcast { sender_id, message }
81 }
82 ProtocolEvent::RecordingStateChanged { state } => BundleUpdateRef::ChannelInfoChange(state),
83 };
84 update.serialize(serializer)
85}
86
87#[cfg(test)]
88#[path = "host_bridge/TESTS/mod.rs"]
89mod tests;