From c0ffeee7debd1e69d3502a40f56fc2ea78d7913d Mon Sep 17 00:00:00 2001 From: Hendrik Sollich Date: Sat, 8 Jan 2022 23:33:33 +0100 Subject: [PATCH] feat: display impl for Session --- examples/session.rs | 5 +- src/media_section.rs | 13 +++++- src/session.rs | 20 ++++++-- src/udisplay.rs | 108 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 136 insertions(+), 10 deletions(-) diff --git a/examples/session.rs b/examples/session.rs index 6c714ab..ad70c21 100644 --- a/examples/session.rs +++ b/examples/session.rs @@ -18,9 +18,10 @@ fn main() { cfg_if::cfg_if! { if #[cfg(feature = "serde")] { - println!("{}", serde_json::to_string_pretty(session).unwrap()); + println!("{}", serde_json::to_string_pretty(&session).unwrap()); } else { - println!("{:#?}", session); + // println!("{:#?}", session); + print!("{}", session.to_string()); } } } diff --git a/src/media_section.rs b/src/media_section.rs index b5295ca..1c624dd 100644 --- a/src/media_section.rs +++ b/src/media_section.rs @@ -5,10 +5,11 @@ use derive_into_owned::IntoOwned; use crate::{ attributes::{ candidate, dtls, extmap, ice::IceParameter, msid, rtcp, rtpmap, AttributeLine, BundleGroup, - Control, Direction, Fingerprint, Fmtp, RtcpOption, Rtp, Ssrc, SsrcGroup, Ice, + Control, Direction, Fingerprint, Fmtp, Ice, RtcpOption, Rtp, Ssrc, SsrcGroup, }, + lazy_media_section::LazyMediaSection, lines::{connection::Connection, media::Media, SessionLine}, - SdpLine, lazy_media_section::LazyMediaSection, + SdpLine, }; #[derive(Debug, Default, IntoOwned)] @@ -51,6 +52,14 @@ pub struct MediaSection<'a> { } impl<'a> MediaSection<'a> { + pub fn media(&self) -> Media<'a> { + Media { + r#type: self.r#type.clone(), + port: self.port.clone(), + protocol: self.protocol.clone(), + payloads: self.payloads.clone(), + } + } pub(crate) fn add_line(&mut self, line: SdpLine<'a>) { use AttributeLine::*; use SessionLine::*; diff --git a/src/session.rs b/src/session.rs index d418b7f..95b05cd 100644 --- a/src/session.rs +++ b/src/session.rs @@ -7,7 +7,8 @@ use crate::{ phone_number::PhoneNumber, session_information::SessionInformation, session_name::SessionName, timing::Timing, uri::Uri, version::Version, SessionLine, }, - sdp_line, LazySession, media_section::MediaSection, SdpLine, + media_section::MediaSection, + sdp_line, LazySession, SdpLine, }; #[derive(Debug, Default, IntoOwned)] @@ -47,7 +48,7 @@ pub struct Session<'a> { pub description: Option>, pub attributes: Vec>, - pub msections: Vec>, + pub media: Vec>, } type ParseError<'a> = nom::Err>; @@ -116,7 +117,7 @@ impl<'a> Session<'a> { Ok((_, parsed)) => { if let SdpLine::Session(SessionLine::Media(mline)) = parsed { if let Some(m) = state.current_msection.take() { - state.session.msections.push(m); + state.session.media.push(m); } let new_m_section = MediaSection::from(mline); state.current_msection = Some(new_m_section); @@ -140,7 +141,7 @@ impl<'a> Session<'a> { return Err(err); } if let Some(m) = state.current_msection.take() { - state.session.msections.push(m); + state.session.media.push(m); } Ok(state.session) } @@ -157,8 +158,17 @@ impl<'a> From> for Session<'a> { for line in lazy.lines { session.add_line(line); } - session.msections = lazy.media.into_iter().map(Into::into).collect(); + session.media = lazy.media.into_iter().map(Into::into).collect(); session } } + +#[cfg(feature = "udisplay")] +impl std::string::ToString for Session<'_> { + fn to_string(&self) -> String { + let mut output = String::new(); + ufmt::uwrite!(output, "{}", self).unwrap(); + output + } +} diff --git a/src/udisplay.rs b/src/udisplay.rs index 9319550..44db931 100644 --- a/src/udisplay.rs +++ b/src/udisplay.rs @@ -26,8 +26,9 @@ use crate::{ bandwidth::*, connection::*, email::*, media::*, origin::*, phone_number::*, session_information::*, session_name::*, timing::*, uri::*, version::*, SessionLine, }, + media_section::MediaSection, parsers::IpVer, - SdpLine, + SdpLine, Session, }; impl ufmt::uDisplay for LazyMediaSection<'_> { @@ -57,6 +58,111 @@ impl ufmt::uDisplay for LazySession<'_> { } } +impl ufmt::uDisplay for Session<'_> { + fn fmt(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error> + where + W: uWrite + ?Sized, + { + write_ln_option(f, &self.version)?; + write_ln_option(f, &self.origin)?; + write_ln_option(f, &self.name)?; + write_ln_option(f, &self.timing)?; + write_ln_option(f, &self.band_width)?; + write_ln_option(f, &self.uri)?; + write_ln_option(f, &self.phone_number)?; + write_ln_option(f, &self.email_address)?; + write_ln_option(f, &self.connection)?; + write_ln_option(f, &self.description)?; + + for x in &self.attributes { + uwriteln!(f, "{}", x)?; + } + + for x in &self.media { + uwriteln!(f, "{}", x)?; + } + Ok(()) + } +} + +fn write_ln_option( + f: &mut Formatter<'_, W>, + content: &Option, +) -> Result<(), W::Error> +where + W: uWrite + ?Sized, +{ + if let Some(ref x) = content { + uwriteln!(f, "{}", x)?; + } + Ok(()) +} + +impl ufmt::uDisplay for MediaSection<'_> { + fn fmt(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error> + where + W: uWrite + ?Sized, + { + uwriteln!(f, "{}", self.media())?; + + write_ln_option(f, &self.connection)?; + + write_ln_option(f, &self.candidate)?; + + write_ln_option(f, &self.rtcp)?; + write_ln_option(f, &self.ice.ufrag.clone().map(IceParameter::Ufrag))?; + + write_ln_option(f, &self.ice.pwd.clone().map(IceParameter::Pwd))?; + + write_ln_option(f, &self.ice.options.clone().map(IceParameter::Options))?; + + write_ln_option(f, &self.fingerprint)?; + write_ln_option(f, &self.setup_role)?; + uwriteln!(f, "{}", Mid(self.mid.clone()))?; + + write_ln_option(f, &self.msid_semantic)?; + write_ln_option(f, &self.msid)?; + write_ln_option(f, &self.p_time)?; + for extmap in &self.extmap { + uwriteln!(f, "{}", extmap)?; + } + + for ssrc in &self.ssrc { + uwriteln!(f, "{}", ssrc)?; + } + + write_ln_option(f, &self.bundle_group)?; + if self.bundle_only { + uwriteln!(f, "a=bundle-only")?; + } + write_ln_option(f, &self.ssrc_group)?; + write_ln_option(f, &self.direction)?; + write_ln_option(f, &self.rtp)?; + for rtcp_option in &self.rtcp_option { + uwriteln!(f, "{}", rtcp_option)?; + } + + for payload in self.payloads.iter().filter_map(|p| p.parse::().ok()) { + for rtp in self.rtp_map.iter().filter(|r| r.payload == payload) { + uwriteln!(f, "{}", rtp)?; + } + for rtcp_fb in self.rtcp_fb.iter().filter(|r| r.payload == payload) { + uwriteln!(f, "{}", rtcp_fb)?; + } + for fmtp in self.fmtp.iter().filter(|r| r.payload == payload) { + uwriteln!(f, "{}", fmtp)?; + } + } + + write_ln_option(f, &self.control)?; + + for x in &self.attributes { + uwriteln!(f, "{}", x)?; + } + + Ok(()) + } +} impl ufmt::uDisplay for SdpLine<'_> { fn fmt(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error> where