Skip to content
File

Blob: firmware/vendor/str0m/src/sdp/mod.rs

rust202 lines
1use std::fmt;
2use std::ops::Deref;
3 
4use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
5 
6mod data;
7#[cfg(test)]
8pub(crate) use data::RtpMap;
9pub(crate) use data::{FormatParam, Sdp, Session, SessionAttribute, Setup};
10pub(crate) use data::{MediaAttribute, MediaLine, MediaType, Msid, Proto};
11pub(crate) use data::{RestrictionId, Simulcast, SimulcastGroups, SimulcastLayer};
12 
13mod parser;
14 
15mod error;
16pub use error::SdpError;
17 
18#[derive(Debug, PartialEq, Eq)]
19/// SDP offer. Offers can be serialized via serde.
20pub struct SdpOffer(Sdp);
21 
22impl SdpOffer {
23 /// Takes the SDP string without any JSON wrapping and makes an `Offer`.
24 pub fn from_sdp_string(input: &str) -> Result<Self, SdpError> {
25 let sdp = Sdp::parse(input)?;
26 Ok(SdpOffer(sdp))
27 }
28 
29 /// Turns this offer into an SDP string, without any JSON wrapping.
30 pub fn to_sdp_string(&self) -> String {
31 self.0.to_string()
32 }
33 
34 #[cfg(test)]
35 pub(crate) fn into_inner(self) -> Sdp {
36 self.0
37 }
38}
39 
40#[derive(Debug, PartialEq, Eq)]
41/// SDP answer. Answers can be serialized via serde.
42pub struct SdpAnswer(Sdp);
43 
44impl SdpAnswer {
45 /// Takes the SDP string without any JSON wrapping and makes an `Answer`.
46 pub fn from_sdp_string(input: &str) -> Result<Self, SdpError> {
47 let sdp = Sdp::parse(input)?;
48 Ok(SdpAnswer(sdp))
49 }
50 
51 /// Turns this answer into an SDP string, without any JSON wrapping.
52 pub fn to_sdp_string(&self) -> String {
53 self.0.to_string()
54 }
55}
56 
57impl Deref for SdpOffer {
58 type Target = Sdp;
59 
60 fn deref(&self) -> &Self::Target {
61 &self.0
62 }
63}
64 
65impl Deref for SdpAnswer {
66 type Target = Sdp;
67 
68 fn deref(&self) -> &Self::Target {
69 &self.0
70 }
71}
72 
73impl From<Sdp> for SdpOffer {
74 fn from(v: Sdp) -> Self {
75 SdpOffer(v)
76 }
77}
78 
79impl From<Sdp> for SdpAnswer {
80 fn from(v: Sdp) -> Self {
81 SdpAnswer(v)
82 }
83}
84 
85impl fmt::Display for SdpOffer {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 write!(f, "{}", **self)
88 }
89}
90 
91impl fmt::Display for SdpAnswer {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 write!(f, "{}", **self)
94 }
95}
96 
97macro_rules! sdp_ser {
98 ($Struct:tt, $Name:literal, $LCName:literal) => {
99 impl Serialize for $Struct {
100 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
101 where
102 S: Serializer,
103 {
104 #[derive(Serialize)]
105 struct Data {
106 r#type: &'static str,
107 sdp: String,
108 }
109 
110 Data {
111 r#type: $LCName,
112 sdp: self.0.to_string(),
113 }
114 .serialize(s)
115 }
116 }
117 
118 impl<'de> Deserialize<'de> for $Struct {
119 fn deserialize<D>(d: D) -> Result<Self, D::Error>
120 where
121 D: Deserializer<'de>,
122 {
123 #[derive(Deserialize)]
124 struct Data {
125 r#type: String,
126 sdp: String,
127 }
128 
129 let data = Data::deserialize(d)?;
130 
131 if data.r#type != $LCName {
132 return Err(de::Error::custom(format!(
133 "Expected SDP type '{}', got '{}'",
134 $LCName, data.r#type
135 )));
136 }
137 
138 let sdp = Sdp::parse(&data.sdp)
139 .map_err(|err| de::Error::custom(format!("Failed to parse SDP: {:?}", err)))?;
140 
141 Ok(Self(sdp))
142 }
143 }
144 };
145}
146 
147sdp_ser!(SdpOffer, "Offer", "offer");
148sdp_ser!(SdpAnswer, "Answer", "answer");
149 
150#[cfg(test)]
151mod test {
152 use crate::VERSION;
153 use crate::rtp_::SessionId;
154 
155 use super::*;
156 
157 fn sdp() -> Sdp {
158 Sdp {
159 session: Session {
160 id: SessionId::from(123_u64),
161 attrs: vec![],
162 bw: None,
163 },
164 media_lines: vec![],
165 }
166 }
167 
168 #[test]
169 fn serialize_deserialize_offer() {
170 let offer = SdpOffer(sdp());
171 let json = serde_json::to_string(&offer).unwrap();
172 
173 let expected = format!(
174 "{{\"type\":\"offer\",\"sdp\":\
175 \"v=0\\r\\no=str0m-{VERSION} 123 2 \
176 IN IP4 0.0.0.0\\r\\ns=-\\r\\nt=0 0\\r\\n\"}}"
177 );
178 assert_eq!(json, expected);
179 
180 let offer2: SdpOffer = serde_json::from_str(&json).unwrap();
181 
182 assert_eq!(offer, offer2);
183 }
184 
185 #[test]
186 fn serialize_deserialize_answer() {
187 let answer = SdpAnswer(sdp());
188 let json = serde_json::to_string(&answer).unwrap();
189 
190 let expected = format!(
191 "{{\"type\":\"answer\",\"sdp\":\
192 \"v=0\\r\\no=str0m-{VERSION} 123 2 \
193 IN IP4 0.0.0.0\\r\\ns=-\\r\\nt=0 0\\r\\n\"}}"
194 );
195 assert_eq!(json, expected);
196 
197 let answer2: SdpAnswer = serde_json::from_str(&json).unwrap();
198 
199 assert_eq!(answer, answer2);
200 }
201}