1use crate::*;
2use crate::attributes::parse_optional_attributes;
3
4use nom::IResult;
5use std::fmt;
6
7#[derive(Debug, PartialEq, Clone)]
9pub struct SdpOffer {
10 pub version: SdpVersion,
11 pub origin: SdpOrigin,
12 pub name: SdpSessionName,
13 pub optional: Vec<SdpOptionalAttribute>,
14 pub attributes: Vec<SdpAttribute>,
15 pub media: Vec<SdpMedia>
16}
17
18pub fn parse_sdp_offer(input: &[u8]) -> IResult<&[u8], SdpOffer> {
20 let (input, version) = parse_version_line(input)?;
21 let (input, origin) = parse_origin_line(input)?;
22 let (input, name) = parse_session_name_line(input)?;
23 let (input, optional) = parse_optional_attributes(input)?;
24 let (input, attributes) = parse_global_attributes(input)?;
25 let (input, media) = parse_media_lines(input)?;
26 Ok((input, SdpOffer { version, origin, name, optional, attributes, media }))
27}
28
29impl SdpOffer {
30
31 pub fn new<S: Into<String>>(origin: SdpOrigin, name: S) -> SdpOffer {
33 SdpOffer {
34 version: SdpVersion,
35 origin,
36 name: SdpSessionName::new(name),
37 optional: vec![],
38 attributes: vec![],
39 media: vec![]
40 }
41 }
42
43 pub fn optional_attribute(mut self, attr: SdpOptionalAttribute) -> SdpOffer {
45 self.optional.push(attr);
46 self
47 }
48
49 pub fn optional_attributes(mut self, attr: Vec<SdpOptionalAttribute>) -> SdpOffer {
51 self.optional = attr;
52 self
53 }
54
55 pub fn attribute(mut self, attr: SdpAttribute) -> SdpOffer {
57 self.attributes.push(attr);
58 self
59 }
60
61 pub fn attributes(mut self, attr: Vec<SdpAttribute>) -> SdpOffer {
63 self.attributes = attr;
64 self
65 }
66
67 pub fn media(mut self, media: SdpMedia) -> SdpOffer {
69 self.media.push(media);
70 self
71 }
72
73 pub fn get_connection(&self) -> Option<SdpConnection> {
75 for thing in &self.optional {
76 if let SdpOptionalAttribute::Connection(conn) = thing {
77 return Some(conn.clone());
78 }
79 }
80 None
81 }
82}
83
84impl fmt::Display for SdpOffer {
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 write!(f, "v={}\r\no={}\r\ns={}", self.version, self.origin, self.name)?;
87 for attribute in &self.optional {
88 write!(f, "\r\n{}", attribute)?;
89 }
90 for attribute in &self.attributes {
91 write!(f, "\r\na={}", attribute)?;
92 }
93 for media in &self.media {
94 write!(f, "\r\nm={}", media)?;
95 }
96 writeln!(f, "\r")?;
97 Ok(())
98 }
99}