libsdp/
offer.rs

1use crate::*;
2use crate::attributes::parse_optional_attributes;
3
4use nom::IResult;
5use std::fmt;
6
7/// A Single Sdp Message
8#[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
18/// Parse this input data into an SdpOffer.
19pub 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    /// Generate a new offer from the `origin` and the session name `name`.
32    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    /// Add an optional attribute.
44    pub fn optional_attribute(mut self, attr: SdpOptionalAttribute) -> SdpOffer {
45        self.optional.push(attr);
46        self
47    }
48
49    /// Add all atributes removing all currently present.
50    pub fn optional_attributes(mut self, attr: Vec<SdpOptionalAttribute>) -> SdpOffer {
51        self.optional = attr;
52        self
53    }
54
55    /// Add a single `SdpAttribute` to the attribute list.
56    pub fn attribute(mut self, attr: SdpAttribute) -> SdpOffer {
57        self.attributes.push(attr);
58        self
59    }
60
61    /// Add all SdpAttributes removing any that might currently by present.
62    pub fn attributes(mut self, attr: Vec<SdpAttribute>) -> SdpOffer {
63        self.attributes = attr;
64        self
65    }
66
67    /// Add a single SdpMedia. Represents a media line.
68    pub fn media(mut self, media: SdpMedia) -> SdpOffer {
69        self.media.push(media);
70        self
71    }
72
73    /// Get the global SDP connection if this offer has one. returns none if not present.
74    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}