o_sfu_core/engine/room/
definition.rs1use secrecy::{ExposeSecret, SecretSlice};
16use subtle::ConstantTimeEq;
17use uuid::Uuid;
18
19use super::{RoomConfig, RoomRuntimeContext, RoomRuntimePolicy};
20use crate::{
21 RoomWorkerPolicy, RuntimeFeatureFlags,
22 engine::{AvailableFeatures, RoomInstanceId},
23};
24
25const fn persistent_recording_backend_available() -> bool {
30 false
31}
32
33#[derive(Debug, Clone)]
34struct RoomIdentity {
35 uuid: String,
36 issuer: String,
37 key: SecretSlice<u8>,
38}
39
40impl RoomIdentity {
41 fn new(issuer: String, key: SecretSlice<u8>) -> Self {
42 Self {
43 uuid: Uuid::new_v4().to_string(),
44 issuer,
45 key,
46 }
47 }
48}
49
50#[derive(Debug, Clone)]
51pub(crate) struct RoomDefinition {
52 instance_id: RoomInstanceId,
57 room_worker_policy: RoomWorkerPolicy,
58 identity: RoomIdentity,
59 config: RoomConfig,
60 feature_flags: RuntimeFeatureFlags,
61}
62
63impl RoomDefinition {
64 #[must_use]
65 pub(crate) fn new(
66 runtime_context: &RoomRuntimeContext,
67 runtime_policy: &RoomRuntimePolicy,
68 issuer: String,
69 key: SecretSlice<u8>,
70 config: RoomConfig,
71 ) -> Self {
72 Self {
73 instance_id: runtime_context.instance(),
74 room_worker_policy: runtime_policy.room_worker_policy,
75 identity: RoomIdentity::new(issuer, key),
76 config,
77 feature_flags: runtime_policy.feature_flags,
78 }
79 }
80
81 #[must_use]
82 pub(crate) fn matches_reservation(&self, key: &SecretSlice<u8>, config: &RoomConfig) -> bool {
83 bool::from(self.identity.key.expose_secret().ct_eq(key.expose_secret()))
85 && self.config == *config
86 }
87
88 #[must_use]
89 pub(crate) fn uuid(&self) -> &str {
90 &self.identity.uuid
91 }
92
93 #[must_use]
94 pub(crate) fn issuer(&self) -> &str {
95 &self.identity.issuer
96 }
97
98 #[must_use]
99 pub(crate) fn key(&self) -> &SecretSlice<u8> {
100 &self.identity.key
101 }
102
103 #[must_use]
104 pub(crate) fn available_features(&self) -> AvailableFeatures {
105 let recording_available = self.recording_available();
106 AvailableFeatures {
107 rtc: self.config.web_rtc_enabled,
108 transcription: recording_available && self.feature_flags.transcription,
109 audio_recording: recording_available && self.feature_flags.audio_recording,
110 video_recording: recording_available && self.feature_flags.video_recording,
111 }
112 }
113
114 #[must_use]
115 pub(crate) const fn web_rtc_enabled(&self) -> bool {
116 self.config.web_rtc_enabled
117 }
118
119 #[must_use]
120 pub(crate) const fn recording_available(&self) -> bool {
121 if self.config.recording_address.is_none() {
122 return false;
123 }
124 persistent_recording_backend_available()
125 }
126
127 #[cfg(any(test, feature = "testing-transport"))]
128 #[must_use]
129 pub fn recording_address(&self) -> Option<&str> {
130 self.config.recording_address.as_deref()
131 }
132
133 #[must_use]
134 pub(crate) fn room_worker_policy(&self) -> RoomWorkerPolicy {
135 self.room_worker_policy
136 }
137
138 #[must_use]
139 pub(crate) const fn instance_id(&self) -> RoomInstanceId {
140 self.instance_id
141 }
142}