sdp_rs/lines/attribute/
rtpmap.rs

1/// The rtpmap tokenizer, which is part of the attribute (`a=`) line. This is low
2/// level stuff and you shouldn't interact directly with it, unless you know what you are doing.
3pub use crate::tokenizers::attributes::rtpmap::Tokenizer;
4use std::convert::TryFrom;
5
6/// The `rtpmap` attribute as it appears in the attribute line(s) (`a=`).
7#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone)]
8pub struct Rtpmap {
9    pub payload_type: u32,
10    pub encoding_name: String,
11    pub clock_rate: i32,
12    pub encoding_params: Option<i32>,
13}
14
15impl<'a> TryFrom<Tokenizer<'a>> for Rtpmap {
16    type Error = crate::Error;
17
18    fn try_from(tokenizer: Tokenizer<'a>) -> Result<Self, Self::Error> {
19        Ok(Self {
20            payload_type: tokenizer.payload_type.parse()?,
21            encoding_name: tokenizer.encoding_name.into(),
22            clock_rate: tokenizer.clock_rate.parse()?,
23            encoding_params: tokenizer.encoding_params.map(|s| s.parse()).transpose()?,
24        })
25    }
26}
27
28impl<'a> TryFrom<&'a str> for Rtpmap {
29    type Error = crate::Error;
30
31    fn try_from(part: &'a str) -> Result<Self, Self::Error> {
32        Self::try_from(Tokenizer::tokenize(part)?.1)
33    }
34}
35
36impl std::fmt::Display for Rtpmap {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        match self.encoding_params {
39            Some(encoding_params) => write!(
40                f,
41                "{} {}/{} {}",
42                self.payload_type, self.encoding_name, self.clock_rate, encoding_params
43            ),
44            None => write!(
45                f,
46                "{} {}/{}",
47                self.payload_type, self.encoding_name, self.clock_rate
48            ),
49        }
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn from_str1() {
59        let tokenizer = Tokenizer {
60            payload_type: "96",
61            encoding_name: "L8",
62            clock_rate: "8000",
63            encoding_params: None,
64        };
65
66        assert_eq!(
67            Rtpmap::try_from(tokenizer),
68            Ok(Rtpmap {
69                payload_type: 96,
70                encoding_name: "L8".into(),
71                clock_rate: 8000,
72                encoding_params: None,
73            })
74        );
75    }
76
77    #[test]
78    fn from_str2() {
79        let tokenizer = Tokenizer {
80            payload_type: "98",
81            encoding_name: "L16",
82            clock_rate: "16000",
83            encoding_params: Some("2"),
84        };
85
86        assert_eq!(
87            Rtpmap::try_from(tokenizer),
88            Ok(Rtpmap {
89                payload_type: 98,
90                encoding_name: "L16".into(),
91                clock_rate: 16000,
92                encoding_params: Some(2),
93            })
94        );
95    }
96
97    #[test]
98    fn display1() {
99        assert_eq!(
100            Rtpmap {
101                payload_type: 98,
102                encoding_name: "L16".into(),
103                clock_rate: 16000,
104                encoding_params: Some(2),
105            }
106            .to_string(),
107            "98 L16/16000 2"
108        );
109    }
110}