1use std::fmt;
2
3use serde::de::{self, Visitor};
4use serde::{Deserialize, Deserializer, Serialize};
5
6use crate::common::formats::{PhantomId, SerializableId, SocketInfo};
7use crate::error;
8use crate::prelude::{PeerId, Token};
9
10#[derive(Serialize, Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
12pub struct MediaId(String);
13
14impl SerializableId for MediaId {
15 fn try_create(media_id: impl Into<String>) -> Result<Self, error::Error>
16 where
17 Self: Sized,
18 {
19 let media_id = media_id.into();
21 if !(media_id.starts_with("vi-") || media_id.starts_with("au-")) {
22 return Err(error::Error::create_local_error(
23 "media_id\'s prefix is \"vi-\" or \"au-\"",
24 ));
25 }
26 if media_id.len() != 39 {
27 return Err(error::Error::create_local_error(
29 "token str's length should be 39",
30 ));
31 }
32 if !media_id.is_ascii() {
33 return Err(error::Error::create_local_error(
34 "token str should be ascii",
35 ));
36 }
37
38 Ok(MediaId(media_id))
39 }
40
41 fn as_str(&self) -> &str {
42 self.0.as_str()
43 }
44
45 fn id(&self) -> String {
46 self.0.clone()
47 }
48
49 fn key(&self) -> &'static str {
50 "media_id"
51 }
52}
53
54struct MediaIdVisitor;
55
56impl<'de> Visitor<'de> for MediaIdVisitor {
57 type Value = MediaId;
58
59 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
60 formatter.write_str("a 39 length str")
61 }
62
63 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
64 where
65 E: de::Error,
66 {
67 let media_id = MediaId::try_create(value);
68 if let Err(error::Error::LocalError(err)) = media_id {
69 return Err(E::custom(format!("fail to deserialize MediaId: {}", err)));
70 } else if let Err(_) = media_id {
71 return Err(E::custom(format!("fail to deserialize MediaId")));
72 }
73
74 Ok(media_id.unwrap())
75 }
76
77 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
78 where
79 E: de::Error,
80 {
81 let media_id = MediaId::try_create(value);
82 if let Err(error::Error::LocalError(err)) = media_id {
83 return Err(E::custom(format!("fail to deserialize MediaId: {}", err)));
84 } else if let Err(_) = media_id {
85 return Err(E::custom(format!("fail to deserialize MediaId")));
86 }
87
88 Ok(media_id.unwrap())
89 }
90}
91
92impl<'de> Deserialize<'de> for MediaId {
93 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
94 where
95 D: Deserializer<'de>,
96 {
97 deserializer.deserialize_identifier(MediaIdVisitor)
98 }
99}
100
101#[derive(Serialize, Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
103pub struct RtcpId(String);
104
105impl SerializableId for RtcpId {
106 fn try_create(rtcp_id: impl Into<String>) -> Result<Self, error::Error>
107 where
108 Self: Sized,
109 {
110 let rtcp_id = rtcp_id.into();
112 if !rtcp_id.starts_with("rc-") {
113 return Err(error::Error::create_local_error(
114 "rtcp_id\'s prefix is \"rc-\"",
115 ));
116 }
117 if rtcp_id.len() != 39 {
118 return Err(error::Error::create_local_error(
120 "token str's length should be 39",
121 ));
122 }
123 if !rtcp_id.is_ascii() {
124 return Err(error::Error::create_local_error(
125 "token str should be ascii",
126 ));
127 }
128
129 Ok(RtcpId(rtcp_id))
130 }
131
132 fn as_str(&self) -> &str {
133 self.0.as_str()
134 }
135
136 fn id(&self) -> String {
137 self.0.clone()
138 }
139
140 fn key(&self) -> &'static str {
141 "rtcp_id"
142 }
143}
144
145struct RtcpIdVisitor;
146
147impl<'de> Visitor<'de> for RtcpIdVisitor {
148 type Value = RtcpId;
149
150 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
151 formatter.write_str("a 39 length str")
152 }
153
154 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
155 where
156 E: de::Error,
157 {
158 let media_id = RtcpId::try_create(value);
159 if let Err(error::Error::LocalError(err)) = media_id {
160 return Err(E::custom(format!("fail to deserialize RtcpId: {}", err)));
161 } else if let Err(_) = media_id {
162 return Err(E::custom(format!("fail to deserialize RtcpId")));
163 }
164
165 Ok(media_id.unwrap())
166 }
167
168 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
169 where
170 E: de::Error,
171 {
172 let media_id = RtcpId::try_create(value);
173 if let Err(error::Error::LocalError(err)) = media_id {
174 return Err(E::custom(format!("fail to deserialize RtcpId: {}", err)));
175 } else if let Err(_) = media_id {
176 return Err(E::custom(format!("fail to deserialize RtcpId")));
177 }
178
179 Ok(media_id.unwrap())
180 }
181}
182
183impl<'de> Deserialize<'de> for RtcpId {
184 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
185 where
186 D: Deserializer<'de>,
187 {
188 deserializer.deserialize_identifier(RtcpIdVisitor)
189 }
190}
191
192#[derive(Serialize, Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
194pub struct MediaConnectionId(String);
195
196impl MediaConnectionId {
197 pub fn as_str(&self) -> &str {
198 self.0.as_str()
199 }
200
201 pub fn try_create(media_connection_id: impl Into<String>) -> Result<Self, error::Error>
202 where
203 Self: Sized,
204 {
205 let media_connection_id = media_connection_id.into();
207 if !media_connection_id.starts_with("mc-") {
208 return Err(error::Error::create_local_error(
209 "media_connection_id\'s prefix is \"mc-\"",
210 ));
211 }
212 if media_connection_id.len() != 39 {
213 return Err(error::Error::create_local_error(
215 "token str's length should be 39",
216 ));
217 }
218 if !media_connection_id.is_ascii() {
219 return Err(error::Error::create_local_error(
220 "token str should be ascii",
221 ));
222 }
223
224 Ok(MediaConnectionId(media_connection_id))
225 }
226}
227
228struct MediaConnectionIdVisitor;
229
230impl<'de> Visitor<'de> for MediaConnectionIdVisitor {
231 type Value = MediaConnectionId;
232
233 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
234 formatter.write_str("a 39 length str")
235 }
236
237 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
238 where
239 E: de::Error,
240 {
241 let media_connection_id = MediaConnectionId::try_create(value);
242 if let Err(error::Error::LocalError(err)) = media_connection_id {
243 return Err(E::custom(format!("fail to deserialize MediaId: {}", err)));
244 } else if let Err(_) = media_connection_id {
245 return Err(E::custom(format!("fail to deserialize MediaId")));
246 }
247
248 Ok(media_connection_id.unwrap())
249 }
250
251 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
252 where
253 E: de::Error,
254 {
255 let media_connection_id = MediaConnectionId::try_create(value);
256 if let Err(error::Error::LocalError(err)) = media_connection_id {
257 return Err(E::custom(format!("fail to deserialize MediaId: {}", err)));
258 } else if let Err(_) = media_connection_id {
259 return Err(E::custom(format!("fail to deserialize MediaId")));
260 }
261
262 Ok(media_connection_id.unwrap())
263 }
264}
265
266impl<'de> Deserialize<'de> for MediaConnectionId {
267 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
268 where
269 D: Deserializer<'de>,
270 {
271 deserializer.deserialize_identifier(MediaConnectionIdVisitor)
272 }
273}
274
275#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
276pub(crate) struct CreateMediaOptions {
277 pub is_video: bool,
278}
279
280#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
284pub struct CallQuery {
285 pub peer_id: PeerId,
287 pub token: Token,
289 pub target_id: PeerId,
291 #[serde(skip_serializing_if = "Option::is_none")]
294 pub constraints: Option<Constraints>,
295 #[serde(skip_serializing_if = "Option::is_none")]
298 pub redirect_params: Option<RedirectParameters>,
299}
300
301#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
303#[allow(non_snake_case)]
304pub struct Constraints {
305 pub video: bool,
307 #[serde(skip_serializing_if = "Option::is_none")]
309 pub videoReceiveEnabled: Option<bool>,
310 pub audio: bool,
312 #[serde(skip_serializing_if = "Option::is_none")]
314 pub audioReceiveEnabled: Option<bool>,
315 #[serde(skip_serializing_if = "Option::is_none")]
317 pub video_params: Option<MediaParams>,
318 #[serde(skip_serializing_if = "Option::is_none")]
320 pub audio_params: Option<MediaParams>,
321 #[serde(skip_serializing_if = "Option::is_none")]
323 pub metadata: Option<String>,
324}
325
326#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
328pub struct MediaParams {
329 pub band_width: usize,
331 pub codec: String,
333 pub media_id: MediaId,
335 #[serde(skip_serializing_if = "Option::is_none")]
337 pub rtcp_id: Option<RtcpId>,
338 #[serde(skip_serializing_if = "Option::is_none")]
340 pub payload_type: Option<u16>,
341 #[serde(skip_serializing_if = "Option::is_none")]
343 pub sampling_rate: Option<usize>,
344}
345
346#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
348pub struct RedirectParameters {
349 #[serde(skip_serializing_if = "Option::is_none")]
351 pub video: Option<SocketInfo<PhantomId>>,
352 #[serde(skip_serializing_if = "Option::is_none")]
354 pub video_rtcp: Option<SocketInfo<PhantomId>>,
355 #[serde(skip_serializing_if = "Option::is_none")]
357 pub audio: Option<SocketInfo<PhantomId>>,
358 #[serde(skip_serializing_if = "Option::is_none")]
360 pub audio_rtcp: Option<SocketInfo<PhantomId>>,
361}
362
363#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
367pub struct CallResponse {
368 pub command_type: String,
370 pub params: MediaConnectionIdWrapper,
372}
373
374#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
376pub struct MediaConnectionIdWrapper {
377 pub media_connection_id: MediaConnectionId,
379}
380
381#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
385pub struct AnswerQuery {
386 pub constraints: Constraints,
389 #[serde(skip_serializing_if = "Option::is_none")]
392 pub redirect_params: Option<RedirectParameters>,
393}
394
395#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
399pub struct AnswerResponse {
400 pub command_type: String,
402 pub params: AnswerResponseParams,
404}
405
406#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
408pub struct AnswerResponseParams {
409 #[serde(skip_serializing_if = "Option::is_none")]
410 pub video_id: Option<MediaId>,
411 #[serde(skip_serializing_if = "Option::is_none")]
412 pub audio_id: Option<MediaId>,
413}
414
415#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
419#[serde(tag = "event")]
420pub(crate) enum EventEnum {
421 READY,
422 STREAM,
423 CLOSE,
424 ERROR { error_message: String },
425 TIMEOUT,
426}
427
428#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
430pub struct MediaConnectionStatus {
431 pub metadata: String,
433 pub open: bool,
435 pub remote_id: PeerId,
437 #[serde(skip_serializing_if = "Option::is_none")]
439 pub ssrc: Option<Vec<SsrcPair>>,
440}
441
442#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
444pub struct SsrcPair {
445 pub media_id: MediaId,
447 pub ssrc: usize,
449}