libsdp/attributes/
mod.rs

1use nom::{
2    IResult,
3    branch::alt,
4    bytes::complete::{tag,take_until},
5    combinator::{map, map_res},
6};
7
8use crate::parse::slice_to_string;
9use crate::parse::ParserResult;
10
11mod ty;
12pub use self::ty::SdpAttributeType;
13pub use self::ty::parse_attribute_type;
14
15mod optional;
16pub use self::optional::SdpOptionalAttribute;
17pub use self::optional::parse_optional_attributes;
18
19use std::fmt;
20
21mod rtpmap;
22pub use self::rtpmap::RtpMap;
23pub use self::rtpmap::parse_rtpmap;
24
25
26#[derive(Debug, PartialEq, Clone)]
27pub enum SdpAttribute {
28    SendOnly,
29    RecvOnly,
30    SendRecv,
31    RtpMap(RtpMap),
32    Fmtp(String)
33}
34
35pub fn parse_global_attribute(input: &[u8]) -> IResult<&[u8], SdpAttribute> {
36     alt((
37       map(tag("a=sendrecv"), |_| SdpAttribute::SendOnly),
38       map(tag("a=recvonly"), |_| SdpAttribute::RecvOnly),
39       map(tag("a=sendrecv"), |_| SdpAttribute::SendRecv),
40       parse_rtpmap_attribute,
41       parse_fmtp_attribute
42     ))(input)
43}
44
45pub fn parse_rtpmap_attribute(input: &[u8]) -> IResult<&[u8], SdpAttribute> {
46    let (input, _) = tag("a=rtpmap ")(input)?;
47    let (input, data) = parse_rtpmap(input)?;
48    Ok((input, SdpAttribute::RtpMap(data)))
49}
50
51pub fn parse_fmtp_attribute(input: &[u8]) -> IResult<&[u8], SdpAttribute> {
52    let (input, _) = tag("a=fmtp ")(input)?;
53    let (input, data) = map_res(take_until("\r"), slice_to_string)(input)?;
54    Ok((input, SdpAttribute::Fmtp(data)))
55}
56
57pub fn parse_global_attributes(input: &[u8]) -> ParserResult<Vec<SdpAttribute>> {
58    let mut output = vec![];
59    let mut data = input;
60    while let Ok((remains, attribute)) = parse_global_attribute(data) {
61        output.push(attribute);
62        data = remains;
63    }
64    Ok((data, output))
65}
66
67impl fmt::Display for SdpAttribute {
68    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        match self {
70            SdpAttribute::RecvOnly => write!(f, "recvonly"),
71            SdpAttribute::SendOnly => write!(f, "sendonly"),
72            SdpAttribute::SendRecv => write!(f, "sendrecv"),
73            SdpAttribute::RtpMap(data) => write!(f, "rtpmap {}", data),
74            SdpAttribute::Fmtp(data) => write!(f, "fmtp {}", data)
75        }
76    }
77}