1use crate::{attributes, clock_signalling, enums};
6use std::net::IpAddr;
7
8#[derive(Debug)]
10pub struct Origin(crate::Origin);
11impl Origin {
12 pub fn with_ip_addr(
14 sess_id: impl ToString,
15 sess_version: u64,
16 unicast_address: impl Into<IpAddr>,
17 ) -> Self {
18 Self(crate::Origin::with_ip_addr(
19 sess_id,
20 sess_version,
21 unicast_address,
22 ))
23 }
24
25 pub fn new(
29 sess_id: impl ToString,
30 sess_version: u64,
31 nettype: enums::NetType,
32 addrtype: enums::AddrType,
33 unicast_address: impl ToString,
34 ) -> Self {
35 Self(crate::Origin::new(
36 sess_id,
37 sess_version,
38 nettype,
39 addrtype,
40 unicast_address,
41 ))
42 }
43
44 pub fn username(mut self, username: impl ToString) -> Self {
45 self.0.set_username(username);
46 self
47 }
48
49 pub fn username_if(mut self, username: impl ToString, predicate: bool) -> Self {
50 if predicate {
51 self.0.set_username(username);
52 }
53 self
54 }
55
56 pub fn username_if_some(mut self, username: Option<impl ToString>) -> Self {
57 if let Some(username) = username {
58 self.0.set_username(username);
59 }
60 self
61 }
62
63 pub fn build(self) -> crate::Origin {
64 self.0
65 }
66}
67
68#[derive(Debug)]
70pub struct Time(crate::Time);
71impl Time {
72 pub fn new(start_time: u64, stop_time: u64) -> Self {
73 Self(crate::Time::new(start_time, stop_time))
74 }
75
76 pub fn repeat(mut self, repeat: crate::Repeat) -> Self {
77 self.0.add_repeat(repeat);
78 self
79 }
80
81 pub fn repeat_if(mut self, repeat: crate::Repeat, predicate: bool) -> Self {
82 if predicate {
83 self.0.add_repeat(repeat);
84 }
85 self
86 }
87
88 pub fn repeat_if_some(mut self, repeat: Option<crate::Repeat>) -> Self {
89 if let Some(repeat) = repeat {
90 self.0.add_repeat(repeat);
91 }
92 self
93 }
94
95 pub fn repeats(mut self, repeats: impl IntoIterator<Item = crate::Repeat>) -> Self {
96 self.0.add_repeats(repeats);
97 self
98 }
99
100 pub fn repeats_if(
101 mut self,
102 repeats: impl IntoIterator<Item = crate::Repeat>,
103 predicate: bool,
104 ) -> Self {
105 if predicate {
106 self.0.add_repeats(repeats);
107 }
108 self
109 }
110
111 pub fn build(self) -> crate::Time {
112 self.0
113 }
114}
115
116#[derive(Debug)]
118pub struct Repeat(crate::Repeat);
119impl Repeat {
120 pub fn new(repeat_interval: u64, active_duration: u64) -> Self {
121 Self(crate::Repeat::new(repeat_interval, active_duration))
122 }
123
124 pub fn offset(mut self, repeat: u64) -> Self {
125 self.0.add_offset(repeat);
126 self
127 }
128
129 pub fn offset_if(mut self, offset: u64, predicate: bool) -> Self {
130 if predicate {
131 self.0.add_offset(offset);
132 }
133 self
134 }
135
136 pub fn offset_if_some(mut self, offset: Option<u64>) -> Self {
137 if let Some(offset) = offset {
138 self.0.add_offset(offset);
139 }
140 self
141 }
142
143 pub fn offsets(mut self, offsets: impl IntoIterator<Item = u64>) -> Self {
144 self.0.add_offsets(offsets);
145 self
146 }
147
148 pub fn offsets_if(mut self, offsets: impl IntoIterator<Item = u64>, predicate: bool) -> Self {
149 if predicate {
150 self.0.add_offsets(offsets);
151 }
152 self
153 }
154
155 pub fn build(self) -> crate::Repeat {
156 self.0
157 }
158}
159
160#[derive(Debug)]
162pub struct Media(crate::Media);
163impl Media {
164 pub fn new(
165 media: enums::MediaType,
166 port: u16,
167 proto: enums::TransportProto,
168 fmt: impl ToString,
169 ) -> Self {
170 Self(crate::Media::new(media, port, proto, fmt))
171 }
172
173 pub fn num_ports(mut self, num_ports: u16) -> Self {
174 self.0.set_num_ports(num_ports);
175 self
176 }
177
178 pub fn num_ports_if(mut self, num_ports: u16, predicate: bool) -> Self {
179 if predicate {
180 self.0.set_num_ports(num_ports);
181 }
182 self
183 }
184
185 pub fn num_ports_if_some(mut self, num_ports: Option<u16>) -> Self {
186 if let Some(num_ports) = num_ports {
187 self.0.set_num_ports(num_ports);
188 }
189 self
190 }
191
192 pub fn media_title(mut self, media_title: impl ToString) -> Self {
193 self.0.set_media_title(media_title);
194 self
195 }
196
197 pub fn media_title_if(mut self, media_title: impl ToString, predicate: bool) -> Self {
198 if predicate {
199 self.0.set_media_title(media_title);
200 }
201 self
202 }
203
204 pub fn media_title_if_some(mut self, media_title: Option<impl ToString>) -> Self {
205 if let Some(media_title) = media_title {
206 self.0.set_media_title(media_title);
207 }
208 self
209 }
210
211 pub fn connection(mut self, connection: impl Into<crate::Connection>) -> Self {
212 self.0.add_connection(connection);
213 self
214 }
215
216 pub fn connection_if(
217 mut self,
218 connection: impl Into<crate::Connection>,
219 predicate: bool,
220 ) -> Self {
221 if predicate {
222 self.0.add_connection(connection);
223 }
224 self
225 }
226
227 pub fn connection_if_some(mut self, connection: Option<impl Into<crate::Connection>>) -> Self {
228 if let Some(connection) = connection {
229 self.0.add_connection(connection);
230 }
231 self
232 }
233
234 pub fn connections(
235 mut self,
236 connections: impl IntoIterator<Item = impl Into<crate::Connection>>,
237 ) -> Self {
238 self.0.add_connections(connections);
239 self
240 }
241
242 pub fn connections_if(
243 mut self,
244 connections: impl IntoIterator<Item = impl Into<crate::Connection>>,
245 predicate: bool,
246 ) -> Self {
247 if predicate {
248 self.0.add_connections(connections);
249 }
250 self
251 }
252
253 pub fn bandwidth(mut self, bandwidth: crate::Bandwidth) -> Self {
254 self.0.add_bandwidth(bandwidth);
255 self
256 }
257
258 pub fn bandwidth_if(mut self, bandwidth: crate::Bandwidth, predicate: bool) -> Self {
259 if predicate {
260 self.0.add_bandwidth(bandwidth);
261 }
262 self
263 }
264
265 pub fn bandwidth_if_some(mut self, bandwidth: Option<crate::Bandwidth>) -> Self {
266 if let Some(bandwidth) = bandwidth {
267 self.0.add_bandwidth(bandwidth);
268 }
269 self
270 }
271
272 pub fn bandwidths(mut self, bandwidths: impl IntoIterator<Item = crate::Bandwidth>) -> Self {
273 self.0.add_bandwidths(bandwidths);
274 self
275 }
276
277 pub fn bandwidths_if(
278 mut self,
279 bandwidths: impl IntoIterator<Item = crate::Bandwidth>,
280 predicate: bool,
281 ) -> Self {
282 if predicate {
283 self.0.add_bandwidths(bandwidths);
284 }
285 self
286 }
287
288 pub fn encryption_key(mut self, key: impl Into<crate::Key>) -> Self {
289 self.0.set_encryption_key(key);
290 self
291 }
292
293 pub fn encryption_key_if(
294 mut self,
295 encryption_key: impl Into<crate::Key>,
296 predicate: bool,
297 ) -> Self {
298 if predicate {
299 self.0.set_encryption_key(encryption_key);
300 }
301 self
302 }
303
304 pub fn encryption_key_if_some(mut self, encryption_key: Option<impl Into<crate::Key>>) -> Self {
305 if let Some(encryption_key) = encryption_key {
306 self.0.set_encryption_key(encryption_key);
307 }
308 self
309 }
310
311 pub fn attribute(mut self, attribute: impl Into<crate::Attribute>) -> Self {
312 self.0.add_attribute(attribute);
313 self
314 }
315
316 pub fn attribute_if(mut self, attribute: impl Into<crate::Attribute>, predicate: bool) -> Self {
317 if predicate {
318 self.0.add_attribute(attribute);
319 }
320 self
321 }
322
323 pub fn attribute_if_some(mut self, attribute: Option<impl Into<crate::Attribute>>) -> Self {
324 if let Some(attribute) = attribute {
325 self.0.add_attribute(attribute);
326 }
327 self
328 }
329
330 pub fn attribute_from_str(mut self, attribute: impl ToString) -> Self {
331 self.0.add_attribute_from_str(attribute);
332 self
333 }
334
335 pub fn attribute_from_str_if(mut self, attribute: impl ToString, predicate: bool) -> Self {
336 if predicate {
337 self.0.add_attribute_from_str(attribute);
338 }
339 self
340 }
341
342 pub fn attribute_from_str_if_some(mut self, attribute: Option<impl ToString>) -> Self {
343 if let Some(attribute) = attribute {
344 self.0.add_attribute_from_str(attribute);
345 }
346 self
347 }
348
349 pub fn attribute_with_value(mut self, attribute: impl ToString, value: impl ToString) -> Self {
350 self.0.add_attribute_with_value(attribute, value);
351 self
352 }
353
354 pub fn attribute_with_value_if(
355 mut self,
356 attribute: impl ToString,
357 value: impl ToString,
358 predicate: bool,
359 ) -> Self {
360 if predicate {
361 self.0.add_attribute_with_value(attribute, value);
362 }
363 self
364 }
365
366 pub fn attribute_with_value_if_some(
367 mut self,
368 attribute: impl ToString,
369 value: Option<impl ToString>,
370 ) -> Self {
371 if let Some(value) = value {
372 self.0.add_attribute_with_value(attribute, value);
373 }
374 self
375 }
376
377 pub fn attributes(
378 mut self,
379 attributes: impl IntoIterator<Item = impl Into<crate::Attribute>>,
380 ) -> Self {
381 self.0.add_attributes(attributes);
382 self
383 }
384
385 pub fn attributes_if(
386 mut self,
387 attributes: impl IntoIterator<Item = impl Into<crate::Attribute>>,
388 predicate: bool,
389 ) -> Self {
390 if predicate {
391 self.0.add_attributes(attributes);
392 }
393 self
394 }
395
396 pub fn attributes_from_strs(
397 mut self,
398 attributes: impl IntoIterator<Item = impl ToString>,
399 ) -> Self {
400 self.0.add_attributes_from_strs(attributes);
401 self
402 }
403
404 pub fn attributes_from_strs_if(
405 mut self,
406 attributes: impl IntoIterator<Item = impl ToString>,
407 predicate: bool,
408 ) -> Self {
409 if predicate {
410 self.0.add_attributes_from_strs(attributes);
411 }
412 self
413 }
414
415 pub fn attributes_from_strs_if_some(
416 mut self,
417 attributes: Option<impl IntoIterator<Item = impl ToString>>,
418 ) -> Self {
419 if let Some(attributes) = attributes {
420 self.0.add_attributes_from_strs(attributes);
421 }
422 self
423 }
424
425 pub fn build(self) -> crate::Media {
426 self.0
427 }
428}
429
430#[derive(Debug)]
432pub struct Session(crate::Session);
433impl Session {
434 pub fn new(origin: crate::Origin, session_name: impl ToString) -> Self {
435 Self(crate::Session::new(origin, session_name))
436 }
437
438 pub fn session_description(mut self, session_description: impl ToString) -> Self {
439 self.0.set_session_description(session_description);
440 self
441 }
442
443 pub fn session_description_if(
444 mut self,
445 session_description: impl ToString,
446 predicate: bool,
447 ) -> Self {
448 if predicate {
449 self.0.set_session_description(session_description);
450 }
451 self
452 }
453
454 pub fn session_description_if_some(
455 mut self,
456 session_description: Option<impl ToString>,
457 ) -> Self {
458 if let Some(session_description) = session_description {
459 self.0.set_session_description(session_description);
460 }
461 self
462 }
463
464 pub fn uri(mut self, uri: impl ToString) -> Self {
465 self.0.set_uri(uri);
466 self
467 }
468
469 pub fn uri_if(mut self, uri: impl ToString, predicate: bool) -> Self {
470 if predicate {
471 self.0.set_uri(uri);
472 }
473 self
474 }
475
476 pub fn uri_if_some(mut self, uri: Option<impl ToString>) -> Self {
477 if let Some(uri) = uri {
478 self.0.set_uri(uri);
479 }
480 self
481 }
482
483 pub fn email(mut self, email: impl ToString) -> Self {
484 self.0.add_email(email);
485 self
486 }
487
488 pub fn email_if(mut self, email: impl ToString, predicate: bool) -> Self {
489 if predicate {
490 self.0.add_email(email);
491 }
492 self
493 }
494
495 pub fn email_if_some(mut self, email: Option<impl ToString>) -> Self {
496 if let Some(email) = email {
497 self.0.add_email(email);
498 }
499 self
500 }
501
502 pub fn emails(mut self, emails: impl IntoIterator<Item = impl ToString>) -> Self {
503 self.0.add_emails(emails);
504 self
505 }
506
507 pub fn emails_if(
508 mut self,
509 emails: impl IntoIterator<Item = impl ToString>,
510 predicate: bool,
511 ) -> Self {
512 if predicate {
513 self.0.add_emails(emails);
514 }
515 self
516 }
517
518 pub fn phone(mut self, phone: impl ToString) -> Self {
519 self.0.add_phone(phone);
520 self
521 }
522
523 pub fn phone_if(mut self, phone: impl ToString, predicate: bool) -> Self {
524 if predicate {
525 self.0.add_phone(phone);
526 }
527 self
528 }
529
530 pub fn phone_if_some(mut self, phone: Option<impl ToString>) -> Self {
531 if let Some(phone) = phone {
532 self.0.add_phone(phone);
533 }
534 self
535 }
536
537 pub fn phones(mut self, phones: impl IntoIterator<Item = impl ToString>) -> Self {
538 self.0.add_phones(phones);
539 self
540 }
541
542 pub fn phones_if(
543 mut self,
544 phones: impl IntoIterator<Item = impl ToString>,
545 predicate: bool,
546 ) -> Self {
547 if predicate {
548 self.0.add_phones(phones);
549 }
550 self
551 }
552
553 pub fn connection(mut self, connection: impl Into<crate::Connection>) -> Self {
554 self.0.set_connection(connection);
555 self
556 }
557
558 pub fn connection_if(
559 mut self,
560 connection: impl Into<crate::Connection>,
561 predicate: bool,
562 ) -> Self {
563 if predicate {
564 self.0.set_connection(connection);
565 }
566 self
567 }
568
569 pub fn connection_if_some(mut self, connection: Option<impl Into<crate::Connection>>) -> Self {
570 if let Some(connection) = connection {
571 self.0.set_connection(connection);
572 }
573 self
574 }
575
576 pub fn bandwidth(mut self, bandwidth: crate::Bandwidth) -> Self {
577 self.0.add_bandwidth(bandwidth);
578 self
579 }
580
581 pub fn bandwidth_if(mut self, bandwidth: crate::Bandwidth, predicate: bool) -> Self {
582 if predicate {
583 self.0.add_bandwidth(bandwidth);
584 }
585 self
586 }
587
588 pub fn bandwidth_if_some(mut self, bandwidth: Option<crate::Bandwidth>) -> Self {
589 if let Some(bandwidth) = bandwidth {
590 self.0.add_bandwidth(bandwidth);
591 }
592 self
593 }
594
595 pub fn bandwidths(mut self, bandwidths: impl IntoIterator<Item = crate::Bandwidth>) -> Self {
596 self.0.add_bandwidths(bandwidths);
597 self
598 }
599
600 pub fn bandwidths_if(
601 mut self,
602 bandwidths: impl IntoIterator<Item = crate::Bandwidth>,
603 predicate: bool,
604 ) -> Self {
605 if predicate {
606 self.0.add_bandwidths(bandwidths);
607 }
608 self
609 }
610
611 pub fn time(mut self, time: crate::Time) -> Self {
612 self.0.add_time(time);
613 self
614 }
615
616 pub fn time_if(mut self, time: crate::Time, predicate: bool) -> Self {
617 if predicate {
618 self.0.add_time(time);
619 }
620 self
621 }
622
623 pub fn time_if_some(mut self, time: Option<crate::Time>) -> Self {
624 if let Some(time) = time {
625 self.0.add_time(time);
626 }
627 self
628 }
629
630 pub fn times(mut self, times: impl IntoIterator<Item = crate::Time>) -> Self {
631 self.0.add_times(times);
632 self
633 }
634
635 pub fn times_if(
636 mut self,
637 times: impl IntoIterator<Item = crate::Time>,
638 predicate: bool,
639 ) -> Self {
640 if predicate {
641 self.0.add_times(times);
642 }
643 self
644 }
645
646 pub fn times_if_some(mut self, times: Option<impl IntoIterator<Item = crate::Time>>) -> Self {
647 if let Some(times) = times {
648 self.0.add_times(times);
649 }
650 self
651 }
652
653 pub fn time_zone(mut self, time_zone: crate::TimeZone) -> Self {
654 self.0.add_time_zone(time_zone);
655 self
656 }
657
658 pub fn time_zone_if(mut self, time_zone: crate::TimeZone, predicate: bool) -> Self {
659 if predicate {
660 self.0.add_time_zone(time_zone);
661 }
662 self
663 }
664
665 pub fn time_zone_if_some(mut self, time_zone: Option<crate::TimeZone>) -> Self {
666 if let Some(time_zone) = time_zone {
667 self.0.add_time_zone(time_zone);
668 }
669 self
670 }
671
672 pub fn time_zones(mut self, time_zones: impl IntoIterator<Item = crate::TimeZone>) -> Self {
673 self.0.add_time_zones(time_zones);
674 self
675 }
676
677 pub fn time_zones_if(
678 mut self,
679 time_zones: impl IntoIterator<Item = crate::TimeZone>,
680 predicate: bool,
681 ) -> Self {
682 if predicate {
683 self.0.add_time_zones(time_zones);
684 }
685 self
686 }
687
688 pub fn encryption_key(mut self, key: impl Into<crate::Key>) -> Self {
689 self.0.set_encryption_key(key);
690 self
691 }
692
693 pub fn encryption_key_if(
694 mut self,
695 encryption_key: impl Into<crate::Key>,
696 predicate: bool,
697 ) -> Self {
698 if predicate {
699 self.0.set_encryption_key(encryption_key);
700 }
701 self
702 }
703
704 pub fn encryption_key_if_some(mut self, encryption_key: Option<impl Into<crate::Key>>) -> Self {
705 if let Some(encryption_key) = encryption_key {
706 self.0.set_encryption_key(encryption_key);
707 }
708 self
709 }
710
711 pub fn attribute(mut self, attribute: impl Into<crate::Attribute>) -> Self {
712 self.0.add_attribute(attribute);
713 self
714 }
715
716 pub fn attribute_if(mut self, attribute: impl Into<crate::Attribute>, predicate: bool) -> Self {
717 if predicate {
718 self.0.add_attribute(attribute);
719 }
720 self
721 }
722
723 pub fn attribute_if_some(mut self, attribute: Option<impl Into<crate::Attribute>>) -> Self {
724 if let Some(attribute) = attribute {
725 self.0.add_attribute(attribute);
726 }
727 self
728 }
729
730 pub fn attribute_from_str(mut self, attribute: impl ToString) -> Self {
731 self.0.add_attribute_from_str(attribute);
732 self
733 }
734
735 pub fn attribute_from_str_if(mut self, attribute: impl ToString, predicate: bool) -> Self {
736 if predicate {
737 self.0.add_attribute_from_str(attribute);
738 }
739 self
740 }
741
742 pub fn attribute_from_str_if_some(mut self, attribute: Option<impl ToString>) -> Self {
743 if let Some(attribute) = attribute {
744 self.0.add_attribute_from_str(attribute);
745 }
746 self
747 }
748
749 pub fn attribute_with_value(mut self, attribute: impl ToString, value: impl ToString) -> Self {
750 self.0.add_attribute_with_value(attribute, value);
751 self
752 }
753
754 pub fn attribute_with_value_if(
755 mut self,
756 attribute: impl ToString,
757 value: impl ToString,
758 predicate: bool,
759 ) -> Self {
760 if predicate {
761 self.0.add_attribute_with_value(attribute, value);
762 }
763 self
764 }
765
766 pub fn attribute_with_value_if_some(
767 mut self,
768 attribute: impl ToString,
769 value: Option<impl ToString>,
770 ) -> Self {
771 if let Some(value) = value {
772 self.0.add_attribute_with_value(attribute, value);
773 }
774 self
775 }
776
777 pub fn attributes(
778 mut self,
779 attributes: impl IntoIterator<Item = impl Into<crate::Attribute>>,
780 ) -> Self {
781 self.0.add_attributes(attributes);
782 self
783 }
784
785 pub fn attributes_if(
786 mut self,
787 attributes: impl IntoIterator<Item = impl Into<crate::Attribute>>,
788 predicate: bool,
789 ) -> Self {
790 if predicate {
791 self.0.add_attributes(attributes);
792 }
793 self
794 }
795
796 pub fn attributes_if_some(
797 mut self,
798 attributes: Option<impl IntoIterator<Item = impl Into<crate::Attribute>>>,
799 ) -> Self {
800 if let Some(attributes) = attributes {
801 self.0.add_attributes(attributes);
802 }
803 self
804 }
805
806 pub fn attributes_from_strs(
807 mut self,
808 attributes: impl IntoIterator<Item = impl ToString>,
809 ) -> Self {
810 self.0.add_attributes_from_strs(attributes);
811 self
812 }
813
814 pub fn attributes_from_strs_if(
815 mut self,
816 attributes: impl IntoIterator<Item = impl ToString>,
817 predicate: bool,
818 ) -> Self {
819 if predicate {
820 self.0.add_attributes_from_strs(attributes);
821 }
822 self
823 }
824
825 pub fn attributes_from_strs_if_some(
826 mut self,
827 attributes: Option<impl IntoIterator<Item = impl ToString>>,
828 ) -> Self {
829 if let Some(attributes) = attributes {
830 self.0.add_attributes_from_strs(attributes);
831 }
832 self
833 }
834
835 pub fn media(mut self, media: crate::Media) -> Self {
836 self.0.add_media(media);
837 self
838 }
839
840 pub fn media_if(mut self, media: crate::Media, predicate: bool) -> Self {
841 if predicate {
842 self.0.add_media(media);
843 }
844 self
845 }
846
847 pub fn media_if_some(mut self, media: Option<crate::Media>) -> Self {
848 if let Some(media) = media {
849 self.0.add_media(media);
850 }
851 self
852 }
853
854 pub fn medias(mut self, medias: impl IntoIterator<Item = crate::Media>) -> Self {
855 self.0.add_medias(medias);
856 self
857 }
858
859 pub fn medias_if(
860 mut self,
861 medias: impl IntoIterator<Item = crate::Media>,
862 predicate: bool,
863 ) -> Self {
864 if predicate {
865 self.0.add_medias(medias);
866 }
867 self
868 }
869
870 pub fn build(self) -> crate::Session {
871 self.0
872 }
873}
874
875#[derive(Debug)]
879pub struct RtpMap(attributes::RtpMap);
880impl RtpMap {
881 pub fn new(payload_type: u8, encoding_name: impl ToString, clock_rate: u32) -> Self {
882 Self(attributes::RtpMap::new(
883 payload_type,
884 encoding_name,
885 clock_rate,
886 ))
887 }
888
889 pub fn encoding_params(mut self, encoding_params: impl ToString) -> Self {
890 self.0.set_encoding_params(encoding_params);
891 self
892 }
893
894 pub fn encoding_params_if(mut self, encoding_params: impl ToString, predicate: bool) -> Self {
895 if predicate {
896 self.0.set_encoding_params(encoding_params);
897 }
898 self
899 }
900
901 pub fn encoding_params_if_some(mut self, encoding_params: Option<impl ToString>) -> Self {
902 if let Some(encoding_params) = encoding_params {
903 self.0.set_encoding_params(encoding_params);
904 }
905 self
906 }
907
908 pub fn build(self) -> attributes::RtpMap {
909 self.0
910 }
911}
912
913#[derive(Debug)]
915pub struct FmtpParam(attributes::FmtpParam);
916impl FmtpParam {
917 pub fn new(param: impl ToString) -> Self {
918 Self(attributes::FmtpParam::new(param))
919 }
920
921 pub fn value(mut self, value: impl ToString) -> Self {
922 self.0.set_value(value);
923 self
924 }
925
926 pub fn value_if(mut self, value: impl ToString, predicate: bool) -> Self {
927 if predicate {
928 self.0.set_value(value);
929 }
930 self
931 }
932
933 pub fn value_if_some(mut self, value: Option<impl ToString>) -> Self {
934 if let Some(value) = value {
935 self.0.set_value(value);
936 }
937 self
938 }
939
940 pub fn build(self) -> attributes::FmtpParam {
941 self.0
942 }
943}
944
945#[derive(Debug)]
947pub struct Fmtp(attributes::Fmtp);
948impl Fmtp {
949 pub fn new(fmt: u8) -> Self {
950 Self(attributes::Fmtp::new(fmt))
951 }
952
953 pub fn format_specific_param(mut self, format_specific_param: attributes::FmtpParam) -> Self {
954 self.0.add_format_specific_param(format_specific_param);
955 self
956 }
957
958 pub fn format_specific_param_if(
959 mut self,
960 format_specific_param: attributes::FmtpParam,
961 predicate: bool,
962 ) -> Self {
963 if predicate {
964 self.0.add_format_specific_param(format_specific_param);
965 }
966 self
967 }
968
969 pub fn format_specific_param_if_some(
970 mut self,
971 format_specific_param: Option<attributes::FmtpParam>,
972 ) -> Self {
973 if let Some(format_specific_param) = format_specific_param {
974 self.0.add_format_specific_param(format_specific_param);
975 }
976 self
977 }
978
979 pub fn format_specific_params(
980 mut self,
981 format_specific_params: impl IntoIterator<Item = attributes::FmtpParam>,
982 ) -> Self {
983 self.0.add_format_specific_params(format_specific_params);
984 self
985 }
986
987 pub fn format_specific_params_if(
988 mut self,
989 format_specific_params: impl IntoIterator<Item = attributes::FmtpParam>,
990 predicate: bool,
991 ) -> Self {
992 if predicate {
993 self.0.add_format_specific_params(format_specific_params);
994 }
995 self
996 }
997
998 pub fn build(self) -> attributes::Fmtp {
999 self.0
1000 }
1001}
1002
1003#[derive(Debug)]
1005pub struct ExtMap(attributes::ExtMap);
1006impl ExtMap {
1007 pub fn new(id: u8, uri: impl ToString) -> Self {
1008 Self(attributes::ExtMap::new(id, uri))
1009 }
1010
1011 pub fn direction(mut self, direction: attributes::Direction) -> Self {
1012 self.0.set_direction(direction);
1013 self
1014 }
1015
1016 pub fn direction_if(mut self, direction: attributes::Direction, predicate: bool) -> Self {
1017 if predicate {
1018 self.0.set_direction(direction);
1019 }
1020 self
1021 }
1022
1023 pub fn direction_if_some(mut self, direction: Option<attributes::Direction>) -> Self {
1024 if let Some(direction) = direction {
1025 self.0.set_direction(direction);
1026 }
1027 self
1028 }
1029
1030 pub fn attributes(mut self, attributes: impl ToString) -> Self {
1031 self.0.set_attributes(attributes);
1032 self
1033 }
1034
1035 pub fn attributes_if(mut self, attributes: impl ToString, predicate: bool) -> Self {
1036 if predicate {
1037 self.0.set_attributes(attributes);
1038 }
1039 self
1040 }
1041
1042 pub fn attributes_if_some(mut self, attributes: Option<impl ToString>) -> Self {
1043 if let Some(attributes) = attributes {
1044 self.0.set_attributes(attributes);
1045 }
1046 self
1047 }
1048
1049 pub fn build(self) -> attributes::ExtMap {
1050 self.0
1051 }
1052}
1053
1054#[derive(Debug)]
1056pub struct Fingerprint(attributes::Fingerprint);
1057impl Fingerprint {
1058 pub fn new(hash_func: enums::HashFunc) -> Self {
1059 Self(attributes::Fingerprint::new(hash_func))
1060 }
1061
1062 pub fn fingerprint(mut self, fingerprint: impl IntoIterator<Item = u8>) -> Self {
1063 self.0.set_fingerprint(fingerprint);
1064 self
1065 }
1066
1067 pub fn fingerprint_if(
1068 mut self,
1069 fingerprint: impl IntoIterator<Item = u8>,
1070 predicate: bool,
1071 ) -> Self {
1072 if predicate {
1073 self.0.set_fingerprint(fingerprint);
1074 }
1075 self
1076 }
1077
1078 pub fn fingerprint_if_some(
1079 mut self,
1080 fingerprint: Option<impl IntoIterator<Item = u8>>,
1081 ) -> Self {
1082 if let Some(fingerprint) = fingerprint {
1083 self.0.set_fingerprint(fingerprint);
1084 }
1085 self
1086 }
1087
1088 pub fn build(self) -> attributes::Fingerprint {
1089 self.0
1090 }
1091}
1092
1093#[derive(Debug)]
1095pub struct Group(attributes::Group);
1096impl Group {
1097 pub fn new(semantics: enums::GroupSemantics) -> Self {
1098 Self(attributes::Group::new(semantics))
1099 }
1100
1101 pub fn mid_tag(mut self, mid_tag: impl ToString) -> Self {
1102 self.0.add_mid_tag(mid_tag);
1103 self
1104 }
1105
1106 pub fn mid_tag_if(mut self, mid_tag: impl ToString, predicate: bool) -> Self {
1107 if predicate {
1108 self.0.add_mid_tag(mid_tag);
1109 }
1110 self
1111 }
1112
1113 pub fn mid_tag_if_some(mut self, mid_tag: Option<impl ToString>) -> Self {
1114 if let Some(mid_tag) = mid_tag {
1115 self.0.add_mid_tag(mid_tag);
1116 }
1117 self
1118 }
1119
1120 pub fn mid_tags(mut self, mid_tags: impl IntoIterator<Item = impl ToString>) -> Self {
1121 self.0.add_mid_tags(mid_tags);
1122 self
1123 }
1124
1125 pub fn mid_tags_if(
1126 mut self,
1127 mid_tags: impl IntoIterator<Item = impl ToString>,
1128 predicate: bool,
1129 ) -> Self {
1130 if predicate {
1131 self.0.add_mid_tags(mid_tags);
1132 }
1133 self
1134 }
1135
1136 pub fn mid_tags_if_some(
1137 mut self,
1138 mid_tags: Option<impl IntoIterator<Item = impl ToString>>,
1139 ) -> Self {
1140 if let Some(mid_tags) = mid_tags {
1141 self.0.add_mid_tags(mid_tags);
1142 }
1143 self
1144 }
1145
1146 pub fn build(self) -> attributes::Group {
1147 self.0
1148 }
1149}
1150
1151#[derive(Debug)]
1153pub struct Ssrc(attributes::Ssrc);
1154impl Ssrc {
1155 pub fn new(ssrc_id: u32, attribute: enums::SsrcAttribute) -> Self {
1156 Self(attributes::Ssrc::new(ssrc_id, attribute))
1157 }
1158
1159 pub fn value(mut self, value: impl ToString) -> Self {
1160 self.0.set_value(value);
1161 self
1162 }
1163
1164 pub fn value_if(mut self, value: impl ToString, predicate: bool) -> Self {
1165 if predicate {
1166 self.0.set_value(value);
1167 }
1168 self
1169 }
1170
1171 pub fn value_if_some(mut self, value: Option<impl ToString>) -> Self {
1172 if let Some(value) = value {
1173 self.0.set_value(value);
1174 }
1175 self
1176 }
1177
1178 pub fn build(self) -> attributes::Ssrc {
1179 self.0
1180 }
1181}
1182
1183#[derive(Debug)]
1185pub struct SsrcGroup(attributes::SsrcGroup);
1186impl SsrcGroup {
1187 pub fn new(semantics: enums::GroupSemantics) -> Self {
1188 Self(attributes::SsrcGroup::new(semantics))
1189 }
1190
1191 pub fn ssrc_id(mut self, ssrc_id: u32) -> Self {
1192 self.0.add_ssrc_id(ssrc_id);
1193 self
1194 }
1195
1196 pub fn ssrc_id_if(mut self, ssrc_id: u32, predicate: bool) -> Self {
1197 if predicate {
1198 self.0.add_ssrc_id(ssrc_id);
1199 }
1200 self
1201 }
1202
1203 pub fn ssrc_id_if_some(mut self, ssrc_id: Option<u32>) -> Self {
1204 if let Some(ssrc_id) = ssrc_id {
1205 self.0.add_ssrc_id(ssrc_id);
1206 }
1207 self
1208 }
1209
1210 pub fn ssrc_ids(mut self, ssrc_ids: impl IntoIterator<Item = u32>) -> Self {
1211 self.0.add_ssrc_ids(ssrc_ids);
1212 self
1213 }
1214
1215 pub fn ssrc_ids_if(mut self, ssrc_ids: impl IntoIterator<Item = u32>, predicate: bool) -> Self {
1216 if predicate {
1217 self.0.add_ssrc_ids(ssrc_ids);
1218 }
1219 self
1220 }
1221
1222 pub fn ssrc_ids_if_some(mut self, ssrc_ids: Option<impl IntoIterator<Item = u32>>) -> Self {
1223 if let Some(ssrc_ids) = ssrc_ids {
1224 self.0.add_ssrc_ids(ssrc_ids);
1225 }
1226 self
1227 }
1228
1229 pub fn build(self) -> attributes::SsrcGroup {
1230 self.0
1231 }
1232}
1233
1234#[derive(Debug)]
1236pub struct SrtpKeyParam(attributes::SrtpKeyParam);
1237impl SrtpKeyParam {
1238 pub fn new(key_and_salt: impl ToString) -> Self {
1239 Self(attributes::SrtpKeyParam::new(key_and_salt))
1240 }
1241
1242 pub fn lifetime(mut self, lifetime: u32) -> Self {
1243 self.0.set_lifetime(lifetime);
1244 self
1245 }
1246
1247 pub fn lifetime_if(mut self, lifetime: u32, predicate: bool) -> Self {
1248 if predicate {
1249 self.0.set_lifetime(lifetime);
1250 }
1251 self
1252 }
1253
1254 pub fn lifetime_if_some(mut self, lifetime: Option<u32>) -> Self {
1255 if let Some(lifetime) = lifetime {
1256 self.0.set_lifetime(lifetime);
1257 }
1258 self
1259 }
1260
1261 pub fn mki_and_length(mut self, mki: u32, length: u32) -> Self {
1262 self.0.set_mki_and_length(mki, length);
1263 self
1264 }
1265
1266 pub fn mki_and_length_if(mut self, mki: u32, length: u32, predicate: bool) -> Self {
1267 if predicate {
1268 self.0.set_mki_and_length(mki, length);
1269 }
1270 self
1271 }
1272
1273 pub fn mki_and_length_if_some(mut self, mki_length: Option<(u32, u32)>) -> Self {
1274 if let Some((mki, length)) = mki_length {
1275 self.0.set_mki_and_length(mki, length);
1276 }
1277 self
1278 }
1279
1280 pub fn build(self) -> attributes::SrtpKeyParam {
1281 self.0
1282 }
1283}
1284
1285#[derive(Debug)]
1287pub struct Crypto(attributes::Crypto);
1288impl Crypto {
1289 pub fn new(tag: u32, crypto_suite: enums::CryptoSuite) -> Self {
1290 Self(attributes::Crypto::new(tag, crypto_suite))
1291 }
1292
1293 pub fn key_param(mut self, key_param: attributes::SrtpKeyParam) -> Self {
1294 self.0.add_key_param(key_param);
1295 self
1296 }
1297
1298 pub fn key_param_if(mut self, key_param: attributes::SrtpKeyParam, predicate: bool) -> Self {
1299 if predicate {
1300 self.0.add_key_param(key_param);
1301 }
1302 self
1303 }
1304
1305 pub fn key_param_if_some(mut self, key_param: Option<attributes::SrtpKeyParam>) -> Self {
1306 if let Some(key_param) = key_param {
1307 self.0.add_key_param(key_param);
1308 }
1309 self
1310 }
1311
1312 pub fn key_params(
1313 mut self,
1314 key_params: impl IntoIterator<Item = attributes::SrtpKeyParam>,
1315 ) -> Self {
1316 self.0.add_key_params(key_params);
1317 self
1318 }
1319
1320 pub fn key_params_if(
1321 mut self,
1322 key_params: impl IntoIterator<Item = attributes::SrtpKeyParam>,
1323 predicate: bool,
1324 ) -> Self {
1325 if predicate {
1326 self.0.add_key_params(key_params);
1327 }
1328 self
1329 }
1330
1331 pub fn key_params_if_some(
1332 mut self,
1333 key_params: Option<impl IntoIterator<Item = attributes::SrtpKeyParam>>,
1334 ) -> Self {
1335 if let Some(key_params) = key_params {
1336 self.0.add_key_params(key_params);
1337 }
1338 self
1339 }
1340
1341 pub fn session_param(mut self, session_param: enums::SrtpSessionParam) -> Self {
1342 self.0.add_session_param(session_param);
1343 self
1344 }
1345
1346 pub fn session_param_if(
1347 mut self,
1348 session_param: enums::SrtpSessionParam,
1349 predicate: bool,
1350 ) -> Self {
1351 if predicate {
1352 self.0.add_session_param(session_param);
1353 }
1354 self
1355 }
1356
1357 pub fn session_param_if_some(mut self, session_param: Option<enums::SrtpSessionParam>) -> Self {
1358 if let Some(session_param) = session_param {
1359 self.0.add_session_param(session_param);
1360 }
1361 self
1362 }
1363
1364 pub fn session_params(
1365 mut self,
1366 session_params: impl IntoIterator<Item = enums::SrtpSessionParam>,
1367 ) -> Self {
1368 self.0.add_session_params(session_params);
1369 self
1370 }
1371
1372 pub fn session_params_if(
1373 mut self,
1374 session_params: impl IntoIterator<Item = enums::SrtpSessionParam>,
1375 predicate: bool,
1376 ) -> Self {
1377 if predicate {
1378 self.0.add_session_params(session_params);
1379 }
1380 self
1381 }
1382
1383 pub fn session_params_if_some(
1384 mut self,
1385 session_params: Option<impl IntoIterator<Item = enums::SrtpSessionParam>>,
1386 ) -> Self {
1387 if let Some(session_params) = session_params {
1388 self.0.add_session_params(session_params);
1389 }
1390 self
1391 }
1392
1393 pub fn build(self) -> attributes::Crypto {
1394 self.0
1395 }
1396}
1397
1398#[derive(Debug)]
1400pub struct Candidate(attributes::Candidate);
1401impl Candidate {
1402 pub fn new(
1403 foundation: impl ToString,
1404 component_id: u32,
1405 transport: impl ToString,
1406 priority: u64,
1407 address: enums::CandidateAddress,
1408 port: u16,
1409 typ: enums::CandidateType,
1410 ) -> Self {
1411 Self(attributes::Candidate::new(
1412 foundation,
1413 component_id,
1414 transport,
1415 priority,
1416 address,
1417 port,
1418 typ,
1419 ))
1420 }
1421
1422 pub fn rel_addr(mut self, rel_addr: impl Into<IpAddr>) -> Self {
1423 self.0.set_rel_addr(rel_addr);
1424 self
1425 }
1426
1427 pub fn rel_addr_if(mut self, rel_addr: impl Into<IpAddr>, predicate: bool) -> Self {
1428 if predicate {
1429 self.0.set_rel_addr(rel_addr);
1430 }
1431 self
1432 }
1433
1434 pub fn rel_addr_if_some(mut self, rel_addr: Option<impl Into<IpAddr>>) -> Self {
1435 if let Some(rel_addr) = rel_addr {
1436 self.0.set_rel_addr(rel_addr);
1437 }
1438 self
1439 }
1440
1441 pub fn rel_port(mut self, rel_port: u16) -> Self {
1442 self.0.set_rel_port(rel_port);
1443 self
1444 }
1445
1446 pub fn rel_port_if(mut self, rel_port: u16, predicate: bool) -> Self {
1447 if predicate {
1448 self.0.set_rel_port(rel_port);
1449 }
1450 self
1451 }
1452
1453 pub fn rel_port_if_some(mut self, rel_port: Option<u16>) -> Self {
1454 if let Some(rel_port) = rel_port {
1455 self.0.set_rel_port(rel_port);
1456 }
1457 self
1458 }
1459
1460 pub fn extension(mut self, name: impl ToString, value: impl ToString) -> Self {
1461 self.0.add_extension(name, value);
1462 self
1463 }
1464
1465 pub fn extension_if(
1466 mut self,
1467 name: impl ToString,
1468 value: impl ToString,
1469 predicate: bool,
1470 ) -> Self {
1471 if predicate {
1472 self.0.add_extension(name, value);
1473 }
1474 self
1475 }
1476
1477 pub fn extension_if_some(mut self, name_value: Option<(impl ToString, impl ToString)>) -> Self {
1478 if let Some((name, value)) = name_value {
1479 self.0.add_extension(name, value);
1480 }
1481 self
1482 }
1483
1484 pub fn build(self) -> attributes::Candidate {
1485 self.0
1486 }
1487}
1488
1489#[derive(Debug)]
1491pub struct NtpServerAddr(clock_signalling::NtpServerAddr);
1492impl NtpServerAddr {
1493 pub fn new(hostname: impl ToString) -> Self {
1494 Self(clock_signalling::NtpServerAddr::from_hostname(hostname))
1495 }
1496
1497 pub fn port(mut self, port: u16) -> Self {
1498 let clock_signalling::NtpServerAddr::HostPort { port: port_opt, .. } = &mut self.0 else {
1499 unreachable!("Builder constructed from hostname");
1500 };
1501 *port_opt = Some(port);
1502
1503 self
1504 }
1505
1506 pub fn port_if(mut self, port: u16, predicate: bool) -> Self {
1507 if predicate {
1508 self = self.port(port);
1509 }
1510 self
1511 }
1512
1513 pub fn port_if_some(mut self, port: Option<u16>) -> Self {
1514 if let Some(port) = port {
1515 self = self.port(port);
1516 }
1517 self
1518 }
1519
1520 pub fn build(self) -> clock_signalling::NtpServerAddr {
1521 self.0
1522 }
1523}
1524
1525#[derive(Debug)]
1527pub struct ClockSourceExt(clock_signalling::ClockSourceExt);
1528impl ClockSourceExt {
1529 pub fn new(name: impl ToString) -> Self {
1530 Self(clock_signalling::ClockSourceExt::new(name))
1531 }
1532
1533 pub fn value(mut self, value: impl ToString) -> Self {
1534 self.0.set_value(value);
1535 self
1536 }
1537
1538 pub fn value_if(mut self, value: impl ToString, predicate: bool) -> Self {
1539 if predicate {
1540 self.0.set_value(value);
1541 }
1542 self
1543 }
1544
1545 pub fn value_if_some(mut self, value: Option<impl ToString>) -> Self {
1546 if let Some(value) = value {
1547 self.0.set_value(value);
1548 }
1549 self
1550 }
1551
1552 pub fn build(self) -> clock_signalling::ClockSourceExt {
1553 self.0
1554 }
1555}
1556
1557#[derive(Debug)]
1559pub struct MediaClockSource(clock_signalling::MediaClockSource);
1560impl MediaClockSource {
1561 pub fn new(clock: impl Into<clock_signalling::MediaClock>) -> Self {
1562 Self(clock_signalling::MediaClockSource::new(clock))
1563 }
1564
1565 pub fn id(mut self, id: clock_signalling::MediaClockId) -> Self {
1566 self.0.set_id(id);
1567 self
1568 }
1569
1570 pub fn id_if(mut self, id: clock_signalling::MediaClockId, predicate: bool) -> Self {
1571 if predicate {
1572 self.0.set_id(id);
1573 }
1574 self
1575 }
1576
1577 pub fn id_if_some(mut self, id: Option<clock_signalling::MediaClockId>) -> Self {
1578 if let Some(id) = id {
1579 self.0.set_id(id);
1580 }
1581 self
1582 }
1583
1584 pub fn build(self) -> clock_signalling::MediaClockSource {
1585 self.0
1586 }
1587}
1588
1589#[derive(Debug)]
1591pub struct Direct(clock_signalling::Direct);
1592impl Direct {
1593 pub fn new() -> Self {
1594 Self(clock_signalling::Direct::new())
1595 }
1596
1597 pub fn offset(mut self, offset: u32) -> Self {
1598 self.0.set_offset(offset);
1599 self
1600 }
1601
1602 pub fn offset_if(mut self, offset: u32, predicate: bool) -> Self {
1603 if predicate {
1604 self.0.set_offset(offset);
1605 }
1606 self
1607 }
1608
1609 pub fn offset_if_some(mut self, offset: Option<u32>) -> Self {
1610 if let Some(offset) = offset {
1611 self.0.set_offset(offset);
1612 }
1613 self
1614 }
1615
1616 pub fn rate(mut self, rate: impl Into<clock_signalling::Rate>) -> Self {
1617 self.0.set_rate(rate);
1618 self
1619 }
1620
1621 pub fn rate_if(mut self, rate: impl Into<clock_signalling::Rate>, predicate: bool) -> Self {
1622 if predicate {
1623 self.0.set_rate(rate);
1624 }
1625 self
1626 }
1627
1628 pub fn rate_if_some(mut self, rate: Option<impl Into<clock_signalling::Rate>>) -> Self {
1629 if let Some(rate) = rate {
1630 self.0.set_rate(rate);
1631 }
1632 self
1633 }
1634
1635 pub fn build(self) -> clock_signalling::Direct {
1636 self.0
1637 }
1638}
1639
1640impl Default for Direct {
1641 fn default() -> Self {
1642 Direct::new()
1643 }
1644}
1645
1646#[derive(Debug)]
1648pub struct MediaClockExt(clock_signalling::MediaClockExt);
1649impl MediaClockExt {
1650 pub fn new(name: impl ToString) -> Self {
1651 Self(clock_signalling::MediaClockExt::new(name))
1652 }
1653
1654 pub fn value(mut self, value: impl ToString) -> Self {
1655 self.0.set_value(value);
1656 self
1657 }
1658
1659 pub fn value_if(mut self, value: impl ToString, predicate: bool) -> Self {
1660 if predicate {
1661 self.0.set_value(value);
1662 }
1663 self
1664 }
1665
1666 pub fn value_if_some(mut self, value: Option<impl ToString>) -> Self {
1667 if let Some(value) = value {
1668 self.0.set_value(value);
1669 }
1670 self
1671 }
1672
1673 pub fn build(self) -> clock_signalling::MediaClockExt {
1674 self.0
1675 }
1676
1677 pub fn build_media_clock(self) -> clock_signalling::MediaClock {
1678 self.0.into()
1679 }
1680}
1681
1682#[cfg(test)]
1683mod test {
1684 #[test]
1685 fn builder() {
1686 use crate::{
1687 Direction, Media, MediaType, Origin, RtpMap, Session, Ssrc, SsrcAttribute,
1688 TransportProto,
1689 };
1690 use std::{net::Ipv4Addr, str::FromStr};
1691
1692 const SESSION_ID: &str = "1234";
1693 const SESSION_NAME: &str = "sdp-type-builder-test";
1694 const USER_NAME: &str = "test-user";
1695 const UNICAST_ADDRESS: &str = "192.168.0.2";
1696 const CONNECTION_ADDRESS: &str = "192.168.0.3";
1697 const CONNECTION_PORT: u16 = 5000;
1698 const SENDER_ADDRESS: &str = "192.168.0.4";
1699 const SENDER_RTCP_PORT: u16 = 5001;
1700 const PT: u8 = 96;
1701 const ENCODING_NAME: &str = "L24";
1702 const AUDIO_RATE: u32 = 48_000;
1703 const AUDIO_PARAMS: u8 = 2;
1704 const SSRC: u32 = 1234;
1705 const CNAME: &str = "user@test.org";
1706 const REFCLK_NTP_HOSTNAME: &str = "192.168.0.2";
1707 const REFCLK_NTP_PORT: u16 = 5000;
1708 const MEDIACLK_OFFSET: u32 = 123456;
1709
1710 let sdp = Session::builder(
1711 Origin::builder_with_ip_addr(
1712 SESSION_ID,
1713 0,
1714 Ipv4Addr::from_str(UNICAST_ADDRESS).unwrap(),
1715 )
1716 .username(USER_NAME)
1717 .build(),
1718 SESSION_NAME,
1719 )
1720 .connection(Ipv4Addr::from_str(CONNECTION_ADDRESS).unwrap())
1721 .attribute(Direction::SendOnly)
1722 .media(
1723 Media::builder(
1724 MediaType::Audio,
1725 CONNECTION_PORT,
1726 TransportProto::RtpAvp,
1727 PT,
1728 )
1729 .attribute(RtpMap::with_encoding_params(
1730 PT,
1731 ENCODING_NAME,
1732 AUDIO_RATE,
1733 AUDIO_PARAMS,
1734 ))
1735 .attribute(Ssrc::with_value(SSRC, SsrcAttribute::Cname, CNAME))
1736 .attribute(Ssrc::with_typed_attribute(
1737 SSRC,
1738 crate::ReferenceClock::from(
1739 crate::NtpServerAddr::builder(REFCLK_NTP_HOSTNAME)
1740 .port(REFCLK_NTP_PORT)
1741 .build(),
1742 ),
1743 ))
1744 .attribute(Ssrc::with_typed_attribute(
1745 SSRC,
1746 crate::MediaClockSource::builder(
1747 crate::Direct::builder().offset(MEDIACLK_OFFSET).build(),
1748 )
1749 .build(),
1750 ))
1751 .attribute(Ssrc::with_typed_attribute(
1752 SSRC,
1753 crate::Rtcp::with_ip_addr(
1754 SENDER_RTCP_PORT,
1755 Ipv4Addr::from_str(SENDER_ADDRESS).unwrap(),
1756 ),
1757 ))
1758 .attribute_from_str("rtcp-mux")
1759 .build(),
1760 )
1761 .build();
1762
1763 use crate::{AddrType, Attribute, Connection, NetType};
1764 assert_eq!(
1765 sdp,
1766 Session {
1767 origin: Origin {
1768 username: Some(USER_NAME.to_string()),
1769 sess_id: SESSION_ID.to_string(),
1770 sess_version: 0,
1771 nettype: NetType::In,
1772 addrtype: AddrType::Ip4,
1773 unicast_address: UNICAST_ADDRESS.to_string(),
1774 },
1775 session_name: SESSION_NAME.to_string(),
1776 connection: Some(Connection {
1777 nettype: NetType::In,
1778 addrtype: AddrType::Ip4,
1779 connection_address: CONNECTION_ADDRESS.to_string(),
1780 }),
1781 session_description: None,
1782 uri: None,
1783 emails: vec![],
1784 phones: vec![],
1785 bandwidths: vec![],
1786 times: vec![],
1787 time_zones: vec![],
1788 key: None,
1789 attributes: vec![Attribute {
1790 attribute: "sendonly".to_string(),
1791 value: None
1792 }],
1793 medias: vec![Media {
1794 media: MediaType::Audio.to_string(),
1795 port: CONNECTION_PORT,
1796 num_ports: None,
1797 proto: TransportProto::RtpAvp.to_string(),
1798 fmt: PT.to_string(),
1799 media_title: None,
1800 connections: vec![],
1801 bandwidths: vec![],
1802 key: None,
1803 attributes: vec![
1804 Attribute {
1805 attribute: "rtpmap".to_string(),
1806 value: Some(format!(
1807 "{PT} {ENCODING_NAME}/{AUDIO_RATE}/{AUDIO_PARAMS}"
1808 )),
1809 },
1810 Attribute {
1811 attribute: "ssrc".to_string(),
1812 value: Some(format!("{SSRC} cname:{CNAME}")),
1813 },
1814 Attribute {
1815 attribute: "ssrc".to_string(),
1816 value: Some(format!(
1817 "{SSRC} ts-refclk:ntp={REFCLK_NTP_HOSTNAME}:{REFCLK_NTP_PORT}"
1818 )),
1819 },
1820 Attribute {
1821 attribute: "ssrc".to_string(),
1822 value: Some(format!("{SSRC} mediaclk:direct={MEDIACLK_OFFSET}")),
1823 },
1824 Attribute {
1825 attribute: "ssrc".to_string(),
1826 value: Some(format!(
1827 "{SSRC} rtcp:{SENDER_RTCP_PORT} IN IP4 {SENDER_ADDRESS}"
1828 )),
1829 },
1830 Attribute {
1831 attribute: "rtcp-mux".to_string(),
1832 value: None,
1833 },
1834 ],
1835 }],
1836 }
1837 )
1838 }
1839}