1#![allow(dead_code)]
2
3use std::borrow::Cow;
4
5use derive_into_owned::IntoOwned;
6use nom::{combinator::map, sequence::tuple, IResult};
7
8use crate::parsers::*;
9#[cfg(test)]
10use crate::{assert_line, assert_line_print};
11
12#[derive(Clone, IntoOwned, PartialEq, Eq)]
14#[cfg_attr(feature = "debug", derive(Debug))]
15#[cfg_attr(
16 feature = "serde",
17 derive(serde::Serialize, serde::Deserialize),
18 serde(rename_all = "camelCase")
19)]
20pub struct Media<'a> {
21 pub r#type: Cow<'a, str>,
22 pub port: u32,
23 pub protocol: Vec<Cow<'a, str>>,
24 pub payloads: Vec<Cow<'a, str>>,
25}
26
27pub fn media_line(input: &str) -> IResult<&str, Media> {
28 line(
29 "m=",
30 wsf(map(
31 tuple((
32 wsf(cowify(read_string)), wsf(read_number), wsf(slash_separated_cow_strings), wsf(read_as_cow_strings), )),
37 |(r#type, port, protocol, payloads)| Media {
38 r#type,
39 port,
40 protocol,
41 payloads,
42 },
43 )),
44 )(input)
45}
46
47#[test]
48fn test_mline() {
49 assert_line!(
50 media_line,
51 "m=video 51744 RTP/AVP 126 97 98 34 31",
52 Media {
53 r#type: "video".into(),
54 port: 51744,
55 protocol: create_test_vec(&["RTP", "AVP"]),
56 payloads: create_test_vec(&["126", "97", "98", "34", "31"]),
57 },
58 print
59 );
60 assert_line!(
61 media_line,
62 "m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126",
63 Media {
64 r#type: "audio".into(),
65 port: 9,
66 protocol: create_test_vec(&["UDP", "TLS", "RTP", "SAVPF"]),
67 payloads: create_test_vec(&[
68 "111", "103", "104", "9", "0", "8", "106", "105", "13", "110", "112", "113", "126"
69 ]),
70 },
71 print
72 );
73 assert_line_print!(
74 media_line,
75 "m=video 9 UDP/TLS/RTP/SAVPF 96 98 100 102 127 125 97 99 101 124"
76 );
77 assert_line_print!(media_line, "m=application 3238 UDP/BFCP *")
78}