1use std::{fmt, marker::PhantomData, ptr, str};
4
5use cfg_if::cfg_if;
6use glib::{
7 prelude::*,
8 translate::*,
9 value::{SendValue, ToSendValue},
10 GStr,
11};
12
13use crate::{caps_features::*, ffi, structure::*, CapsIntersectMode, IdStr};
14
15mini_object_wrapper!(Caps, CapsRef, ffi::GstCaps, || { ffi::gst_caps_get_type() });
16
17impl Caps {
18 #[doc(alias = "gst_caps_new_simple")]
19 pub fn builder(name: impl IntoGStr) -> Builder<NoFeature> {
20 assert_initialized_main_thread!();
21 Builder::new(name)
22 }
23
24 #[doc(alias = "gst_caps_new_static_str_simple")]
25 pub fn builder_from_static(name: impl AsRef<GStr> + 'static) -> Builder<NoFeature> {
26 assert_initialized_main_thread!();
27 Builder::from_static(name)
28 }
29
30 #[doc(alias = "gst_caps_new_id_str_simple")]
31 pub fn builder_from_id(name: impl AsRef<IdStr>) -> Builder<NoFeature> {
32 assert_initialized_main_thread!();
33 Builder::from_id(name)
34 }
35
36 #[doc(alias = "gst_caps_new_full")]
37 pub fn builder_full() -> BuilderFull<SomeFeatures> {
38 assert_initialized_main_thread!();
39 BuilderFull::new()
40 }
41
42 #[doc(alias = "gst_caps_new_full")]
43 pub fn builder_full_with_features(features: CapsFeatures) -> BuilderFull<SomeFeatures> {
44 assert_initialized_main_thread!();
45 BuilderFull::with_features(features)
46 }
47
48 #[doc(alias = "gst_caps_new_full")]
49 pub fn builder_full_with_any_features() -> BuilderFull<AnyFeatures> {
50 assert_initialized_main_thread!();
51 BuilderFull::with_any_features()
52 }
53
54 #[doc(alias = "gst_caps_new_empty")]
62 pub fn new_empty() -> Self {
63 assert_initialized_main_thread!();
64 unsafe { from_glib_full(ffi::gst_caps_new_empty()) }
65 }
66
67 #[doc(alias = "gst_caps_new_any")]
74 pub fn new_any() -> Self {
75 assert_initialized_main_thread!();
76 unsafe { from_glib_full(ffi::gst_caps_new_any()) }
77 }
78
79 #[doc(alias = "gst_caps_new_empty_simple")]
88 pub fn new_empty_simple(name: impl IntoGStr) -> Self {
89 skip_assert_initialized!();
90 let mut caps = Caps::new_empty();
91
92 let structure = Structure::new_empty(name);
93 caps.get_mut().unwrap().append_structure(structure);
94
95 caps
96 }
97
98 #[doc(alias = "gst_caps_new_static_str_empty_simple")]
99 pub fn new_empty_simple_from_static(name: impl AsRef<GStr> + 'static) -> Self {
100 skip_assert_initialized!();
101 let mut caps = Caps::new_empty();
102
103 let structure = Structure::new_empty_from_static(name);
104 caps.get_mut().unwrap().append_structure(structure);
105
106 caps
107 }
108
109 #[doc(alias = "gst_caps_new_id_str_empty_simple")]
110 pub fn new_empty_simple_from_id(name: impl AsRef<IdStr>) -> Self {
111 skip_assert_initialized!();
112 let mut caps = Caps::new_empty();
113
114 let structure = Structure::new_empty_from_id(name);
115 caps.get_mut().unwrap().append_structure(structure);
116
117 caps
118 }
119
120 #[doc(alias = "gst_caps_fixate")]
138 pub fn fixate(&mut self) {
139 unsafe {
140 assert!(!self.is_any());
142 let ptr = if self.is_empty() {
143 ffi::gst_caps_new_empty()
144 } else {
145 ffi::gst_caps_fixate(self.as_mut_ptr())
146 };
147 self.replace_ptr(ptr);
148 }
149 }
150
151 #[doc(alias = "gst_caps_merge")]
162 pub fn merge(&mut self, other: Self) {
163 unsafe {
164 let ptr = ffi::gst_caps_merge(self.as_mut_ptr(), other.into_glib_ptr());
165 self.replace_ptr(ptr);
166 }
167 }
168
169 #[doc(alias = "gst_caps_merge_structure")]
177 pub fn merge_structure(&mut self, structure: Structure) {
178 unsafe {
179 let ptr = ffi::gst_caps_merge_structure(self.as_mut_ptr(), structure.into_glib_ptr());
180 self.replace_ptr(ptr);
181 }
182 }
183
184 #[doc(alias = "gst_caps_merge_structure_full")]
194 pub fn merge_structure_full(&mut self, structure: Structure, features: Option<CapsFeatures>) {
195 unsafe {
196 let ptr = ffi::gst_caps_merge_structure_full(
197 self.as_mut_ptr(),
198 structure.into_glib_ptr(),
199 features
200 .map(|f| f.into_glib_ptr())
201 .unwrap_or(ptr::null_mut()),
202 );
203 self.replace_ptr(ptr);
204 }
205 }
206
207 #[doc(alias = "gst_caps_normalize")]
219 pub fn normalize(&mut self) {
220 unsafe {
221 let ptr = ffi::gst_caps_normalize(self.as_mut_ptr());
222 self.replace_ptr(ptr);
223 }
224 }
225
226 #[doc(alias = "gst_caps_simplify")]
241 pub fn simplify(&mut self) {
242 unsafe {
243 let ptr = ffi::gst_caps_simplify(self.as_mut_ptr());
244 self.replace_ptr(ptr);
245 }
246 }
247
248 #[doc(alias = "gst_caps_truncate")]
263 pub fn truncate(&mut self) {
264 unsafe {
265 let ptr = ffi::gst_caps_truncate(self.as_mut_ptr());
266 self.replace_ptr(ptr);
267 }
268 }
269}
270
271impl str::FromStr for Caps {
272 type Err = glib::BoolError;
273
274 #[doc(alias = "gst_caps_from_string")]
275 fn from_str(s: &str) -> Result<Self, Self::Err> {
276 assert_initialized_main_thread!();
277 unsafe {
278 s.run_with_gstr(|s| {
279 Option::<_>::from_glib_full(ffi::gst_caps_from_string(s.as_ptr()))
280 .ok_or_else(|| glib::bool_error!("Failed to parse caps from string"))
281 })
282 }
283 }
284}
285
286impl From<Structure> for Caps {
287 fn from(v: Structure) -> Caps {
288 skip_assert_initialized!();
289 let mut caps = Caps::new_empty();
290
291 {
292 let caps = caps.get_mut().unwrap();
293 caps.append_structure(v);
294 }
295
296 caps
297 }
298}
299
300impl<const N: usize> From<[Structure; N]> for Caps {
301 fn from(v: [Structure; N]) -> Caps {
302 skip_assert_initialized!();
303 let mut caps = Caps::new_empty();
304
305 {
306 let caps = caps.get_mut().unwrap();
307 v.into_iter().for_each(|s| caps.append_structure(s));
308 }
309
310 caps
311 }
312}
313
314impl From<(Structure, CapsFeatures)> for Caps {
315 fn from(v: (Structure, CapsFeatures)) -> Caps {
316 skip_assert_initialized!();
317 let mut caps = Caps::new_empty();
318
319 {
320 let caps = caps.get_mut().unwrap();
321 caps.append_structure_full(v.0, Some(v.1));
322 }
323
324 caps
325 }
326}
327
328impl<const N: usize> From<[(Structure, CapsFeatures); N]> for Caps {
329 fn from(v: [(Structure, CapsFeatures); N]) -> Caps {
330 skip_assert_initialized!();
331 let mut caps = Caps::new_empty();
332
333 {
334 let caps = caps.get_mut().unwrap();
335 v.into_iter()
336 .for_each(|s| caps.append_structure_full(s.0, Some(s.1)));
337 }
338
339 caps
340 }
341}
342
343impl<const N: usize> From<[(Structure, Option<CapsFeatures>); N]> for Caps {
344 fn from(v: [(Structure, Option<CapsFeatures>); N]) -> Caps {
345 skip_assert_initialized!();
346 let mut caps = Caps::new_empty();
347
348 {
349 let caps = caps.get_mut().unwrap();
350 v.into_iter()
351 .for_each(|s| caps.append_structure_full(s.0, s.1));
352 }
353
354 caps
355 }
356}
357
358impl std::iter::FromIterator<Structure> for Caps {
359 fn from_iter<T: IntoIterator<Item = Structure>>(iter: T) -> Self {
360 skip_assert_initialized!();
361 let mut caps = Caps::new_empty();
362
363 {
364 let caps = caps.get_mut().unwrap();
365 iter.into_iter().for_each(|s| caps.append_structure(s));
366 }
367
368 caps
369 }
370}
371
372impl std::iter::FromIterator<(Structure, CapsFeatures)> for Caps {
373 fn from_iter<T: IntoIterator<Item = (Structure, CapsFeatures)>>(iter: T) -> Self {
374 skip_assert_initialized!();
375 let mut caps = Caps::new_empty();
376
377 {
378 let caps = caps.get_mut().unwrap();
379 iter.into_iter()
380 .for_each(|(s, f)| caps.append_structure_full(s, Some(f)));
381 }
382
383 caps
384 }
385}
386
387impl std::iter::FromIterator<(Structure, Option<CapsFeatures>)> for Caps {
388 fn from_iter<T: IntoIterator<Item = (Structure, Option<CapsFeatures>)>>(iter: T) -> Self {
389 skip_assert_initialized!();
390 let mut caps = Caps::new_empty();
391
392 {
393 let caps = caps.get_mut().unwrap();
394 iter.into_iter()
395 .for_each(|(s, f)| caps.append_structure_full(s, f));
396 }
397
398 caps
399 }
400}
401
402impl std::iter::FromIterator<Caps> for Caps {
403 fn from_iter<T: IntoIterator<Item = Caps>>(iter: T) -> Self {
404 skip_assert_initialized!();
405 let mut caps = Caps::new_empty();
406
407 {
408 let caps = caps.get_mut().unwrap();
409 iter.into_iter()
410 .for_each(|other_caps| caps.append(other_caps));
411 }
412
413 caps
414 }
415}
416
417impl std::iter::Extend<Structure> for CapsRef {
418 fn extend<T: IntoIterator<Item = Structure>>(&mut self, iter: T) {
419 iter.into_iter().for_each(|s| self.append_structure(s));
420 }
421}
422
423impl std::iter::Extend<(Structure, CapsFeatures)> for CapsRef {
424 fn extend<T: IntoIterator<Item = (Structure, CapsFeatures)>>(&mut self, iter: T) {
425 iter.into_iter()
426 .for_each(|(s, f)| self.append_structure_full(s, Some(f)));
427 }
428}
429
430impl std::iter::Extend<(Structure, Option<CapsFeatures>)> for CapsRef {
431 fn extend<T: IntoIterator<Item = (Structure, Option<CapsFeatures>)>>(&mut self, iter: T) {
432 iter.into_iter()
433 .for_each(|(s, f)| self.append_structure_full(s, f));
434 }
435}
436
437impl std::iter::Extend<Caps> for CapsRef {
438 fn extend<T: IntoIterator<Item = Caps>>(&mut self, iter: T) {
439 iter.into_iter().for_each(|caps| self.append(caps));
440 }
441}
442
443impl CapsRef {
444 #[doc(alias = "gst_caps_set_value")]
449 #[doc(alias = "gst_caps_set_simple")]
450 pub fn set(&mut self, name: impl IntoGStr, value: impl ToSendValue + Sync) {
451 let value = value.to_send_value();
452 self.set_value(name, value);
453 }
454
455 #[doc(alias = "gst_caps_set_value_static_str")]
460 #[doc(alias = "gst_caps_set_simple_static_str")]
461 pub fn set_with_static(
462 &mut self,
463 name: impl AsRef<GStr> + 'static,
464 value: impl ToSendValue + Sync,
465 ) {
466 let value = value.to_send_value();
467 self.set_value_with_static(name, value);
468 }
469
470 #[doc(alias = "gst_caps_id_str_set_value")]
475 #[doc(alias = "gst_caps_id_str_set_simple")]
476 pub fn set_with_id(&mut self, name: impl AsRef<IdStr>, value: impl ToSendValue + Sync) {
477 let value = value.to_send_value();
478 self.set_value_with_id(name, value);
479 }
480
481 #[doc(alias = "gst_caps_set_value")]
487 #[doc(alias = "gst_caps_set_simple")]
488 pub fn set_if(&mut self, name: impl IntoGStr, value: impl ToSendValue + Sync, predicate: bool) {
489 if predicate {
490 self.set(name, value);
491 }
492 }
493
494 #[doc(alias = "gst_caps_set_value_static_str")]
500 #[doc(alias = "gst_caps_set_simple_static_str")]
501 pub fn set_with_static_if(
502 &mut self,
503 name: impl AsRef<GStr> + 'static,
504 value: impl ToSendValue + Sync,
505 predicate: bool,
506 ) {
507 if predicate {
508 self.set_with_static(name, value);
509 }
510 }
511
512 #[doc(alias = "gst_caps_id_str_set_value")]
518 #[doc(alias = "gst_caps_id_str_set_simple")]
519 pub fn set_with_id_if(
520 &mut self,
521 name: impl AsRef<IdStr>,
522 value: impl ToSendValue + Sync,
523 predicate: bool,
524 ) {
525 if predicate {
526 self.set_with_id(name, value);
527 }
528 }
529
530 #[doc(alias = "gst_caps_set_value")]
535 #[doc(alias = "gst_caps_set_simple")]
536 pub fn set_if_some(&mut self, name: impl IntoGStr, value: Option<impl ToSendValue + Sync>) {
537 if let Some(value) = value {
538 self.set(name, value);
539 }
540 }
541
542 #[doc(alias = "gst_caps_set_value_static_str")]
547 #[doc(alias = "gst_caps_set_simple_static_str")]
548 pub fn set_with_static_if_some(
549 &mut self,
550 name: impl AsRef<GStr> + 'static,
551 value: Option<impl ToSendValue + Sync>,
552 ) {
553 if let Some(value) = value {
554 self.set_with_static(name, value);
555 }
556 }
557
558 #[doc(alias = "gst_caps_id_str_set_value")]
563 #[doc(alias = "gst_caps_id_str_set_simple")]
564 pub fn set_with_id_if_some(
565 &mut self,
566 name: impl AsRef<IdStr>,
567 value: Option<impl ToSendValue + Sync>,
568 ) {
569 if let Some(value) = value {
570 self.set_with_id(name, value);
571 }
572 }
573
574 #[inline]
579 pub fn set_from_iter<
580 V: ValueType + ToSendValue + FromIterator<SendValue> + Sync,
581 I: ToSendValue,
582 >(
583 &mut self,
584 name: impl IntoGStr,
585 iter: impl IntoIterator<Item = I>,
586 ) {
587 let iter = iter.into_iter().map(|item| item.to_send_value());
588 self.set(name, V::from_iter(iter));
589 }
590
591 #[inline]
596 pub fn set_with_static_from_iter<
597 V: ValueType + ToSendValue + FromIterator<SendValue> + Sync,
598 I: ToSendValue,
599 >(
600 &mut self,
601 name: impl AsRef<GStr> + 'static,
602 iter: impl IntoIterator<Item = I>,
603 ) {
604 let iter = iter.into_iter().map(|item| item.to_send_value());
605 self.set_with_static(name, V::from_iter(iter));
606 }
607
608 #[inline]
613 pub fn set_with_id_from_iter<
614 V: ValueType + ToSendValue + FromIterator<SendValue> + Sync,
615 I: ToSendValue,
616 >(
617 &mut self,
618 name: impl AsRef<IdStr>,
619 iter: impl IntoIterator<Item = I>,
620 ) {
621 let iter = iter.into_iter().map(|item| item.to_send_value());
622 self.set_with_id(name, V::from_iter(iter));
623 }
624
625 #[inline]
631 pub fn set_if_not_empty<
632 V: ValueType + ToSendValue + FromIterator<SendValue> + Sync,
633 I: ToSendValue,
634 >(
635 &mut self,
636 name: impl IntoGStr,
637 iter: impl IntoIterator<Item = I>,
638 ) {
639 let mut iter = iter.into_iter().peekable();
640 if iter.peek().is_some() {
641 let iter = iter.map(|item| item.to_send_value());
642 self.set(name, V::from_iter(iter));
643 }
644 }
645
646 #[inline]
652 pub fn set_with_static_if_not_empty<
653 V: ValueType + ToSendValue + FromIterator<SendValue> + Sync,
654 I: ToSendValue,
655 >(
656 &mut self,
657 name: impl AsRef<GStr> + 'static,
658 iter: impl IntoIterator<Item = I>,
659 ) {
660 let mut iter = iter.into_iter().peekable();
661 if iter.peek().is_some() {
662 let iter = iter.map(|item| item.to_send_value());
663 self.set_with_static(name, V::from_iter(iter));
664 }
665 }
666
667 #[inline]
673 pub fn set_with_id_if_not_empty<
674 V: ValueType + ToSendValue + FromIterator<SendValue> + Sync,
675 I: ToSendValue,
676 >(
677 &mut self,
678 name: impl AsRef<IdStr>,
679 iter: impl IntoIterator<Item = I>,
680 ) {
681 let mut iter = iter.into_iter().peekable();
682 if iter.peek().is_some() {
683 let iter = iter.map(|item| item.to_send_value());
684 self.set_with_id(name, V::from_iter(iter));
685 }
686 }
687
688 #[doc(alias = "gst_caps_set_value")]
693 pub fn set_value(&mut self, name: impl IntoGStr, value: glib::SendValue) {
694 unsafe {
695 name.run_with_gstr(|name| {
696 ffi::gst_caps_set_value(self.as_mut_ptr(), name.as_ptr(), value.to_glib_none().0)
697 });
698 }
699 }
700
701 #[doc(alias = "gst_caps_set_value_static_str")]
706 pub fn set_value_with_static(
707 &mut self,
708 name: impl AsRef<GStr> + 'static,
709 value: glib::SendValue,
710 ) {
711 unsafe {
712 cfg_if! {
713 if #[cfg(feature = "v1_26")] {
714 ffi::gst_caps_set_value_static_str(
715 self.as_mut_ptr(),
716 name.as_ref().as_ptr(),
717 value.to_glib_none().0,
718 )
719 } else {
720 ffi::gst_caps_set_value(self.as_mut_ptr(), name.as_ref().as_ptr(), value.to_glib_none().0)
721 }
722 }
723 }
724 }
725
726 #[doc(alias = "gst_caps_id_str_set_value")]
731 pub fn set_value_with_id(&mut self, name: impl AsRef<IdStr>, value: glib::SendValue) {
732 unsafe {
733 cfg_if! {
734 if #[cfg(feature = "v1_26")] {
735 ffi::gst_caps_id_str_set_value(
736 self.as_mut_ptr(),
737 name.as_ref().as_ptr(),
738 value.to_glib_none().0,
739 )
740 } else {
741 ffi::gst_caps_set_value(self.as_mut_ptr(), name.as_ref().as_gstr().as_ptr(), value.to_glib_none().0)
742 }
743 }
744 }
745 }
746
747 #[doc(alias = "gst_caps_set_value")]
753 pub fn set_value_if(&mut self, name: impl IntoGStr, value: SendValue, predicate: bool) {
754 if predicate {
755 self.set_value(name, value);
756 }
757 }
758
759 #[doc(alias = "gst_caps_set_value_static_str")]
765 pub fn set_value_with_static_if(
766 &mut self,
767 name: impl AsRef<GStr> + 'static,
768 value: SendValue,
769 predicate: bool,
770 ) {
771 if predicate {
772 self.set_value_with_static(name, value);
773 }
774 }
775
776 #[doc(alias = "gst_caps_id_str_set_value")]
782 pub fn set_value_with_id_if(
783 &mut self,
784 name: impl AsRef<IdStr>,
785 value: SendValue,
786 predicate: bool,
787 ) {
788 if predicate {
789 self.set_value_with_id(name, value);
790 }
791 }
792
793 #[doc(alias = "gst_caps_set_value")]
798 pub fn set_value_if_some(&mut self, name: impl IntoGStr, value: Option<SendValue>) {
799 if let Some(value) = value {
800 self.set_value(name, value);
801 }
802 }
803
804 #[doc(alias = "gst_caps_set_value_static_str")]
809 pub fn set_value_with_static_if_some(
810 &mut self,
811 name: impl AsRef<GStr> + 'static,
812 value: Option<SendValue>,
813 ) {
814 if let Some(value) = value {
815 self.set_value_with_static(name, value);
816 }
817 }
818
819 #[doc(alias = "gst_caps_id_str_set_value")]
824 pub fn set_value_with_id_if_some(&mut self, name: impl AsRef<IdStr>, value: Option<SendValue>) {
825 if let Some(value) = value {
826 self.set_value_with_id(name, value);
827 }
828 }
829
830 #[doc(alias = "get_structure")]
831 #[doc(alias = "gst_caps_get_structure")]
832 pub fn structure(&self, idx: usize) -> Option<&StructureRef> {
833 if idx >= self.size() {
834 return None;
835 }
836
837 unsafe {
838 let structure = ffi::gst_caps_get_structure(self.as_ptr(), idx as u32);
839 if structure.is_null() {
840 return None;
841 }
842
843 Some(StructureRef::from_glib_borrow(structure))
844 }
845 }
846
847 #[doc(alias = "get_mut_structure")]
848 #[doc(alias = "gst_caps_get_structure")]
849 pub fn structure_mut(&mut self, idx: usize) -> Option<&mut StructureRef> {
850 if idx >= self.size() {
851 return None;
852 }
853
854 unsafe {
855 let structure = ffi::gst_caps_get_structure(self.as_ptr(), idx as u32);
856 if structure.is_null() {
857 return None;
858 }
859
860 Some(StructureRef::from_glib_borrow_mut(structure))
861 }
862 }
863
864 #[doc(alias = "get_features")]
865 #[doc(alias = "gst_caps_get_features")]
866 pub fn features(&self, idx: usize) -> Option<&CapsFeaturesRef> {
867 if idx >= self.size() {
868 return None;
869 }
870
871 unsafe {
872 let features = ffi::gst_caps_get_features(self.as_ptr(), idx as u32);
873 Some(CapsFeaturesRef::from_glib_borrow(features))
874 }
875 }
876
877 #[doc(alias = "get_mut_features")]
878 #[doc(alias = "gst_caps_get_features")]
879 pub fn features_mut(&mut self, idx: usize) -> Option<&mut CapsFeaturesRef> {
880 if idx >= self.size() {
881 return None;
882 }
883
884 unsafe {
885 let features = ffi::gst_caps_get_features(self.as_ptr(), idx as u32);
886 Some(CapsFeaturesRef::from_glib_borrow_mut(features))
887 }
888 }
889
890 #[doc(alias = "gst_caps_set_features")]
891 pub fn set_features(&mut self, idx: usize, features: Option<CapsFeatures>) {
892 assert!(idx < self.size());
893
894 unsafe {
895 ffi::gst_caps_set_features(
896 self.as_mut_ptr(),
897 idx as u32,
898 features
899 .map(|f| f.into_glib_ptr())
900 .unwrap_or(ptr::null_mut()),
901 )
902 }
903 }
904
905 #[cfg(feature = "v1_16")]
906 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
907 #[doc(alias = "gst_caps_set_features_simple")]
908 pub fn set_features_simple(&mut self, features: Option<CapsFeatures>) {
909 unsafe {
910 ffi::gst_caps_set_features_simple(
911 self.as_mut_ptr(),
912 features
913 .map(|f| f.into_glib_ptr())
914 .unwrap_or(ptr::null_mut()),
915 )
916 }
917 }
918
919 #[doc(alias = "get_size")]
920 #[doc(alias = "gst_caps_get_size")]
921 pub fn size(&self) -> usize {
922 unsafe { ffi::gst_caps_get_size(self.as_ptr()) as usize }
923 }
924
925 pub fn len(&self) -> usize {
926 self.size()
927 }
928
929 pub fn iter(&self) -> Iter {
930 Iter::new(self)
931 }
932
933 pub fn iter_mut(&mut self) -> IterMut {
934 IterMut::new(self)
935 }
936
937 pub fn iter_with_features(&self) -> IterFeatures {
938 IterFeatures::new(self)
939 }
940
941 pub fn iter_with_features_mut(&mut self) -> IterFeaturesMut {
942 IterFeaturesMut::new(self)
943 }
944
945 #[doc(alias = "gst_caps_append_structure")]
946 pub fn append_structure(&mut self, structure: Structure) {
947 unsafe { ffi::gst_caps_append_structure(self.as_mut_ptr(), structure.into_glib_ptr()) }
948 }
949
950 #[doc(alias = "gst_caps_append_structure_full")]
951 pub fn append_structure_full(&mut self, structure: Structure, features: Option<CapsFeatures>) {
952 unsafe {
953 ffi::gst_caps_append_structure_full(
954 self.as_mut_ptr(),
955 structure.into_glib_ptr(),
956 features
957 .map(|f| f.into_glib_ptr())
958 .unwrap_or(ptr::null_mut()),
959 )
960 }
961 }
962
963 #[doc(alias = "gst_caps_remove_structure")]
964 pub fn remove_structure(&mut self, idx: usize) {
965 assert!(idx < self.size());
966
967 unsafe { ffi::gst_caps_remove_structure(self.as_mut_ptr(), idx as u32) }
968 }
969
970 #[doc(alias = "gst_caps_append")]
971 pub fn append(&mut self, other: Caps) {
972 unsafe { ffi::gst_caps_append(self.as_mut_ptr(), other.into_glib_ptr()) }
973 }
974
975 #[doc(alias = "gst_caps_can_intersect")]
976 pub fn can_intersect(&self, other: &Self) -> bool {
977 unsafe { from_glib(ffi::gst_caps_can_intersect(self.as_ptr(), other.as_ptr())) }
978 }
979
980 #[doc(alias = "gst_caps_intersect")]
981 pub fn intersect(&self, other: &Self) -> Caps {
982 unsafe {
983 from_glib_full(ffi::gst_caps_intersect(
984 self.as_mut_ptr(),
985 other.as_mut_ptr(),
986 ))
987 }
988 }
989
990 #[doc(alias = "gst_caps_intersect_full")]
991 pub fn intersect_with_mode(&self, other: &Self, mode: CapsIntersectMode) -> Caps {
992 unsafe {
993 from_glib_full(ffi::gst_caps_intersect_full(
994 self.as_mut_ptr(),
995 other.as_mut_ptr(),
996 mode.into_glib(),
997 ))
998 }
999 }
1000
1001 #[doc(alias = "gst_caps_is_always_compatible")]
1002 pub fn is_always_compatible(&self, other: &Self) -> bool {
1003 unsafe {
1004 from_glib(ffi::gst_caps_is_always_compatible(
1005 self.as_ptr(),
1006 other.as_ptr(),
1007 ))
1008 }
1009 }
1010
1011 #[doc(alias = "gst_caps_is_any")]
1012 pub fn is_any(&self) -> bool {
1013 unsafe { from_glib(ffi::gst_caps_is_any(self.as_ptr())) }
1014 }
1015
1016 #[doc(alias = "gst_caps_is_empty")]
1017 pub fn is_empty(&self) -> bool {
1018 unsafe { from_glib(ffi::gst_caps_is_empty(self.as_ptr())) }
1019 }
1020
1021 #[doc(alias = "gst_caps_is_fixed")]
1022 pub fn is_fixed(&self) -> bool {
1023 unsafe { from_glib(ffi::gst_caps_is_fixed(self.as_ptr())) }
1024 }
1025
1026 #[doc(alias = "gst_caps_is_equal_fixed")]
1027 pub fn is_equal_fixed(&self, other: &Self) -> bool {
1028 unsafe { from_glib(ffi::gst_caps_is_equal_fixed(self.as_ptr(), other.as_ptr())) }
1029 }
1030
1031 #[doc(alias = "gst_caps_is_strictly_equal")]
1032 pub fn is_strictly_equal(&self, other: &Self) -> bool {
1033 unsafe {
1034 from_glib(ffi::gst_caps_is_strictly_equal(
1035 self.as_ptr(),
1036 other.as_ptr(),
1037 ))
1038 }
1039 }
1040
1041 #[doc(alias = "gst_caps_is_subset")]
1042 pub fn is_subset(&self, superset: &Self) -> bool {
1043 unsafe { from_glib(ffi::gst_caps_is_subset(self.as_ptr(), superset.as_ptr())) }
1044 }
1045
1046 #[doc(alias = "gst_caps_is_subset_structure")]
1047 pub fn is_subset_structure(&self, structure: &StructureRef) -> bool {
1048 unsafe {
1049 from_glib(ffi::gst_caps_is_subset_structure(
1050 self.as_ptr(),
1051 structure.as_ptr(),
1052 ))
1053 }
1054 }
1055
1056 #[doc(alias = "gst_caps_is_subset_structure_full")]
1057 pub fn is_subset_structure_full(
1058 &self,
1059 structure: &StructureRef,
1060 features: Option<&CapsFeaturesRef>,
1061 ) -> bool {
1062 unsafe {
1063 from_glib(ffi::gst_caps_is_subset_structure_full(
1064 self.as_ptr(),
1065 structure.as_ptr(),
1066 features.map(|f| f.as_ptr()).unwrap_or(ptr::null()),
1067 ))
1068 }
1069 }
1070
1071 #[doc(alias = "gst_caps_subtract")]
1072 pub fn subtract(&self, other: &Self) -> Caps {
1073 unsafe {
1074 from_glib_full(ffi::gst_caps_subtract(
1075 self.as_mut_ptr(),
1076 other.as_mut_ptr(),
1077 ))
1078 }
1079 }
1080
1081 #[cfg(feature = "v1_20")]
1082 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
1083 #[doc(alias = "gst_caps_serialize")]
1084 pub fn serialize(&self, flags: crate::SerializeFlags) -> glib::GString {
1085 unsafe { from_glib_full(ffi::gst_caps_serialize(&self.0, flags.into_glib())) }
1086 }
1087
1088 #[doc(alias = "gst_caps_foreach")]
1089 pub fn foreach<F: FnMut(&CapsFeaturesRef, &StructureRef) -> std::ops::ControlFlow<()>>(
1090 &self,
1091 mut func: F,
1092 ) -> bool {
1093 unsafe {
1094 unsafe extern "C" fn trampoline<
1095 F: FnMut(&CapsFeaturesRef, &StructureRef) -> std::ops::ControlFlow<()>,
1096 >(
1097 features: *mut ffi::GstCapsFeatures,
1098 s: *mut ffi::GstStructure,
1099 user_data: glib::ffi::gpointer,
1100 ) -> glib::ffi::gboolean {
1101 let func = &mut *(user_data as *mut F);
1102 let res = func(
1103 CapsFeaturesRef::from_glib_borrow(features),
1104 StructureRef::from_glib_borrow(s),
1105 );
1106
1107 matches!(res, std::ops::ControlFlow::Continue(_)).into_glib()
1108 }
1109 let func = &mut func as *mut F;
1110 from_glib(ffi::gst_caps_foreach(
1111 self.as_ptr(),
1112 Some(trampoline::<F>),
1113 func as glib::ffi::gpointer,
1114 ))
1115 }
1116 }
1117
1118 #[doc(alias = "gst_caps_map_in_place")]
1119 pub fn map_in_place<
1120 F: FnMut(&mut CapsFeaturesRef, &mut StructureRef) -> std::ops::ControlFlow<()>,
1121 >(
1122 &mut self,
1123 mut func: F,
1124 ) {
1125 unsafe {
1126 unsafe extern "C" fn trampoline<
1127 F: FnMut(&mut CapsFeaturesRef, &mut StructureRef) -> std::ops::ControlFlow<()>,
1128 >(
1129 features: *mut ffi::GstCapsFeatures,
1130 s: *mut ffi::GstStructure,
1131 user_data: glib::ffi::gpointer,
1132 ) -> glib::ffi::gboolean {
1133 let func = &mut *(user_data as *mut F);
1134 let res = func(
1135 CapsFeaturesRef::from_glib_borrow_mut(features),
1136 StructureRef::from_glib_borrow_mut(s),
1137 );
1138
1139 matches!(res, std::ops::ControlFlow::Continue(_)).into_glib()
1140 }
1141 let func = &mut func as *mut F;
1142 let _ = ffi::gst_caps_map_in_place(
1143 self.as_mut_ptr(),
1144 Some(trampoline::<F>),
1145 func as glib::ffi::gpointer,
1146 );
1147 }
1148 }
1149
1150 #[doc(alias = "gst_caps_filter_and_map_in_place")]
1151 pub fn filter_map_in_place<
1152 F: FnMut(&mut CapsFeaturesRef, &mut StructureRef) -> CapsFilterMapAction,
1153 >(
1154 &mut self,
1155 mut func: F,
1156 ) {
1157 unsafe {
1158 unsafe extern "C" fn trampoline<
1159 F: FnMut(&mut CapsFeaturesRef, &mut StructureRef) -> CapsFilterMapAction,
1160 >(
1161 features: *mut ffi::GstCapsFeatures,
1162 s: *mut ffi::GstStructure,
1163 user_data: glib::ffi::gpointer,
1164 ) -> glib::ffi::gboolean {
1165 let func = &mut *(user_data as *mut F);
1166
1167 let res = func(
1168 CapsFeaturesRef::from_glib_borrow_mut(features),
1169 StructureRef::from_glib_borrow_mut(s),
1170 );
1171
1172 match res {
1173 CapsFilterMapAction::Keep => glib::ffi::GTRUE,
1174 CapsFilterMapAction::Remove => glib::ffi::GFALSE,
1175 }
1176 }
1177
1178 let func = &mut func as *mut F;
1179 ffi::gst_caps_filter_and_map_in_place(
1180 self.as_mut_ptr(),
1181 Some(trampoline::<F>),
1182 func as glib::ffi::gpointer,
1183 );
1184 }
1185 }
1186}
1187
1188#[derive(Debug)]
1189pub enum CapsFilterMapAction {
1190 Keep,
1191 Remove,
1192}
1193
1194macro_rules! define_iter(
1195 ($name:ident, $typ:ty, $styp:ty, $get_item:expr) => {
1196 crate::utils::define_fixed_size_iter!(
1197 $name, $typ, $styp,
1198 |collection: &CapsRef| collection.size(),
1199 $get_item
1200 );
1201 }
1202);
1203
1204define_iter!(
1205 Iter,
1206 &'a CapsRef,
1207 &'a StructureRef,
1208 |caps: &CapsRef, idx| unsafe {
1209 let ptr = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
1210 StructureRef::from_glib_borrow(ptr as *const ffi::GstStructure)
1211 }
1212);
1213define_iter!(
1214 IterMut,
1215 &'a mut CapsRef,
1216 &'a mut StructureRef,
1217 |caps: &mut CapsRef, idx| unsafe {
1218 let ptr = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
1219 StructureRef::from_glib_borrow_mut(ptr)
1220 }
1221);
1222define_iter!(
1223 IterFeatures,
1224 &'a CapsRef,
1225 (&'a StructureRef, &'a CapsFeaturesRef),
1226 |caps: &CapsRef, idx| unsafe {
1227 let ptr1 = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
1228 let ptr2 = ffi::gst_caps_get_features(caps.as_ptr(), idx as u32);
1229 (
1230 StructureRef::from_glib_borrow(ptr1),
1231 CapsFeaturesRef::from_glib_borrow(ptr2),
1232 )
1233 }
1234);
1235define_iter!(
1236 IterFeaturesMut,
1237 &'a mut CapsRef,
1238 (&'a mut StructureRef, &'a mut CapsFeaturesRef),
1239 |caps: &mut CapsRef, idx| unsafe {
1240 let ptr1 = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
1241 let ptr2 = ffi::gst_caps_get_features(caps.as_ptr(), idx as u32);
1242 (
1243 StructureRef::from_glib_borrow_mut(ptr1),
1244 CapsFeaturesRef::from_glib_borrow_mut(ptr2),
1245 )
1246 }
1247);
1248
1249impl<'a> IntoIterator for &'a CapsRef {
1250 type IntoIter = IterFeatures<'a>;
1251 type Item = (&'a StructureRef, &'a CapsFeaturesRef);
1252
1253 fn into_iter(self) -> Self::IntoIter {
1254 self.iter_with_features()
1255 }
1256}
1257
1258impl<'a> IntoIterator for &'a mut CapsRef {
1259 type IntoIter = IterFeaturesMut<'a>;
1260 type Item = (&'a mut StructureRef, &'a mut CapsFeaturesRef);
1261
1262 fn into_iter(self) -> Self::IntoIter {
1263 self.iter_with_features_mut()
1264 }
1265}
1266
1267impl fmt::Debug for Caps {
1268 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1269 <CapsRef as fmt::Debug>::fmt(self, f)
1270 }
1271}
1272
1273impl fmt::Display for Caps {
1274 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1275 <CapsRef as fmt::Display>::fmt(self, f)
1276 }
1277}
1278
1279impl PartialEq for Caps {
1280 fn eq(&self, other: &Caps) -> bool {
1281 CapsRef::eq(self, other)
1282 }
1283}
1284
1285impl Eq for Caps {}
1286
1287impl PartialEq<CapsRef> for Caps {
1288 fn eq(&self, other: &CapsRef) -> bool {
1289 CapsRef::eq(self, other)
1290 }
1291}
1292
1293impl PartialEq<Caps> for CapsRef {
1294 fn eq(&self, other: &Caps) -> bool {
1295 CapsRef::eq(other, self)
1296 }
1297}
1298
1299impl fmt::Debug for CapsRef {
1300 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1301 if self.is_any() {
1302 f.debug_tuple("Caps(\"ANY\")").finish()
1303 } else if self.is_empty() {
1304 f.debug_tuple("Caps(\"EMPTY\")").finish()
1305 } else {
1306 let mut debug = f.debug_tuple("Caps");
1307
1308 for (structure, features) in self.iter_with_features() {
1309 struct WithFeatures<'a> {
1310 features: &'a CapsFeaturesRef,
1311 structure: &'a StructureRef,
1312 }
1313
1314 impl fmt::Debug for WithFeatures<'_> {
1315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1316 let name = format!("{}({})", self.structure.name(), self.features);
1317 let mut debug = f.debug_struct(&name);
1318
1319 for (id, field) in self.structure.iter() {
1320 if field.type_() == Structure::static_type() {
1321 let s = field.get::<Structure>().unwrap();
1322 debug.field(id, &s);
1323 } else if field.type_() == crate::Array::static_type() {
1324 let arr = field.get::<crate::Array>().unwrap();
1325 debug.field(id, &arr);
1326 } else if field.type_() == crate::List::static_type() {
1327 let list = field.get::<crate::List>().unwrap();
1328 debug.field(id, &list);
1329 } else {
1330 debug.field(id, &field);
1331 }
1332 }
1333
1334 debug.finish()
1335 }
1336 }
1337
1338 debug.field(&WithFeatures {
1339 structure,
1340 features,
1341 });
1342 }
1343
1344 debug.finish()
1345 }
1346 }
1347}
1348
1349impl fmt::Display for CapsRef {
1350 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1351 let s = unsafe { glib::GString::from_glib_full(ffi::gst_caps_to_string(self.as_ptr())) };
1352 f.write_str(&s)
1353 }
1354}
1355
1356impl PartialEq for CapsRef {
1357 #[doc(alias = "gst_caps_is_equal")]
1358 fn eq(&self, other: &CapsRef) -> bool {
1359 unsafe { from_glib(ffi::gst_caps_is_equal(self.as_ptr(), other.as_ptr())) }
1360 }
1361}
1362
1363impl Eq for CapsRef {}
1364
1365pub enum NoFeature {}
1366pub enum HasFeatures {}
1367
1368#[must_use = "The builder must be built to be used"]
1369pub struct Builder<T> {
1370 s: crate::Structure,
1371 features: Option<CapsFeatures>,
1372 phantom: PhantomData<T>,
1373}
1374
1375impl<T> fmt::Debug for Builder<T> {
1376 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1377 f.debug_struct("Builder")
1378 .field("s", &self.s)
1379 .field("features", &self.features)
1380 .field("phantom", &self.phantom)
1381 .finish()
1382 }
1383}
1384
1385impl Builder<NoFeature> {
1386 fn new(name: impl IntoGStr) -> Builder<NoFeature> {
1387 skip_assert_initialized!();
1388 Builder {
1389 s: crate::Structure::new_empty(name),
1390 features: None,
1391 phantom: PhantomData,
1392 }
1393 }
1394
1395 fn from_static(name: impl AsRef<GStr> + 'static) -> Builder<NoFeature> {
1396 skip_assert_initialized!();
1397 Builder {
1398 s: crate::Structure::new_empty_from_static(name),
1399 features: None,
1400 phantom: PhantomData,
1401 }
1402 }
1403
1404 fn from_id(name: impl AsRef<IdStr>) -> Builder<NoFeature> {
1405 skip_assert_initialized!();
1406 Builder {
1407 s: crate::Structure::new_empty_from_id(name),
1408 features: None,
1409 phantom: PhantomData,
1410 }
1411 }
1412
1413 pub fn features<S: IntoGStr>(
1414 self,
1415 features: impl IntoIterator<Item = S>,
1416 ) -> Builder<HasFeatures> {
1417 Builder {
1418 s: self.s,
1419 features: Some(CapsFeatures::new(features)),
1420 phantom: PhantomData,
1421 }
1422 }
1423
1424 pub fn features_from_statics<S: AsRef<GStr> + 'static>(
1425 self,
1426 features: impl IntoIterator<Item = S>,
1427 ) -> Builder<HasFeatures> {
1428 Builder {
1429 s: self.s,
1430 features: Some(CapsFeatures::new_from_static(features)),
1431 phantom: PhantomData,
1432 }
1433 }
1434
1435 pub fn features_from_ids<S: AsRef<IdStr>>(
1436 self,
1437 features: impl IntoIterator<Item = S>,
1438 ) -> Builder<HasFeatures> {
1439 Builder {
1440 s: self.s,
1441 features: Some(CapsFeatures::new_from_id(features)),
1442 phantom: PhantomData,
1443 }
1444 }
1445
1446 pub fn any_features(self) -> Builder<HasFeatures> {
1447 Builder {
1448 s: self.s,
1449 features: Some(CapsFeatures::new_any()),
1450 phantom: PhantomData,
1451 }
1452 }
1453}
1454
1455impl<T> Builder<T> {
1456 #[inline]
1461 pub fn field(mut self, name: impl IntoGStr, value: impl Into<glib::Value> + Send) -> Self {
1462 self.s.set(name, value);
1463 self
1464 }
1465
1466 #[inline]
1471 pub fn field_with_static(
1472 mut self,
1473 name: impl AsRef<glib::GStr> + 'static,
1474 value: impl Into<glib::Value> + Send,
1475 ) -> Self {
1476 self.s.set_with_static(name, value);
1477 self
1478 }
1479
1480 #[inline]
1485 pub fn field_with_id(
1486 mut self,
1487 name: impl AsRef<IdStr>,
1488 value: impl Into<glib::Value> + Send,
1489 ) -> Self {
1490 self.s.set_with_id(name, value);
1491 self
1492 }
1493
1494 impl_builder_gvalue_extra_setters!(field);
1495
1496 #[must_use = "Building the caps without using them has no effect"]
1497 pub fn build(self) -> Caps {
1498 let mut caps = Caps::new_empty();
1499
1500 caps.get_mut()
1501 .unwrap()
1502 .append_structure_full(self.s, self.features);
1503 caps
1504 }
1505
1506 pub fn structure(&self) -> &crate::Structure {
1507 &self.s
1508 }
1509}
1510
1511pub enum AnyFeatures {}
1512pub enum SomeFeatures {}
1513
1514#[must_use = "The builder must be built to be used"]
1515pub struct BuilderFull<T> {
1516 caps: crate::Caps,
1517 features: Option<CapsFeatures>,
1518 phantom: PhantomData<T>,
1519}
1520
1521impl<T> fmt::Debug for BuilderFull<T> {
1522 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1523 f.debug_struct("Builder")
1524 .field("caps", &self.caps)
1525 .field("features", &self.features)
1526 .field("phantom", &self.phantom)
1527 .finish()
1528 }
1529}
1530
1531impl BuilderFull<SomeFeatures> {
1532 fn new() -> Self {
1533 BuilderFull {
1534 caps: Caps::new_empty(),
1535 features: None,
1536 phantom: PhantomData,
1537 }
1538 }
1539
1540 fn with_features(features: CapsFeatures) -> Self {
1541 skip_assert_initialized!();
1542 BuilderFull {
1543 caps: Caps::new_empty(),
1544 features: Some(features),
1545 phantom: PhantomData,
1546 }
1547 }
1548
1549 pub fn structure_with_features(self, structure: Structure, features: CapsFeatures) -> Self {
1550 self.append_structure(structure, Some(features))
1551 }
1552
1553 pub fn structure_with_features_if_some(
1554 self,
1555 structure: Option<Structure>,
1556 features: CapsFeatures,
1557 ) -> Self {
1558 if let Some(structure) = structure {
1559 self.structure_with_features(structure, features)
1560 } else {
1561 self
1562 }
1563 }
1564
1565 pub fn structure_with_any_features(self, structure: Structure) -> Self {
1566 self.append_structure(structure, Some(CapsFeatures::new_any()))
1567 }
1568
1569 pub fn structure_with_any_features_if_some(self, structure: Option<Structure>) -> Self {
1570 if let Some(structure) = structure {
1571 self.structure_with_any_features(structure)
1572 } else {
1573 self
1574 }
1575 }
1576}
1577
1578impl BuilderFull<AnyFeatures> {
1579 fn with_any_features() -> Self {
1580 BuilderFull {
1581 caps: Caps::new_empty(),
1582 features: Some(CapsFeatures::new_any()),
1583 phantom: PhantomData,
1584 }
1585 }
1586}
1587
1588impl<T> BuilderFull<T> {
1589 fn append_structure(mut self, structure: Structure, features: Option<CapsFeatures>) -> Self {
1590 let features = {
1591 match self.features {
1592 None => features,
1593 Some(ref result) => {
1594 let mut result = result.clone();
1595 match features {
1596 None => Some(result),
1597 Some(features) => {
1598 features.iter().for_each(|feat| result.add(feat));
1599 Some(result)
1600 }
1601 }
1602 }
1603 }
1604 };
1605
1606 self.caps
1607 .get_mut()
1608 .unwrap()
1609 .append_structure_full(structure, features);
1610 self
1611 }
1612
1613 pub fn structure(self, structure: Structure) -> Self {
1614 self.append_structure(structure, None)
1615 }
1616
1617 pub fn structure_if_some(self, structure: Option<Structure>) -> Self {
1618 if let Some(structure) = structure {
1619 self.structure(structure)
1620 } else {
1621 self
1622 }
1623 }
1624
1625 #[must_use = "Building the caps without using them has no effect"]
1626 pub fn build(self) -> Caps {
1627 self.caps
1628 }
1629}
1630
1631#[cfg(test)]
1632mod tests {
1633 use super::*;
1634 use crate::{Array, Fraction};
1635 use glib::gstr;
1636
1637 #[test]
1638 fn test_builder() {
1639 crate::init().unwrap();
1640
1641 let mut caps = Caps::builder("foo/bar")
1642 .field("int", 12)
1643 .field_with_static(gstr!("bool"), true)
1644 .field_with_id(idstr!("string"), "bla")
1645 .field("fraction", Fraction::new(1, 2))
1646 .field_with_id(idstr!("array"), Array::new([1, 2]))
1647 .build();
1648 assert_eq!(
1649 caps.to_string(),
1650 "foo/bar, int=(int)12, bool=(boolean)true, string=(string)bla, fraction=(fraction)1/2, array=(int)< 1, 2 >"
1651 );
1652
1653 assert!(caps
1654 .features(0)
1655 .unwrap()
1656 .is_equal(crate::CAPS_FEATURES_MEMORY_SYSTEM_MEMORY.as_ref()));
1657
1658 {
1659 let caps = caps.get_mut().unwrap();
1660 caps.set_features(0, Some(CapsFeatures::new(["foo:bla"])));
1661 }
1662 assert!(caps
1663 .features(0)
1664 .unwrap()
1665 .is_equal(CapsFeatures::new(["foo:bla"]).as_ref()));
1666
1667 let caps = Caps::builder("foo/bar")
1668 .field("int", 12)
1669 .any_features()
1670 .build();
1671 assert_eq!(caps.to_string(), "foo/bar(ANY), int=(int)12");
1672
1673 let caps = Caps::builder("foo/bar")
1674 .field("int", 12)
1675 .features(["foo:bla", "foo:baz"])
1676 .build();
1677 assert_eq!(caps.to_string(), "foo/bar(foo:bla, foo:baz), int=(int)12");
1678
1679 let caps = Caps::builder("foo/bar")
1680 .field_if_some("int0", Option::<i32>::None)
1681 .field_if_some("int1", Some(12))
1682 .field_with_static_if_some(gstr!("string0"), Option::<String>::None)
1683 .field_with_id_if_some(idstr!("string1"), Some("bla"))
1684 .build();
1685 assert_eq!(
1686 caps.to_string(),
1687 "foo/bar, int1=(int)12, string1=(string)bla"
1688 );
1689 }
1690
1691 #[test]
1692 fn test_display() {
1693 crate::init().unwrap();
1694
1695 let caps = Caps::builder("foo/bar").build();
1696 let _ = format!("{caps}");
1697 }
1698
1699 #[test]
1700 fn test_builder_full() {
1701 crate::init().unwrap();
1702
1703 let caps = Caps::builder_full()
1704 .structure(Structure::builder("audio/x-raw").build())
1705 .structure(Structure::builder("video/x-raw").build())
1706 .build();
1707 assert_eq!(caps.to_string(), "audio/x-raw; video/x-raw");
1708
1709 let caps = Caps::builder_full()
1710 .structure(
1711 Structure::builder("audio/x-raw")
1712 .field("format", "S16LE")
1713 .build(),
1714 )
1715 .structure(Structure::builder("video/x-raw").build())
1716 .build();
1717 assert_eq!(
1718 caps.to_string(),
1719 "audio/x-raw, format=(string)S16LE; video/x-raw"
1720 );
1721
1722 let caps = Caps::builder_full()
1723 .structure_with_any_features(Structure::builder("audio/x-raw").build())
1724 .structure_with_features(
1725 Structure::builder("video/x-raw").build(),
1726 CapsFeatures::new(["foo:bla", "foo:baz"]),
1727 )
1728 .build();
1729 assert_eq!(
1730 caps.to_string(),
1731 "audio/x-raw(ANY); video/x-raw(foo:bla, foo:baz)"
1732 );
1733
1734 let caps = Caps::builder_full()
1735 .structure_if_some(Option::<Structure>::None)
1736 .build();
1737 assert!(caps.is_empty());
1738
1739 let caps = Caps::builder_full()
1740 .structure_if_some(Some(Structure::builder("audio/x-raw").build()))
1741 .build();
1742 assert_eq!(caps.to_string(), "audio/x-raw");
1743
1744 let caps = Caps::builder_full()
1745 .structure_with_any_features_if_some(Some(Structure::builder("audio/x-raw").build()))
1746 .structure_with_features_if_some(
1747 Some(Structure::builder("video/x-raw").build()),
1748 CapsFeatures::new_from_id([idstr!("foo:bla"), idstr!("foo:baz")]),
1749 )
1750 .build();
1751 assert_eq!(
1752 caps.to_string(),
1753 "audio/x-raw(ANY); video/x-raw(foo:bla, foo:baz)"
1754 );
1755
1756 let caps = Caps::builder_full()
1757 .structure_with_any_features_if_some(Option::<Structure>::None)
1758 .structure_with_features_if_some(
1759 Option::<Structure>::None,
1760 CapsFeatures::new(["foo:bla", "foo:baz"]),
1761 )
1762 .build();
1763 assert!(caps.is_empty());
1764 }
1765
1766 #[test]
1767 fn test_builder_full_with_features() {
1768 crate::init().unwrap();
1769
1770 let caps = Caps::builder_full_with_features(CapsFeatures::new(["foo:bla"]))
1771 .structure(Structure::builder("audio/x-raw").build())
1772 .structure_with_features(
1773 Structure::builder("video/x-raw").build(),
1774 CapsFeatures::new(["foo:baz"]),
1775 )
1776 .build();
1777 assert_eq!(
1778 caps.to_string(),
1779 "audio/x-raw(foo:bla); video/x-raw(foo:bla, foo:baz)"
1780 );
1781 }
1782
1783 #[test]
1784 fn test_builder_full_with_any_features() {
1785 crate::init().unwrap();
1786
1787 let caps = Caps::builder_full_with_any_features()
1788 .structure(Structure::builder("audio/x-raw").build())
1789 .structure(Structure::builder("video/x-raw").build())
1790 .build();
1791 assert_eq!(caps.to_string(), "audio/x-raw(ANY); video/x-raw(ANY)");
1792
1793 let caps = Caps::builder_full_with_any_features()
1794 .structure(Structure::builder("audio/x-raw").build())
1795 .build();
1796 assert_eq!(caps.to_string(), "audio/x-raw(ANY)");
1797 }
1798
1799 #[test]
1800 fn test_new_from_iter() {
1801 crate::init().unwrap();
1802
1803 let caps = Caps::builder_full_with_any_features()
1804 .structure(Structure::builder("audio/x-raw").build())
1805 .structure(Structure::builder("video/x-raw").build())
1806 .build();
1807
1808 let audio = caps
1809 .iter()
1810 .filter(|s| s.name() == "audio/x-raw")
1811 .map(|s| s.to_owned())
1812 .collect::<Caps>();
1813 assert_eq!(audio.to_string(), "audio/x-raw");
1814
1815 let audio = caps
1816 .iter_with_features()
1817 .filter(|(s, _)| s.name() == "audio/x-raw")
1818 .map(|(s, c)| (s.to_owned(), c.to_owned()))
1819 .collect::<Caps>();
1820 assert_eq!(audio.to_string(), "audio/x-raw(ANY)");
1821 }
1822
1823 #[test]
1824 fn test_debug() {
1825 crate::init().unwrap();
1826
1827 let caps = Caps::new_any();
1828 assert_eq!(format!("{caps:?}"), "Caps(\"ANY\")");
1829
1830 let caps = Caps::new_empty();
1831 assert_eq!(format!("{caps:?}"), "Caps(\"EMPTY\")");
1832
1833 let caps = Caps::builder_full_with_any_features()
1834 .structure(Structure::builder("audio/x-raw").build())
1835 .build();
1836 assert_eq!(format!("{caps:?}"), "Caps(audio/x-raw(ANY))");
1837
1838 let caps = Caps::builder_full_with_features(CapsFeatures::new(["foo:bla"]))
1839 .structure(
1840 Structure::builder("audio/x-raw")
1841 .field(
1842 "struct",
1843 Structure::builder("nested").field("badger", true).build(),
1844 )
1845 .build(),
1846 )
1847 .structure(
1848 Structure::builder("video/x-raw")
1849 .field("width", 800u32)
1850 .build(),
1851 )
1852 .build();
1853
1854 assert_eq!(format!("{caps:?}"), "Caps(audio/x-raw(foo:bla) { struct: Structure(nested { badger: (gboolean) TRUE }) }, video/x-raw(foo:bla) { width: (guint) 800 })");
1855
1856 let caps = Caps::builder_full()
1857 .structure(
1858 Structure::builder("video/x-raw")
1859 .field("array", crate::Array::new(["a", "b", "c"]))
1860 .field("list", crate::List::new(["d", "e", "f"]))
1861 .build(),
1862 )
1863 .build();
1864
1865 assert_eq!(format!("{caps:?}"), "Caps(video/x-raw(memory:SystemMemory) { array: Array([(gchararray) \"a\", (gchararray) \"b\", (gchararray) \"c\"]), list: List([(gchararray) \"d\", (gchararray) \"e\", (gchararray) \"f\"]) })");
1866 }
1867}