rtsp_types/headers/
supported.rs1use super::features::*;
6use super::*;
7
8#[derive(Debug, Clone)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Supported(Vec<String>);
12
13impl std::ops::Deref for Supported {
14 type Target = Vec<String>;
15
16 fn deref(&self) -> &Self::Target {
17 &self.0
18 }
19}
20
21impl std::ops::DerefMut for Supported {
22 fn deref_mut(&mut self) -> &mut Self::Target {
23 &mut self.0
24 }
25}
26
27impl AsRef<Vec<String>> for Supported {
28 fn as_ref(&self) -> &Vec<String> {
29 &self.0
30 }
31}
32
33impl AsMut<Vec<String>> for Supported {
34 fn as_mut(&mut self) -> &mut Vec<String> {
35 &mut self.0
36 }
37}
38
39impl From<Vec<String>> for Supported {
40 fn from(v: Vec<String>) -> Self {
41 Supported(v)
42 }
43}
44
45impl<'a> From<&'a [String]> for Supported {
46 fn from(v: &'a [String]) -> Self {
47 Supported(v.to_vec())
48 }
49}
50
51impl<'a> From<&'a [&'a &str]> for Supported {
52 fn from(v: &'a [&'a &str]) -> Self {
53 Supported(v.iter().map(|s| String::from(**s)).collect())
54 }
55}
56
57impl Supported {
58 pub fn builder() -> SupportedBuilder {
60 SupportedBuilder(Vec::new())
61 }
62
63 pub fn contains_play_basic(&self) -> bool {
67 self.0.iter().any(|f| f == PLAY_BASIC)
68 }
69
70 pub fn contains_play_scale(&self) -> bool {
74 self.0.iter().any(|f| f == PLAY_SCALE)
75 }
76
77 pub fn contains_play_speed(&self) -> bool {
81 self.0.iter().any(|f| f == PLAY_SPEED)
82 }
83
84 pub fn contains_setup_rtp_rtcp_mux(&self) -> bool {
88 self.0.iter().any(|f| f == SETUP_RTP_RTCP_MUX)
89 }
90}
91
92#[derive(Debug, Clone)]
94pub struct SupportedBuilder(Vec<String>);
95
96impl SupportedBuilder {
97 pub fn feature<S: Into<String>>(mut self, feature: S) -> Self {
99 self.0.push(feature.into());
100 self
101 }
102
103 pub fn play_basic(self) -> Self {
107 self.feature(PLAY_BASIC)
108 }
109
110 pub fn play_scale(self) -> Self {
114 self.feature(PLAY_SCALE)
115 }
116
117 pub fn play_speed(self) -> Self {
121 self.feature(PLAY_SPEED)
122 }
123
124 pub fn setup_rtp_rtcp_mux(self) -> Self {
128 self.feature(SETUP_RTP_RTCP_MUX)
129 }
130
131 pub fn build(self) -> Supported {
133 Supported(self.0)
134 }
135}
136
137impl super::TypedHeader for Supported {
138 fn from_headers(headers: impl AsRef<Headers>) -> Result<Option<Self>, HeaderParseError> {
139 let headers = headers.as_ref();
140
141 let header = match headers.get(&SUPPORTED) {
142 None => return Ok(None),
143 Some(header) => header,
144 };
145
146 let mut supported = Vec::new();
147 for feature in header.as_str().split(',') {
148 let feature = feature.trim();
149
150 supported.push(feature.into());
151 }
152
153 Ok(Some(Supported(supported)))
154 }
155
156 fn insert_into(&self, mut headers: impl AsMut<Headers>) {
157 let headers = headers.as_mut();
158
159 let mut supported = String::new();
160 for feature in &self.0 {
161 if !supported.is_empty() {
162 supported.push_str(", ");
163 }
164
165 supported.push_str(feature);
166 }
167
168 headers.insert(SUPPORTED, supported);
169 }
170}
171
172impl super::TypedAppendableHeader for Supported {
173 fn append_to(&self, mut headers: impl AsMut<Headers>) {
174 let headers = headers.as_mut();
175
176 let mut supported = String::new();
177 for feature in &self.0 {
178 if !supported.is_empty() {
179 supported.push_str(", ");
180 }
181
182 supported.push_str(feature);
183 }
184
185 headers.append(SUPPORTED, supported);
186 }
187}