1use ufmt::{uWrite, uwrite, uwriteln, Formatter};
2
3use crate::{
4 attributes::{
5 bundle::BundleGroup,
6 candidate::{Candidate, CandidateComponent, CandidateProtocol, CandidateType},
7 control::Control,
8 direction::Direction,
9 dtls::SetupRole,
10 extmap::Extmap,
11 fingerprint::Fingerprint,
12 fmtp::Fmtp,
13 ice::IceParameter,
14 mid::Mid,
15 msid::*,
16 rtcp::*,
17 rtcp_option::RtcpOption,
18 rtp::Rtp,
19 rtpmap::*,
20 ssrc::{Ssrc, SsrcGroup, SsrcSemantic},
21 AttributeLine,
22 },
23 lines::{
24 bandwidth::*, connection::*, email::*, media::*, origin::*, phone_number::*,
25 session_information::*, session_name::*, timing::*, uri::*, version::*, SessionLine,
26 },
27 media_section::MediaSection,
28 parsers::IpVer,
29 SdpLine, Session,
30};
31impl ufmt::uDisplay for Session<'_> {
32 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
33 where
34 W: uWrite + ?Sized,
35 {
36 write_ln_option(f, &self.version)?;
37 write_ln_option(f, &self.origin)?;
38 write_ln_option(f, &self.name)?;
39 write_ln_option(f, &self.timing)?;
40 write_ln_option(f, &self.band_width)?;
41 write_ln_option(f, &self.uri)?;
42 write_ln_option(f, &self.phone_number)?;
43 write_ln_option(f, &self.email_address)?;
44 write_ln_option(f, &self.connection)?;
45 write_ln_option(f, &self.description)?;
46
47 for x in &self.attributes {
48 uwriteln!(f, "{}", x)?;
49 }
50
51 for x in &self.media {
52 uwrite!(f, "{}", x)?;
53 }
54 Ok(())
55 }
56}
57
58fn write_ln_option<W>(
59 f: &mut Formatter<'_, W>,
60 content: &Option<impl ufmt::uDisplay>,
61) -> Result<(), W::Error>
62where
63 W: uWrite + ?Sized,
64{
65 if let Some(ref x) = content {
66 uwriteln!(f, "{}", x)?;
67 }
68 Ok(())
69}
70
71impl ufmt::uDisplay for MediaSection<'_> {
72 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
73 where
74 W: uWrite + ?Sized,
75 {
76 uwriteln!(f, "{}", self.media())?;
77
78 write_ln_option(f, &self.connection)?;
79
80 write_ln_option(f, &self.rtcp)?;
81 for candidate in &self.candidates {
82 uwriteln!(f, "{}", candidate)?;
83 }
84
85 write_ln_option(f, &self.ice.ufrag.clone().map(IceParameter::Ufrag))?;
86
87 write_ln_option(f, &self.ice.pwd.clone().map(IceParameter::Pwd))?;
88
89 write_ln_option(f, &self.ice.options.clone().map(IceParameter::Options))?;
90
91 write_ln_option(f, &self.fingerprint)?;
92 write_ln_option(f, &self.setup_role)?;
93 write_ln_option(f, &self.mid.to_owned().map(Mid))?;
95
96 write_ln_option(f, &self.p_time)?;
97 for extmap in &self.extmap {
98 uwriteln!(f, "{}", extmap)?;
99 }
100
101 write_ln_option(f, &self.bundle_group)?;
102 if self.bundle_only {
103 uwriteln!(f, "a=bundle-only")?;
104 }
105 write_ln_option(f, &self.direction)?;
106 write_ln_option(f, &self.msid_semantic)?;
107 write_ln_option(f, &self.msid)?;
108 write_ln_option(f, &self.rtp)?;
109 for rtcp_option in &self.rtcp_option {
110 uwriteln!(f, "{}", rtcp_option)?;
111 }
112
113 let known_payloads = self
114 .payloads
115 .iter()
116 .filter_map(|p| p.parse::<u32>().ok())
117 .collect::<Vec<_>>();
118
119 for payload in &known_payloads {
120 for rtp in self.rtp_map.iter().filter(|r| r.payload == *payload) {
121 uwriteln!(f, "{}", rtp)?;
122 }
123 for rtcp_fb in self.rtcp_fb.iter().filter(|r| r.payload == *payload) {
124 uwriteln!(f, "{}", rtcp_fb)?;
125 }
126 for fmtp in self.fmtp.iter().filter(|r| r.payload == *payload) {
127 uwriteln!(f, "{}", fmtp)?;
128 }
129 } {
131 for rtp in self
132 .rtp_map
133 .iter()
134 .filter(|r| !known_payloads.contains(&r.payload))
135 {
136 uwriteln!(f, "{}", rtp)?;
137 }
138 for rtcp_fb in self
139 .rtcp_fb
140 .iter()
141 .filter(|r| !known_payloads.contains(&r.payload))
142 {
143 uwriteln!(f, "{}", rtcp_fb)?;
144 }
145 for fmtp in self
146 .fmtp
147 .iter()
148 .filter(|r| !known_payloads.contains(&r.payload))
149 {
150 uwriteln!(f, "{}", fmtp)?;
151 }
152 }
153
154 write_ln_option(f, &self.ssrc_group)?;
155 for ssrc in &self.ssrc {
156 uwriteln!(f, "{}", ssrc)?;
157 }
158
159 write_ln_option(f, &self.control)?;
160
161 for x in &self.attributes {
162 uwriteln!(f, "{}", x)?;
163 }
164
165 Ok(())
166 }
167}
168impl ufmt::uDisplay for SdpLine<'_> {
169 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
170 where
171 W: uWrite + ?Sized,
172 {
173 match self {
174 SdpLine::Session(session) => uwriteln!(f, "{}", session),
175 SdpLine::Attribute(attribute) => uwriteln!(f, "{}", attribute),
176 SdpLine::Comment(_) => Ok(()),
177 }
178 }
179}
180#[cfg(all(feature = "udisplay"))]
181impl std::string::ToString for SdpLine<'_> {
182 fn to_string(&self) -> String {
183 let mut output = String::new();
184 ufmt::uwrite!(output, "{}", self).unwrap();
185 output
186 }
187}
188
189impl ufmt::uDisplay for SessionLine<'_> {
190 #[rustfmt::skip]
191 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
192 where
193 W: uWrite + ?Sized, {
194 match self {
195 SessionLine::Version(v) => uwrite!(f,"{}", v),
196 SessionLine::Name(n) => uwrite!(f,"{}", n),
197 SessionLine::Timing(t) => uwrite!(f,"{}", t),
198 SessionLine::Origin(o) => uwrite!(f,"{}", o),
199 SessionLine::BandWidth(b) => uwrite!(f,"{}", b),
200 SessionLine::Uri(u) => uwrite!(f,"{}", u),
201 SessionLine::PhoneNumber(p) => uwrite!(f,"{}", p),
202 SessionLine::EmailAddress(e) => uwrite!(f,"{}", e),
203 SessionLine::Connection(c) => uwrite!(f,"{}", c),
204 SessionLine::Description(d) => uwrite!(f,"{}", d),
205 SessionLine::Media(m) => uwrite!(f,"{}", m),
206 }
207 }
208}
209
210impl ufmt::uDisplay for AttributeLine<'_> {
211 #[rustfmt::skip]
212 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
213 where
214 W: uWrite + ?Sized, {
215 match self {
216 AttributeLine::Candidate(c) => uwrite!(f, "{}", c),
217 AttributeLine::Ice(i) => uwrite!(f, "{}", i),
218 AttributeLine::Mid(m) => uwrite!(f, "{}", m),
219 AttributeLine::MsidSemantic(ms) => uwrite!(f, "{}", ms),
220 AttributeLine::Msid(m) => uwrite!(f, "{}", m),
221 AttributeLine::RtpMap(r) => uwrite!(f, "{}", r),
222 AttributeLine::PTime(p) => uwrite!(f, "{}", p),
223 AttributeLine::Ssrc(s) => uwrite!(f, "{}", s),
224 AttributeLine::BundleGroup(b) => uwrite!(f, "{}", b),
225 AttributeLine::SsrcGroup(s) => uwrite!(f, "{}", s),
226 AttributeLine::Fingerprint(fp) => uwrite!(f, "{}", fp),
227 AttributeLine::Direction(d) => uwrite!(f, "{}", d),
228 AttributeLine::Rtp(r) => uwrite!(f, "{}", r),
229 AttributeLine::Rtcp(r) => uwrite!(f, "{}", r),
230 AttributeLine::Fmtp(fmtp) => uwrite!(f, "{}", fmtp),
231 AttributeLine::RtcpFb(r) => uwrite!(f, "{}", r),
232 AttributeLine::RtcpOption(r) => uwrite!(f, "{}", r),
233 AttributeLine::Control(c) => uwrite!(f, "{}", c),
234 AttributeLine::SetupRole(s) => uwrite!(f, "{}", s),
235 AttributeLine::Extmap(e) => uwrite!(f, "{}", e),
236 AttributeLine::BundleOnly => uwrite!(f, "a=bundle-only"),
237 AttributeLine::EoC => uwrite!(f, "a=end-of-candidates"),
238 AttributeLine::KeyValue {
239 key,
240 val
241 } => uwrite!(f, "a={}:{}", key.as_ref(), val.as_ref()),
242 AttributeLine::KeyOnly(key) => uwrite!(f, "a={}", key.as_ref()),
243 }
244 }
245}
246
247impl ufmt::uDisplay for BundleGroup<'_> {
248 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
249 where
250 W: uWrite + ?Sized,
251 {
252 uwrite!(f, "a=group:BUNDLE")?;
253 for v in &self.0 {
254 uwrite!(f, " {}", v.as_ref())?;
255 }
256 Ok(())
257 }
258}
259impl ufmt::uDisplay for Fmtp<'_> {
260 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
261 where
262 W: uWrite + ?Sized,
263 {
264 uwrite!(f, "a=fmtp:{} {}", self.payload, self.config.as_ref())
265 }
266}
267impl ufmt::uDisplay for Rtp<'_> {
268 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
269 where
270 W: uWrite + ?Sized,
271 {
272 uwrite!(
273 f,
274 "a=rtpmap:{} {}/{}/{}",
275 self.payload,
276 self.codec.as_ref(),
277 self.rate,
278 self.encoding
279 )
280 }
281}
282impl ufmt::uDisplay for Control<'_> {
283 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
284 where
285 W: uWrite + ?Sized,
286 {
287 uwrite!(f, "a=control:{}", self.0.as_ref())
288 }
289}
290impl ufmt::uDisplay for Direction {
291 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
292 where
293 W: uWrite + ?Sized,
294 {
295 match self {
296 Direction::SendOnly => uwrite!(f, "a=sendonly"),
297 Direction::SendRecv => uwrite!(f, "a=sendrecv"),
298 Direction::RecvOnly => uwrite!(f, "a=recvonly"),
299 Direction::Inactive => uwrite!(f, "a=inactive"),
300 }
301 }
302}
303impl ufmt::uDisplay for RtcpOption {
304 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
305 where
306 W: uWrite + ?Sized,
307 {
308 match self {
309 RtcpOption::RtcpMux => uwrite!(f, "a=rtcp-mux"),
310 RtcpOption::RtcpMuxOnly => uwrite!(f, "a=rtcp-mux-only"),
311 RtcpOption::RtcpRsize => uwrite!(f, "a=rtcp-rsize"),
312 }
313 }
314}
315impl ufmt::uDisplay for Fingerprint<'_> {
316 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
317 where
318 W: uWrite + ?Sized,
319 {
320 uwrite!(
321 f,
322 "a=fingerprint:{} {}",
323 self.r#type.as_ref(),
324 self.hash.as_ref()
325 )
326 }
327}
328impl ufmt::uDisplay for Mid<'_> {
329 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
330 where
331 W: uWrite + ?Sized,
332 {
333 uwrite!(f, "a=mid:{}", self.0.as_ref())
334 }
335}
336impl ufmt::uDisplay for MsidSemantic<'_> {
337 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
338 where
339 W: uWrite + ?Sized,
340 {
341 uwrite!(f, "a=msid-semantic: ")?;
342 uwrite!(f, "{} ", self.semantic.as_ref())?;
343 if let Some(ref token) = self.token {
344 uwrite!(f, "{}", token.as_ref())?;
345 }
346 Ok(())
347 }
348}
349impl ufmt::uDisplay for Msid<'_> {
350 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
351 where
352 W: uWrite + ?Sized,
353 {
354 uwrite!(f, "a=msid:")?;
355 for (i, x) in self.0.iter().enumerate() {
356 if i > 0 {
357 uwrite!(f, " ")?;
358 }
359 uwrite!(f, "{}", x.as_ref())?;
360 }
361 Ok(())
362 }
363}
364impl ufmt::uDisplay for Version {
365 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
366 where
367 W: uWrite + ?Sized,
368 {
369 uwrite!(f, "v={}", self.0)
370 }
371}
372impl ufmt::uDisplay for SessionInformation<'_> {
373 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
374 where
375 W: uWrite + ?Sized,
376 {
377 uwrite!(f, "i={}", self.0.as_ref())
378 }
379}
380impl ufmt::uDisplay for SessionName<'_> {
381 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
382 where
383 W: uWrite + ?Sized,
384 {
385 uwrite!(f, "s={}", self.0.as_ref())
386 }
387}
388
389impl ufmt::uDisplay for Origin<'_> {
390 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
391 where
392 W: uWrite + ?Sized,
393 {
394 uwrite!(
395 f,
396 "o={} {} {} {} {} {}",
397 self.user_name.as_ref(),
398 self.session_id,
399 self.session_version,
400 self.net_type.as_ref(),
401 self.ip_ver,
402 IpAddress(&self.addr)
403 )
404 }
405}
406
407impl ufmt::uDisplay for Media<'_> {
408 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
409 where
410 W: uWrite + ?Sized,
411 {
412 uwrite!(
413 f,
414 "m={} {} {}",
415 self.r#type.as_ref(),
416 self.port,
417 self.protocol.join("/").as_str(),
418 )?;
419 for payload in &self.payloads {
420 uwrite!(f, " {}", payload.as_ref())?;
421 }
422 Ok(())
423 }
424}
425
426struct IpAddress<'a>(&'a std::net::IpAddr);
427#[allow(clippy::many_single_char_names)]
428impl ufmt::uDisplay for IpAddress<'_> {
429 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
430 where
431 W: uWrite + ?Sized,
432 {
433 match self.0 {
434 std::net::IpAddr::V4(addr) => {
435 let [a, b, c, d] = addr.octets();
436 uwrite!(f, "{}.{}.{}.{}", a, b, c, d)
437 }
438 std::net::IpAddr::V6(addr) => {
439 uwrite!(f, "{}", addr.to_string())
440 }
441 }
442 }
443}
444
445impl ufmt::uDisplay for Connection {
446 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
447 where
448 W: uWrite + ?Sized,
449 {
450 let Self { ip_ver, addr, mask } = self;
451 if let Some(mask) = mask {
452 uwrite!(f, "c=IN {} {}/{}", ip_ver, IpAddress(addr), mask)
453 } else {
454 uwrite!(f, "c=IN {} {}", ip_ver, IpAddress(addr))
455 }
456 }
457}
458impl ufmt::uDisplay for SsrcGroup {
459 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
460 where
461 W: uWrite + ?Sized,
462 {
463 uwrite!(f, "a=ssrc-group:")?;
464 match self.semantic {
465 SsrcSemantic::FID => uwrite!(f, "FID")?,
466 SsrcSemantic::FEC => uwrite!(f, "FEC")?,
467 }
468 for id in &self.ids {
469 uwrite!(f, " {}", id)?;
470 }
471 Ok(())
472 }
473}
474impl ufmt::uDisplay for Ssrc<'_> {
475 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
476 where
477 W: uWrite + ?Sized,
478 {
479 uwrite!(
480 f,
481 "a=ssrc:{} {}:{}",
482 self.id,
483 self.attribute.as_ref(),
484 self.value.as_ref()
485 )
486 }
487}
488impl ufmt::uDisplay for RtpMap<'_> {
489 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
490 where
491 W: uWrite + ?Sized,
492 {
493 uwrite!(
494 f,
495 "a=rtpmap:{} {}",
496 self.payload,
497 self.encoding_name.as_ref()
498 )?;
499 if let Some(clock_rate) = self.clock_rate {
500 uwrite!(f, "/{}", clock_rate)?;
501 }
502 if let Some(encoding) = self.encoding {
503 uwrite!(f, "/{}", encoding)?;
504 }
505 Ok(())
506 }
507}
508impl ufmt::uDisplay for PTime {
509 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
510 where
511 W: uWrite + ?Sized,
512 {
513 match self {
514 PTime::MaxPTime(x) => uwrite!(f, "a=maxptime:{}", x),
515 PTime::MinPTime(x) => uwrite!(f, "a=minptime:{}", x),
516 PTime::PTime(x) => uwrite!(f, "a=ptime:{}", x),
517 }
518 }
519}
520
521impl ufmt::uDisplay for FbAckParam<'_> {
522 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
523 where
524 W: uWrite + ?Sized,
525 {
526 match self {
527 FbAckParam::Rpsi => uwrite!(f, "rpsi"),
528 FbAckParam::Sli(Some(x)) => uwrite!(f, "sli {}", x.as_ref()),
529 FbAckParam::Sli(None) => uwrite!(f, "sli"),
530 FbAckParam::App(x) => uwrite!(f, "app {}", x.as_ref()),
531 FbAckParam::Other(k, Some(v)) => uwrite!(f, "{} {}", k.as_ref(), v.as_ref()),
532 FbAckParam::Other(k, None) => uwrite!(f, "{}", k.as_ref()),
533 }
534 }
535}
536
537impl ufmt::uDisplay for FbNackParam<'_> {
538 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
539 where
540 W: uWrite + ?Sized,
541 {
542 match self {
543 FbNackParam::Pli => uwrite!(f, "pli"),
544 FbNackParam::Rpsi => uwrite!(f, "rpsi"),
545 FbNackParam::Sli => uwrite!(f, "sli"),
546 FbNackParam::Other(k, v) => uwrite!(f, "{} {}", k.as_ref(), v.as_ref()),
547 FbNackParam::App(x) => uwrite!(f, "app {}", x.as_ref()),
548 }
549 }
550}
551
552impl ufmt::uDisplay for FbParam<'_> {
553 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
554 where
555 W: uWrite + ?Sized,
556 {
557 match self {
558 FbParam::App(p) => uwrite!(f, "app {}", p.as_ref()),
559 FbParam::Single(p) => uwrite!(f, "{}", p.as_ref()),
560 FbParam::Pair(k, v) => uwrite!(f, "{} {}", k.as_ref(), v.as_ref()),
561 }
562 }
563}
564
565impl ufmt::uDisplay for FbVal<'_> {
566 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
567 where
568 W: uWrite + ?Sized,
569 {
570 match self {
571 FbVal::Ack(p) => uwrite!(f, "ack {}", p),
572 FbVal::Nack(p) => uwrite!(f, "nack {}", p),
573 FbVal::TrrInt(p) => uwrite!(f, "trr-int {}", p),
574 FbVal::RtcpFbId {
575 id,
576 param: Some(param),
577 } => uwrite!(f, "{} {}", id.as_ref(), param),
578 FbVal::RtcpFbId { id, param: None } => uwrite!(f, "{}", id.as_ref()),
579 }
580 }
581}
582
583impl ufmt::uDisplay for Fb<'_> {
584 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
585 where
586 W: uWrite + ?Sized,
587 {
588 uwrite!(f, "a=rtcp-fb:{} {}", self.payload, self.val)
589 }
590}
591impl ufmt::uDisplay for NetType {
592 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
593 where
594 W: uWrite + ?Sized,
595 {
596 uwrite!(f, "IN")
597 }
598}
599
600impl ufmt::uDisplay for Rtcp {
601 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
602 where
603 W: uWrite + ?Sized,
604 {
605 uwrite!(
606 f,
607 "a=rtcp:{} {} {} {}",
608 self.port,
609 self.net_type,
610 self.ip_ver,
611 IpAddress(&self.addr),
612 )
613 }
614}
615
616impl ufmt::uDisplay for IceParameter<'_> {
617 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
618 where
619 W: uWrite + ?Sized,
620 {
621 match self {
622 IceParameter::Ufrag(ufrag) => uwrite!(f, "a=ice-ufrag:{}", ufrag.as_ref()),
623 IceParameter::Pwd(pwd) => uwrite!(f, "a=ice-pwd:{}", pwd.as_ref()),
624 IceParameter::Options(options) => uwrite!(f, "a=ice-options:{}", options.as_ref()),
625 IceParameter::Mismatch => uwrite!(f, "a=ice-mismatch"),
626 IceParameter::Lite => uwrite!(f, "a=ice-lite"),
627 }
628 }
629}
630
631impl ufmt::uDisplay for Extmap<'_> {
632 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
633 where
634 W: uWrite + ?Sized,
635 {
636 if let Some(direction) = self.direction {
637 uwrite!(f, "a=extmap:{}/", self.value,)?;
638
639 match direction {
640 Direction::SendOnly => uwrite!(f, "sendonly")?,
641 Direction::SendRecv => uwrite!(f, "sendrecv")?,
642 Direction::RecvOnly => uwrite!(f, "recvonly")?,
643 Direction::Inactive => uwrite!(f, "inactive")?,
644 }
645
646 uwrite!(f, " {}", self.uri.as_ref())?;
647 } else {
648 uwrite!(f, "a=extmap:{} {}", self.value, self.uri.as_ref())?;
649 }
650 for a in &self.attributes {
651 uwrite!(f, " {}", a.as_ref())?;
652 }
653 Ok(())
654 }
655}
656impl ufmt::uDisplay for BandWidthType {
657 #[rustfmt::skip]
658 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
659 where
660 W: uWrite + ?Sized, {
661 use BandWidthType::*;
662 uwrite!( f, "{}", match self { TIAS => "TIAS", AS => "AS", CT => "CT", RR => "RR", RS => "R" })
663 }
664}
665
666impl ufmt::uDisplay for BandWidth {
667 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
668 where
669 W: uWrite + ?Sized,
670 {
671 uwrite!(f, "b={}:{}", self.r#type, self.limit)
672 }
673}
674
675impl ufmt::uDisplay for Uri<'_> {
676 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
677 where
678 W: uWrite + ?Sized,
679 {
680 uwrite!(f, "u={}", self.0.as_ref())
681 }
682}
683impl ufmt::uDisplay for EmailAddress<'_> {
684 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
685 where
686 W: uWrite + ?Sized,
687 {
688 uwrite!(f, "e={}", self.0.as_ref())
689 }
690}
691impl ufmt::uDisplay for PhoneNumber<'_> {
692 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
693 where
694 W: uWrite + ?Sized,
695 {
696 uwrite!(f, "p={}", self.0.as_ref())
697 }
698}
699impl ufmt::uDisplay for Timing {
700 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
701 where
702 W: uWrite + ?Sized,
703 {
704 uwrite!(f, "t={} {}", self.start, self.stop)
705 }
706}
707
708impl ufmt::uDisplay for IpVer {
709 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
710 where
711 W: uWrite + ?Sized,
712 {
713 match self {
714 IpVer::Ip4 => uwrite!(f, "IP4"),
715 IpVer::Ip6 => uwrite!(f, "IP6"),
716 }
717 }
718}
719impl ufmt::uDisplay for CandidateComponent {
720 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
721 where
722 W: uWrite + ?Sized,
723 {
724 match self {
725 CandidateComponent::Rtp => uwrite!(f, "1"),
726 CandidateComponent::Rtcp => uwrite!(f, "2"),
727 }
728 }
729}
730
731impl ufmt::uDisplay for CandidateProtocol {
732 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
733 where
734 W: uWrite + ?Sized,
735 {
736 match self {
737 CandidateProtocol::Tcp => uwrite!(f, "tcp"),
738 CandidateProtocol::Udp => uwrite!(f, "udp"),
739 CandidateProtocol::Dccp => uwrite!(f, "dccp"),
740 }
741 }
742}
743
744impl ufmt::uDisplay for CandidateType {
745 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
746 where
747 W: uWrite + ?Sized,
748 {
749 match self {
750 CandidateType::Host => uwrite!(f, "host"),
751 CandidateType::Relay => uwrite!(f, "relay"),
752 CandidateType::Srflx => uwrite!(f, "srflx"),
753 CandidateType::Prflx => uwrite!(f, "prflx"),
754 }
755 }
756}
757
758impl ufmt::uDisplay for Candidate<'_> {
759 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
760 where
761 W: uWrite + ?Sized,
762 {
763 uwrite!(
764 f,
765 "a=candidate:{} {} {} {} {} {} typ {}",
766 self.foundation,
767 self.component,
768 self.protocol,
769 self.priority,
770 IpAddress(&self.addr),
771 self.port,
772 self.r#type,
773 )?;
774 if let Some(x) = self.raddr {
775 uwrite!(f, " raddr {}", IpAddress(&x))?;
776 }
777 if let Some(x) = self.rport {
778 uwrite!(f, " rport {}", x)?;
779 }
780 if let Some(x) = self.tcptype.as_ref() {
781 uwrite!(f, " tcptype {}", x.as_ref())?;
782 }
783 if let Some(x) = self.generation {
784 uwrite!(f, " generation {}", x)?;
785 }
786 if let Some(x) = self.network_id {
787 uwrite!(f, " network-id {}", x)?;
788 }
789 Ok(())
790 }
791}
792
793impl ufmt::uDisplay for SetupRole {
794 fn fmt<W>(&self, f: &mut Formatter<'_, W>) -> Result<(), W::Error>
795 where
796 W: uWrite + ?Sized,
797 {
798 match self {
799 SetupRole::Active => uwrite!(f, "a=setup:active"),
800 SetupRole::Passive => uwrite!(f, "a=setup:passive"),
801 SetupRole::ActPass => uwrite!(f, "a=setup:actpass"),
802 }
803 }
804}