rtsp_types/headers/
accept.rs1use super::*;
6
7use std::fmt;
8
9#[derive(Debug, Clone)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct Accept(Vec<MediaTypeRange>);
13
14#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct MediaTypeRange {
18 pub type_: Option<MediaType>,
22 pub subtype: Option<String>,
26 pub params: Vec<(String, Option<String>)>,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
32#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
33pub enum MediaType {
34 Text,
35 Image,
36 Audio,
37 Video,
38 Application,
39 Message,
40 Multipart,
41 Extension(String),
42}
43
44impl MediaType {
45 pub fn as_str(&self) -> &str {
46 match self {
47 MediaType::Text => "text",
48 MediaType::Image => "image",
49 MediaType::Audio => "audio",
50 MediaType::Video => "video",
51 MediaType::Application => "application",
52 MediaType::Message => "message",
53 MediaType::Multipart => "Multipart",
54 MediaType::Extension(ref s) => s.as_str(),
55 }
56 }
57}
58
59impl fmt::Display for MediaType {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 f.write_str(self.as_str())
62 }
63}
64
65impl std::str::FromStr for MediaType {
66 type Err = HeaderParseError;
67
68 fn from_str(s: &str) -> Result<Self, HeaderParseError> {
69 match s {
70 "text" => Ok(MediaType::Text),
71 "image" => Ok(MediaType::Image),
72 "audio" => Ok(MediaType::Audio),
73 "video" => Ok(MediaType::Video),
74 "application" => Ok(MediaType::Application),
75 "message" => Ok(MediaType::Message),
76 "multipart" => Ok(MediaType::Multipart),
77 _ => Ok(MediaType::Extension(String::from(s))),
78 }
79 }
80}
81
82impl std::ops::Deref for Accept {
83 type Target = Vec<MediaTypeRange>;
84
85 fn deref(&self) -> &Self::Target {
86 &self.0
87 }
88}
89
90impl std::ops::DerefMut for Accept {
91 fn deref_mut(&mut self) -> &mut Self::Target {
92 &mut self.0
93 }
94}
95
96impl AsRef<Vec<MediaTypeRange>> for Accept {
97 fn as_ref(&self) -> &Vec<MediaTypeRange> {
98 &self.0
99 }
100}
101
102impl AsMut<Vec<MediaTypeRange>> for Accept {
103 fn as_mut(&mut self) -> &mut Vec<MediaTypeRange> {
104 &mut self.0
105 }
106}
107
108impl From<Vec<MediaTypeRange>> for Accept {
109 fn from(v: Vec<MediaTypeRange>) -> Self {
110 Accept(v)
111 }
112}
113
114impl<'a> From<&'a [MediaTypeRange]> for Accept {
115 fn from(v: &'a [MediaTypeRange]) -> Self {
116 Accept(v.to_vec())
117 }
118}
119
120impl Accept {
121 pub fn builder() -> AcceptBuilder {
123 AcceptBuilder(Vec::new())
124 }
125}
126
127#[derive(Debug, Clone)]
129pub struct AcceptBuilder(Vec<MediaTypeRange>);
130
131impl AcceptBuilder {
132 pub fn media_type(mut self, media_type: MediaTypeRange) -> Self {
134 self.0.push(media_type);
135 self
136 }
137
138 pub fn build(self) -> Accept {
140 Accept(self.0)
141 }
142}
143
144impl super::TypedHeader for Accept {
145 fn from_headers(headers: impl AsRef<Headers>) -> Result<Option<Self>, HeaderParseError> {
146 use super::parser_helpers::split_once;
147
148 let headers = headers.as_ref();
149
150 let header = match headers.get(&ACCEPT) {
151 None => return Ok(None),
152 Some(header) => header,
153 };
154
155 let mut media_types = Vec::new();
156 for media_type_range in header.as_str().split(',') {
157 let media_type_range = media_type_range.trim();
158
159 let mut iter = media_type_range.split(';');
160 let media_type = iter.next().ok_or(HeaderParseError)?.trim();
161 let (media_type, media_subtype) =
162 split_once(media_type, '/').ok_or(HeaderParseError)?;
163
164 let media_type = if media_type == "*" {
165 None
166 } else {
167 Some(media_type)
168 };
169 let media_subtype = if media_subtype == "*" {
170 None
171 } else {
172 Some(media_subtype)
173 };
174
175 let mut params = Vec::new();
176 for param in iter {
177 let param = param.trim();
178 if let Some((param, value)) = split_once(param, '=') {
179 params.push((String::from(param), Some(String::from(value))));
180 } else {
181 params.push((String::from(param), None));
182 }
183 }
184
185 media_types.push(MediaTypeRange {
186 type_: media_type
187 .map(|s| s.parse())
188 .transpose()
189 .map_err(|_| HeaderParseError)?,
190 subtype: media_subtype.map(String::from),
191 params,
192 });
193 }
194
195 Ok(Some(Accept(media_types)))
196 }
197
198 fn insert_into(&self, mut headers: impl AsMut<Headers>) {
199 use std::fmt::Write;
200
201 let headers = headers.as_mut();
202
203 let mut media_types = String::new();
204 for media_type in &self.0 {
205 if !media_types.is_empty() {
206 media_types.push_str(", ");
207 }
208
209 if let Some(ref t) = media_type.type_ {
210 write!(&mut media_types, "{t}").unwrap();
211 } else {
212 media_types.push('*');
213 }
214 media_types.push('/');
215 if let Some(ref t) = media_type.subtype {
216 media_types.push_str(t);
217 } else {
218 media_types.push('*');
219 }
220
221 for param in &media_type.params {
222 media_types.push(';');
223 if let Some(ref value) = param.1 {
224 write!(&mut media_types, "{}={}", param.0, value).unwrap();
225 } else {
226 media_types.push_str(¶m.0);
227 }
228 }
229 }
230
231 headers.insert(ACCEPT, media_types);
232 }
233}
234
235impl super::TypedAppendableHeader for Accept {
236 fn append_to(&self, mut headers: impl AsMut<Headers>) {
237 use std::fmt::Write;
238
239 let headers = headers.as_mut();
240
241 let mut media_types = String::new();
242 for media_type in &self.0 {
243 if !media_types.is_empty() {
244 media_types.push_str(", ");
245 }
246
247 if let Some(ref t) = media_type.type_ {
248 write!(&mut media_types, "{t}").unwrap();
249 } else {
250 media_types.push('*');
251 }
252 media_types.push('/');
253 if let Some(ref t) = media_type.subtype {
254 media_types.push_str(t);
255 } else {
256 media_types.push('*');
257 }
258
259 for param in &media_type.params {
260 media_types.push(';');
261 if let Some(ref value) = param.1 {
262 write!(&mut media_types, "{}={}", param.0, value).unwrap();
263 } else {
264 media_types.push_str(¶m.0);
265 }
266 }
267 }
268
269 headers.append(ACCEPT, media_types);
270 }
271}