1use crate::tag::hls::TagName;
7use std::collections::HashSet;
8
9const ALL_KNOWN_HLS_TAG_NAMES: [TagName; 32] = [
10 TagName::M3u,
11 TagName::Version,
12 TagName::IndependentSegments,
13 TagName::Start,
14 TagName::Define,
15 TagName::Targetduration,
16 TagName::MediaSequence,
17 TagName::DiscontinuitySequence,
18 TagName::Endlist,
19 TagName::PlaylistType,
20 TagName::IFramesOnly,
21 TagName::PartInf,
22 TagName::ServerControl,
23 TagName::Inf,
24 TagName::Byterange,
25 TagName::Discontinuity,
26 TagName::Key,
27 TagName::Map,
28 TagName::ProgramDateTime,
29 TagName::Gap,
30 TagName::Bitrate,
31 TagName::Part,
32 TagName::Daterange,
33 TagName::Skip,
34 TagName::PreloadHint,
35 TagName::RenditionReport,
36 TagName::Media,
37 TagName::StreamInf,
38 TagName::IFrameStreamInf,
39 TagName::SessionData,
40 TagName::SessionKey,
41 TagName::ContentSteering,
42];
43
44#[derive(Debug, PartialEq, Clone)]
49pub struct ParsingOptions {
50 hls_tag_names_to_parse: HashSet<TagName>,
51}
52
53impl Default for ParsingOptions {
54 fn default() -> Self {
55 Self {
56 hls_tag_names_to_parse: HashSet::from(ALL_KNOWN_HLS_TAG_NAMES),
57 }
58 }
59}
60
61impl ParsingOptions {
62 pub fn builder() -> ParsingOptionsBuilder {
64 ParsingOptionsBuilder::new()
65 }
66
67 pub fn hls_tag_names_to_parse(&self) -> &HashSet<TagName> {
72 &self.hls_tag_names_to_parse
73 }
74
75 pub(crate) fn is_known_name(&self, name: &'_ str) -> bool {
76 let Ok(tag_name) = TagName::try_from(name) else {
77 return false;
78 };
79 self.hls_tag_names_to_parse.contains(&tag_name)
80 }
81}
82
83#[derive(Default, Debug)]
89pub struct ParsingOptionsBuilder {
90 hls_tag_names_to_parse: HashSet<TagName>,
91}
92
93impl ParsingOptionsBuilder {
94 pub fn new() -> Self {
96 Self {
97 hls_tag_names_to_parse: HashSet::default(),
98 }
99 }
100
101 pub fn build(&self) -> ParsingOptions {
103 ParsingOptions {
104 hls_tag_names_to_parse: self.hls_tag_names_to_parse.clone(),
105 }
106 }
107
108 pub fn with_parsing_for_all_tags(&mut self) -> &mut Self {
110 self.hls_tag_names_to_parse.extend(ALL_KNOWN_HLS_TAG_NAMES);
111 self
112 }
113
114 pub fn with_parsing_for_m3u(&mut self) -> &mut Self {
116 self.hls_tag_names_to_parse.insert(TagName::M3u);
117 self
118 }
119
120 pub fn without_parsing_for_m3u(&mut self) -> &mut Self {
122 self.hls_tag_names_to_parse.remove(&TagName::M3u);
123 self
124 }
125
126 pub fn with_parsing_for_version(&mut self) -> &mut Self {
128 self.hls_tag_names_to_parse.insert(TagName::Version);
129 self
130 }
131
132 pub fn without_parsing_for_version(&mut self) -> &mut Self {
134 self.hls_tag_names_to_parse.remove(&TagName::Version);
135 self
136 }
137
138 pub fn with_parsing_for_independent_segments(&mut self) -> &mut Self {
140 self.hls_tag_names_to_parse
141 .insert(TagName::IndependentSegments);
142 self
143 }
144
145 pub fn without_parsing_for_independent_segments(&mut self) -> &mut Self {
147 self.hls_tag_names_to_parse
148 .remove(&TagName::IndependentSegments);
149 self
150 }
151
152 pub fn with_parsing_for_start(&mut self) -> &mut Self {
154 self.hls_tag_names_to_parse.insert(TagName::Start);
155 self
156 }
157
158 pub fn without_parsing_for_start(&mut self) -> &mut Self {
160 self.hls_tag_names_to_parse.remove(&TagName::Start);
161 self
162 }
163
164 pub fn with_parsing_for_define(&mut self) -> &mut Self {
166 self.hls_tag_names_to_parse.insert(TagName::Define);
167 self
168 }
169
170 pub fn without_parsing_for_define(&mut self) -> &mut Self {
172 self.hls_tag_names_to_parse.remove(&TagName::Define);
173 self
174 }
175
176 pub fn with_parsing_for_targetduration(&mut self) -> &mut Self {
178 self.hls_tag_names_to_parse.insert(TagName::Targetduration);
179 self
180 }
181
182 pub fn without_parsing_for_targetduration(&mut self) -> &mut Self {
184 self.hls_tag_names_to_parse.remove(&TagName::Targetduration);
185 self
186 }
187
188 pub fn with_parsing_for_media_sequence(&mut self) -> &mut Self {
190 self.hls_tag_names_to_parse.insert(TagName::MediaSequence);
191 self
192 }
193
194 pub fn without_parsing_for_media_sequence(&mut self) -> &mut Self {
196 self.hls_tag_names_to_parse.remove(&TagName::MediaSequence);
197 self
198 }
199
200 pub fn with_parsing_for_discontinuity_sequence(&mut self) -> &mut Self {
202 self.hls_tag_names_to_parse
203 .insert(TagName::DiscontinuitySequence);
204 self
205 }
206
207 pub fn without_parsing_for_discontinuity_sequence(&mut self) -> &mut Self {
209 self.hls_tag_names_to_parse
210 .remove(&TagName::DiscontinuitySequence);
211 self
212 }
213
214 pub fn with_parsing_for_endlist(&mut self) -> &mut Self {
216 self.hls_tag_names_to_parse.insert(TagName::Endlist);
217 self
218 }
219
220 pub fn without_parsing_for_endlist(&mut self) -> &mut Self {
222 self.hls_tag_names_to_parse.remove(&TagName::Endlist);
223 self
224 }
225
226 pub fn with_parsing_for_playlist_type(&mut self) -> &mut Self {
228 self.hls_tag_names_to_parse.insert(TagName::PlaylistType);
229 self
230 }
231
232 pub fn without_parsing_for_playlist_type(&mut self) -> &mut Self {
234 self.hls_tag_names_to_parse.remove(&TagName::PlaylistType);
235 self
236 }
237
238 pub fn with_parsing_for_i_frames_only(&mut self) -> &mut Self {
240 self.hls_tag_names_to_parse.insert(TagName::IFramesOnly);
241 self
242 }
243
244 pub fn without_parsing_for_i_frames_only(&mut self) -> &mut Self {
246 self.hls_tag_names_to_parse.remove(&TagName::IFramesOnly);
247 self
248 }
249
250 pub fn with_parsing_for_part_inf(&mut self) -> &mut Self {
252 self.hls_tag_names_to_parse.insert(TagName::PartInf);
253 self
254 }
255
256 pub fn without_parsing_for_part_inf(&mut self) -> &mut Self {
258 self.hls_tag_names_to_parse.remove(&TagName::PartInf);
259 self
260 }
261
262 pub fn with_parsing_for_server_control(&mut self) -> &mut Self {
264 self.hls_tag_names_to_parse.insert(TagName::ServerControl);
265 self
266 }
267
268 pub fn without_parsing_for_server_control(&mut self) -> &mut Self {
270 self.hls_tag_names_to_parse.remove(&TagName::ServerControl);
271 self
272 }
273
274 pub fn with_parsing_for_inf(&mut self) -> &mut Self {
276 self.hls_tag_names_to_parse.insert(TagName::Inf);
277 self
278 }
279
280 pub fn without_parsing_for_inf(&mut self) -> &mut Self {
282 self.hls_tag_names_to_parse.remove(&TagName::Inf);
283 self
284 }
285
286 pub fn with_parsing_for_byterange(&mut self) -> &mut Self {
288 self.hls_tag_names_to_parse.insert(TagName::Byterange);
289 self
290 }
291
292 pub fn without_parsing_for_byterange(&mut self) -> &mut Self {
294 self.hls_tag_names_to_parse.remove(&TagName::Byterange);
295 self
296 }
297
298 pub fn with_parsing_for_discontinuity(&mut self) -> &mut Self {
300 self.hls_tag_names_to_parse.insert(TagName::Discontinuity);
301 self
302 }
303
304 pub fn without_parsing_for_discontinuity(&mut self) -> &mut Self {
306 self.hls_tag_names_to_parse.remove(&TagName::Discontinuity);
307 self
308 }
309
310 pub fn with_parsing_for_key(&mut self) -> &mut Self {
312 self.hls_tag_names_to_parse.insert(TagName::Key);
313 self
314 }
315
316 pub fn without_parsing_for_key(&mut self) -> &mut Self {
318 self.hls_tag_names_to_parse.remove(&TagName::Key);
319 self
320 }
321
322 pub fn with_parsing_for_map(&mut self) -> &mut Self {
324 self.hls_tag_names_to_parse.insert(TagName::Map);
325 self
326 }
327
328 pub fn without_parsing_for_map(&mut self) -> &mut Self {
330 self.hls_tag_names_to_parse.remove(&TagName::Map);
331 self
332 }
333
334 pub fn with_parsing_for_program_date_time(&mut self) -> &mut Self {
336 self.hls_tag_names_to_parse.insert(TagName::ProgramDateTime);
337 self
338 }
339
340 pub fn without_parsing_for_program_date_time(&mut self) -> &mut Self {
342 self.hls_tag_names_to_parse
343 .remove(&TagName::ProgramDateTime);
344 self
345 }
346
347 pub fn with_parsing_for_gap(&mut self) -> &mut Self {
349 self.hls_tag_names_to_parse.insert(TagName::Gap);
350 self
351 }
352
353 pub fn without_parsing_for_gap(&mut self) -> &mut Self {
355 self.hls_tag_names_to_parse.remove(&TagName::Gap);
356 self
357 }
358
359 pub fn with_parsing_for_bitrate(&mut self) -> &mut Self {
361 self.hls_tag_names_to_parse.insert(TagName::Bitrate);
362 self
363 }
364
365 pub fn without_parsing_for_bitrate(&mut self) -> &mut Self {
367 self.hls_tag_names_to_parse.remove(&TagName::Bitrate);
368 self
369 }
370
371 pub fn with_parsing_for_part(&mut self) -> &mut Self {
373 self.hls_tag_names_to_parse.insert(TagName::Part);
374 self
375 }
376
377 pub fn without_parsing_for_part(&mut self) -> &mut Self {
379 self.hls_tag_names_to_parse.remove(&TagName::Part);
380 self
381 }
382
383 pub fn with_parsing_for_daterange(&mut self) -> &mut Self {
385 self.hls_tag_names_to_parse.insert(TagName::Daterange);
386 self
387 }
388
389 pub fn without_parsing_for_daterange(&mut self) -> &mut Self {
391 self.hls_tag_names_to_parse.remove(&TagName::Daterange);
392 self
393 }
394
395 pub fn with_parsing_for_skip(&mut self) -> &mut Self {
397 self.hls_tag_names_to_parse.insert(TagName::Skip);
398 self
399 }
400
401 pub fn without_parsing_for_skip(&mut self) -> &mut Self {
403 self.hls_tag_names_to_parse.remove(&TagName::Skip);
404 self
405 }
406
407 pub fn with_parsing_for_preload_hint(&mut self) -> &mut Self {
409 self.hls_tag_names_to_parse.insert(TagName::PreloadHint);
410 self
411 }
412
413 pub fn without_parsing_for_preload_hint(&mut self) -> &mut Self {
415 self.hls_tag_names_to_parse.remove(&TagName::PreloadHint);
416 self
417 }
418
419 pub fn with_parsing_for_rendition_report(&mut self) -> &mut Self {
421 self.hls_tag_names_to_parse.insert(TagName::RenditionReport);
422 self
423 }
424
425 pub fn without_parsing_for_rendition_report(&mut self) -> &mut Self {
427 self.hls_tag_names_to_parse
428 .remove(&TagName::RenditionReport);
429 self
430 }
431
432 pub fn with_parsing_for_media(&mut self) -> &mut Self {
434 self.hls_tag_names_to_parse.insert(TagName::Media);
435 self
436 }
437
438 pub fn without_parsing_for_media(&mut self) -> &mut Self {
440 self.hls_tag_names_to_parse.remove(&TagName::Media);
441 self
442 }
443
444 pub fn with_parsing_for_stream_inf(&mut self) -> &mut Self {
446 self.hls_tag_names_to_parse.insert(TagName::StreamInf);
447 self
448 }
449
450 pub fn without_parsing_for_stream_inf(&mut self) -> &mut Self {
452 self.hls_tag_names_to_parse.remove(&TagName::StreamInf);
453 self
454 }
455
456 pub fn with_parsing_for_i_frame_stream_inf(&mut self) -> &mut Self {
458 self.hls_tag_names_to_parse.insert(TagName::IFrameStreamInf);
459 self
460 }
461
462 pub fn without_parsing_for_i_frame_stream_inf(&mut self) -> &mut Self {
464 self.hls_tag_names_to_parse
465 .remove(&TagName::IFrameStreamInf);
466 self
467 }
468
469 pub fn with_parsing_for_session_data(&mut self) -> &mut Self {
471 self.hls_tag_names_to_parse.insert(TagName::SessionData);
472 self
473 }
474
475 pub fn without_parsing_for_session_data(&mut self) -> &mut Self {
477 self.hls_tag_names_to_parse.remove(&TagName::SessionData);
478 self
479 }
480
481 pub fn with_parsing_for_session_key(&mut self) -> &mut Self {
483 self.hls_tag_names_to_parse.insert(TagName::SessionKey);
484 self
485 }
486
487 pub fn without_parsing_for_session_key(&mut self) -> &mut Self {
489 self.hls_tag_names_to_parse.remove(&TagName::SessionKey);
490 self
491 }
492
493 pub fn with_parsing_for_content_steering(&mut self) -> &mut Self {
495 self.hls_tag_names_to_parse.insert(TagName::ContentSteering);
496 self
497 }
498
499 pub fn without_parsing_for_content_steering(&mut self) -> &mut Self {
501 self.hls_tag_names_to_parse
502 .remove(&TagName::ContentSteering);
503 self
504 }
505}
506
507#[cfg(test)]
508mod tests {
509 use super::*;
510 use pretty_assertions::assert_eq;
511
512 #[test]
513 fn builder_with_all_tag_names() {
514 let options = ParsingOptionsBuilder::new()
515 .with_parsing_for_all_tags()
516 .build();
517 let mut count = 0;
518 for name in options.hls_tag_names_to_parse {
519 count += 1;
520 assert!(ALL_KNOWN_HLS_TAG_NAMES.contains(&name));
521 }
522 assert_eq!(32, count);
523 }
524
525 #[test]
526 fn builder_with_some_tag_names() {
527 let options = ParsingOptionsBuilder::new()
528 .with_parsing_for_bitrate()
529 .with_parsing_for_byterange()
530 .with_parsing_for_daterange()
531 .build();
532 assert!(options.hls_tag_names_to_parse.contains(&TagName::Bitrate));
533 assert!(options.hls_tag_names_to_parse.contains(&TagName::Byterange));
534 assert!(options.hls_tag_names_to_parse.contains(&TagName::Daterange));
535 assert_eq!(3, options.hls_tag_names_to_parse.len());
536 }
537
538 #[test]
539 fn builder_with_removing_some_tag_names() {
540 let options = ParsingOptionsBuilder::new()
541 .with_parsing_for_all_tags()
542 .without_parsing_for_define()
543 .without_parsing_for_i_frame_stream_inf()
544 .build();
545 assert!(!options.hls_tag_names_to_parse.contains(&TagName::Define));
546 assert!(
547 !options
548 .hls_tag_names_to_parse
549 .contains(&TagName::IFrameStreamInf)
550 );
551 assert_eq!(30, options.hls_tag_names_to_parse.len());
552 }
553}