use std::borrow::Cow;
use std::str::FromStr;
use crate::{Error, Result};
pub fn parse_offer(body: &str) -> Result<str0m::change::SdpOffer> {
str0m::change::SdpOffer::from_sdp_string(body).map_err(|err| Error::InvalidSdp(err.to_string()))
}
pub fn render_answer(answer: &str0m::change::SdpAnswer) -> String {
answer
.to_sdp_string()
.split("\r\n")
.map(ensure_media_format)
.collect::<Vec<Cow<str>>>()
.join("\r\n")
}
fn ensure_media_format(line: &str) -> Cow<'_, str> {
if !line.starts_with("m=") {
return Cow::Borrowed(line);
}
if line.split_whitespace().count() >= 4 {
return Cow::Borrowed(line);
}
Cow::Owned(format!("{} 0", line.trim_end()))
}
pub fn new_resource_id() -> String {
uuid::Uuid::new_v4().to_string()
}
pub fn parse_resource_id(path: &str) -> Result<uuid::Uuid> {
let last = path
.rsplit('/')
.find(|s| !s.is_empty())
.ok_or_else(|| Error::InvalidSdp("missing resource id".into()))?;
uuid::Uuid::from_str(last).map_err(|err| Error::InvalidSdp(err.to_string()))
}
#[cfg(test)]
mod tests {
use super::ensure_media_format;
#[test]
fn rejected_mline_with_no_format_gets_placeholder() {
assert_eq!(
ensure_media_format("m=audio 0 UDP/TLS/RTP/SAVPF "),
"m=audio 0 UDP/TLS/RTP/SAVPF 0"
);
assert_eq!(
ensure_media_format("m=audio 0 UDP/TLS/RTP/SAVPF"),
"m=audio 0 UDP/TLS/RTP/SAVPF 0"
);
}
#[test]
fn well_formed_lines_are_untouched() {
let video = "m=video 9 UDP/TLS/RTP/SAVPF 96 97";
assert_eq!(ensure_media_format(video), video);
let attr = "a=ice-ufrag:abcd";
assert_eq!(ensure_media_format(attr), attr);
}
}