1use std::{
4 borrow::{Borrow, BorrowMut, ToOwned},
5 fmt,
6 marker::PhantomData,
7 mem,
8 ops::{Deref, DerefMut},
9 ptr, str,
10};
11
12use crate::ffi;
13use glib::{prelude::*, translate::*};
14use once_cell::sync::Lazy;
15
16#[doc(alias = "GstCapsFeatures")]
35#[repr(transparent)]
36pub struct CapsFeatures(ptr::NonNull<ffi::GstCapsFeatures>);
37unsafe impl Send for CapsFeatures {}
38unsafe impl Sync for CapsFeatures {}
39
40impl CapsFeatures {
41 #[doc(alias = "gst_caps_features_new")]
50 pub fn new(features: impl IntoIterator<Item = impl IntoGStr>) -> Self {
51 skip_assert_initialized!();
52 let mut f = Self::new_empty();
53
54 for feature in features {
55 f.add(feature);
56 }
57
58 f
59 }
60
61 #[doc(alias = "gst_caps_features_new_id")]
62 pub fn from_quarks(features: impl IntoIterator<Item = glib::Quark>) -> Self {
63 skip_assert_initialized!();
64 let mut f = Self::new_empty();
65
66 for feature in features.into_iter() {
67 f.add_from_quark(feature);
68 }
69
70 f
71 }
72
73 #[doc(alias = "gst_caps_features_new_empty")]
79 pub fn new_empty() -> Self {
80 assert_initialized_main_thread!();
81 unsafe {
82 CapsFeatures(ptr::NonNull::new_unchecked(
83 ffi::gst_caps_features_new_empty(),
84 ))
85 }
86 }
87
88 #[doc(alias = "gst_caps_features_new_any")]
96 pub fn new_any() -> Self {
97 assert_initialized_main_thread!();
98 unsafe { CapsFeatures(ptr::NonNull::new_unchecked(ffi::gst_caps_features_new_any())) }
99 }
100}
101
102impl IntoGlibPtr<*mut ffi::GstCapsFeatures> for CapsFeatures {
103 #[inline]
104 unsafe fn into_glib_ptr(self) -> *mut ffi::GstCapsFeatures {
105 let s = mem::ManuallyDrop::new(self);
106 s.0.as_ptr()
107 }
108}
109
110impl Deref for CapsFeatures {
111 type Target = CapsFeaturesRef;
112
113 #[inline]
114 fn deref(&self) -> &CapsFeaturesRef {
115 unsafe { &*(self.0.as_ref() as *const ffi::GstCapsFeatures as *const CapsFeaturesRef) }
116 }
117}
118
119impl DerefMut for CapsFeatures {
120 #[inline]
121 fn deref_mut(&mut self) -> &mut CapsFeaturesRef {
122 unsafe { &mut *(self.0.as_mut() as *mut ffi::GstCapsFeatures as *mut CapsFeaturesRef) }
123 }
124}
125
126impl AsRef<CapsFeaturesRef> for CapsFeatures {
127 #[inline]
128 fn as_ref(&self) -> &CapsFeaturesRef {
129 self.deref()
130 }
131}
132
133impl AsMut<CapsFeaturesRef> for CapsFeatures {
134 #[inline]
135 fn as_mut(&mut self) -> &mut CapsFeaturesRef {
136 self.deref_mut()
137 }
138}
139
140impl Clone for CapsFeatures {
141 #[inline]
142 fn clone(&self) -> Self {
143 unsafe {
144 let ptr = ffi::gst_caps_features_copy(self.0.as_ref());
145 debug_assert!(!ptr.is_null());
146 CapsFeatures(ptr::NonNull::new_unchecked(ptr))
147 }
148 }
149}
150
151impl Drop for CapsFeatures {
152 #[inline]
153 fn drop(&mut self) {
154 unsafe { ffi::gst_caps_features_free(self.0.as_mut()) }
155 }
156}
157
158impl fmt::Debug for CapsFeatures {
159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160 f.debug_tuple("CapsFeatures")
161 .field(&self.to_string())
162 .finish()
163 }
164}
165
166impl fmt::Display for CapsFeatures {
167 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
168 f.write_str(&CapsFeaturesRef::to_string(self.as_ref()))
171 }
172}
173
174impl str::FromStr for CapsFeatures {
175 type Err = glib::BoolError;
176
177 #[doc(alias = "gst_caps_features_from_string")]
178 fn from_str(s: &str) -> Result<Self, Self::Err> {
179 assert_initialized_main_thread!();
180 unsafe {
181 let ptr = s.run_with_gstr(|s| ffi::gst_caps_features_from_string(s.as_ptr()));
182 if ptr.is_null() {
183 return Err(glib::bool_error!(
184 "Failed to parse caps features from string"
185 ));
186 }
187
188 Ok(Self(ptr::NonNull::new_unchecked(ptr)))
189 }
190 }
191}
192
193impl Borrow<CapsFeaturesRef> for CapsFeatures {
194 #[inline]
195 fn borrow(&self) -> &CapsFeaturesRef {
196 self.as_ref()
197 }
198}
199
200impl BorrowMut<CapsFeaturesRef> for CapsFeatures {
201 #[inline]
202 fn borrow_mut(&mut self) -> &mut CapsFeaturesRef {
203 self.as_mut()
204 }
205}
206
207impl glib::types::StaticType for CapsFeatures {
208 #[inline]
209 fn static_type() -> glib::types::Type {
210 unsafe { from_glib(ffi::gst_caps_features_get_type()) }
211 }
212}
213
214impl<'a> ToGlibPtr<'a, *const ffi::GstCapsFeatures> for CapsFeatures {
215 type Storage = PhantomData<&'a Self>;
216
217 #[inline]
218 fn to_glib_none(&'a self) -> Stash<'a, *const ffi::GstCapsFeatures, Self> {
219 unsafe { Stash(self.0.as_ref(), PhantomData) }
220 }
221
222 #[inline]
223 fn to_glib_full(&self) -> *const ffi::GstCapsFeatures {
224 unsafe { ffi::gst_caps_features_copy(self.0.as_ref()) }
225 }
226}
227
228impl<'a> ToGlibPtr<'a, *mut ffi::GstCapsFeatures> for CapsFeatures {
229 type Storage = PhantomData<&'a Self>;
230
231 #[inline]
232 fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::GstCapsFeatures, Self> {
233 unsafe {
234 Stash(
235 self.0.as_ref() as *const ffi::GstCapsFeatures as *mut ffi::GstCapsFeatures,
236 PhantomData,
237 )
238 }
239 }
240
241 #[inline]
242 fn to_glib_full(&self) -> *mut ffi::GstCapsFeatures {
243 unsafe { ffi::gst_caps_features_copy(self.0.as_ref()) }
244 }
245}
246
247impl<'a> ToGlibPtrMut<'a, *mut ffi::GstCapsFeatures> for CapsFeatures {
248 type Storage = PhantomData<&'a mut Self>;
249
250 #[inline]
251 fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::GstCapsFeatures, Self> {
252 unsafe { StashMut(self.0.as_mut(), PhantomData) }
253 }
254}
255
256impl FromGlibPtrNone<*const ffi::GstCapsFeatures> for CapsFeatures {
257 #[inline]
258 unsafe fn from_glib_none(ptr: *const ffi::GstCapsFeatures) -> Self {
259 debug_assert!(!ptr.is_null());
260 let ptr = ffi::gst_caps_features_copy(ptr);
261 debug_assert!(!ptr.is_null());
262 CapsFeatures(ptr::NonNull::new_unchecked(ptr))
263 }
264}
265
266impl FromGlibPtrNone<*mut ffi::GstCapsFeatures> for CapsFeatures {
267 #[inline]
268 unsafe fn from_glib_none(ptr: *mut ffi::GstCapsFeatures) -> Self {
269 debug_assert!(!ptr.is_null());
270 let ptr = ffi::gst_caps_features_copy(ptr);
271 debug_assert!(!ptr.is_null());
272 CapsFeatures(ptr::NonNull::new_unchecked(ptr))
273 }
274}
275
276impl FromGlibPtrFull<*const ffi::GstCapsFeatures> for CapsFeatures {
277 #[inline]
278 unsafe fn from_glib_full(ptr: *const ffi::GstCapsFeatures) -> Self {
279 debug_assert!(!ptr.is_null());
280 CapsFeatures(ptr::NonNull::new_unchecked(
281 ptr as *mut ffi::GstCapsFeatures,
282 ))
283 }
284}
285
286impl FromGlibPtrFull<*mut ffi::GstCapsFeatures> for CapsFeatures {
287 #[inline]
288 unsafe fn from_glib_full(ptr: *mut ffi::GstCapsFeatures) -> Self {
289 debug_assert!(!ptr.is_null());
290 CapsFeatures(ptr::NonNull::new_unchecked(ptr))
291 }
292}
293
294impl glib::value::ValueType for CapsFeatures {
295 type Type = Self;
296}
297
298impl glib::value::ValueTypeOptional for CapsFeatures {}
299
300unsafe impl<'a> glib::value::FromValue<'a> for CapsFeatures {
301 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
302
303 unsafe fn from_value(value: &'a glib::Value) -> Self {
304 skip_assert_initialized!();
305 from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0)
306 as *mut ffi::GstCapsFeatures)
307 }
308}
309
310impl glib::value::ToValue for CapsFeatures {
311 fn to_value(&self) -> glib::Value {
312 let mut value = glib::Value::for_value_type::<Self>();
313 unsafe {
314 glib::gobject_ffi::g_value_set_boxed(
315 value.to_glib_none_mut().0,
316 ToGlibPtr::<*mut ffi::GstCapsFeatures>::to_glib_none(self).0 as *mut _,
317 )
318 }
319 value
320 }
321
322 fn value_type(&self) -> glib::Type {
323 Self::static_type()
324 }
325}
326
327impl glib::value::ToValueOptional for CapsFeatures {
328 fn to_value_optional(s: Option<&Self>) -> glib::Value {
329 skip_assert_initialized!();
330 let mut value = glib::Value::for_value_type::<Self>();
331 unsafe {
332 glib::gobject_ffi::g_value_set_boxed(
333 value.to_glib_none_mut().0,
334 ToGlibPtr::<*mut ffi::GstCapsFeatures>::to_glib_none(&s).0 as *mut _,
335 )
336 }
337 value
338 }
339}
340
341impl From<CapsFeatures> for glib::Value {
342 fn from(v: CapsFeatures) -> glib::Value {
343 skip_assert_initialized!();
344 let mut value = glib::Value::for_value_type::<CapsFeatures>();
345 unsafe {
346 glib::gobject_ffi::g_value_take_boxed(
347 value.to_glib_none_mut().0,
348 IntoGlibPtr::<*mut ffi::GstCapsFeatures>::into_glib_ptr(v) as *mut _,
349 )
350 }
351 value
352 }
353}
354
355impl GlibPtrDefault for CapsFeatures {
356 type GlibType = *mut ffi::GstCapsFeatures;
357}
358
359unsafe impl TransparentPtrType for CapsFeatures {}
360
361#[repr(transparent)]
362#[doc(alias = "GstCapsFeatures")]
363pub struct CapsFeaturesRef(ffi::GstCapsFeatures);
364
365impl CapsFeaturesRef {
366 #[inline]
367 pub unsafe fn from_glib_borrow<'a>(ptr: *const ffi::GstCapsFeatures) -> &'a CapsFeaturesRef {
368 debug_assert!(!ptr.is_null());
369
370 &*(ptr as *mut CapsFeaturesRef)
371 }
372
373 #[inline]
374 pub unsafe fn from_glib_borrow_mut<'a>(
375 ptr: *mut ffi::GstCapsFeatures,
376 ) -> &'a mut CapsFeaturesRef {
377 debug_assert!(!ptr.is_null());
378
379 &mut *(ptr as *mut CapsFeaturesRef)
380 }
381
382 #[inline]
383 pub fn as_ptr(&self) -> *const ffi::GstCapsFeatures {
384 self as *const Self as *const ffi::GstCapsFeatures
385 }
386
387 #[inline]
388 pub fn as_mut_ptr(&self) -> *mut ffi::GstCapsFeatures {
389 self as *const Self as *mut ffi::GstCapsFeatures
390 }
391
392 pub fn is_empty(&self) -> bool {
393 self.size() == 0 && !self.is_any()
394 }
395
396 #[doc(alias = "gst_caps_features_is_any")]
397 pub fn is_any(&self) -> bool {
398 unsafe { from_glib(ffi::gst_caps_features_is_any(self.as_ptr())) }
399 }
400
401 #[doc(alias = "gst_caps_features_contains")]
402 pub fn contains(&self, feature: impl IntoGStr) -> bool {
403 unsafe {
404 feature.run_with_gstr(|feature| {
405 from_glib(ffi::gst_caps_features_contains(
406 self.as_ptr(),
407 feature.as_ptr(),
408 ))
409 })
410 }
411 }
412
413 #[doc(alias = "gst_caps_features_contains_id")]
414 pub fn contains_quark(&self, feature: glib::Quark) -> bool {
415 unsafe {
416 from_glib(ffi::gst_caps_features_contains_id(
417 self.as_ptr(),
418 feature.into_glib(),
419 ))
420 }
421 }
422
423 #[doc(alias = "get_size")]
424 #[doc(alias = "gst_caps_features_get_size")]
425 pub fn size(&self) -> usize {
426 unsafe { ffi::gst_caps_features_get_size(self.as_ptr()) as usize }
427 }
428
429 #[doc(alias = "get_nth")]
430 #[doc(alias = "gst_caps_features_get_nth")]
431 pub fn nth(&self, idx: usize) -> Option<&glib::GStr> {
432 if idx >= self.size() {
433 return None;
434 }
435
436 unsafe {
437 let feature = ffi::gst_caps_features_get_nth(self.as_ptr(), idx as u32);
438 if feature.is_null() {
439 return None;
440 }
441
442 Some(glib::GStr::from_ptr(feature))
445 }
446 }
447
448 #[doc(alias = "gst_caps_features_get_nth_id")]
449 pub fn nth_quark(&self, idx: usize) -> Option<glib::Quark> {
450 if idx >= self.size() {
451 return None;
452 }
453
454 unsafe {
455 let feature = ffi::gst_caps_features_get_nth_id(self.as_ptr(), idx as u32);
456 Some(from_glib(feature))
457 }
458 }
459
460 #[doc(alias = "gst_caps_features_add")]
461 pub fn add(&mut self, feature: impl IntoGStr) {
462 unsafe {
463 feature.run_with_gstr(|feature| {
464 ffi::gst_caps_features_add(self.as_mut_ptr(), feature.as_ptr())
465 })
466 }
467 }
468
469 #[doc(alias = "gst_caps_features_remove")]
470 pub fn remove(&mut self, feature: impl IntoGStr) {
471 unsafe {
472 feature.run_with_gstr(|feature| {
473 ffi::gst_caps_features_remove(self.as_mut_ptr(), feature.as_ptr())
474 })
475 }
476 }
477
478 #[doc(alias = "gst_caps_features_add_id")]
479 pub fn add_from_quark(&mut self, feature: glib::Quark) {
480 unsafe { ffi::gst_caps_features_add_id(self.as_mut_ptr(), feature.into_glib()) }
481 }
482
483 #[doc(alias = "gst_caps_features_remove_id")]
484 pub fn remove_by_quark(&mut self, feature: glib::Quark) {
485 unsafe { ffi::gst_caps_features_remove_id(self.as_mut_ptr(), feature.into_glib()) }
486 }
487
488 pub fn iter(&self) -> Iter {
489 Iter::new(self)
490 }
491
492 #[doc(alias = "gst_caps_features_is_equal")]
494 pub fn is_equal(&self, other: &CapsFeaturesRef) -> bool {
495 unsafe {
496 from_glib(ffi::gst_caps_features_is_equal(
497 self.as_ptr(),
498 other.as_ptr(),
499 ))
500 }
501 }
502}
503
504impl glib::types::StaticType for CapsFeaturesRef {
505 #[inline]
506 fn static_type() -> glib::types::Type {
507 unsafe { from_glib(ffi::gst_structure_get_type()) }
508 }
509}
510
511impl<'a> std::iter::Extend<&'a str> for CapsFeaturesRef {
512 fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
513 iter.into_iter().for_each(|f| self.add(f));
514 }
515}
516
517impl<'a> std::iter::Extend<&'a glib::GStr> for CapsFeaturesRef {
518 fn extend<T: IntoIterator<Item = &'a glib::GStr>>(&mut self, iter: T) {
519 iter.into_iter().for_each(|f| self.add(f));
520 }
521}
522
523impl std::iter::Extend<String> for CapsFeaturesRef {
524 fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
525 iter.into_iter().for_each(|f| self.add(&f));
526 }
527}
528
529impl std::iter::Extend<glib::GString> for CapsFeaturesRef {
530 fn extend<T: IntoIterator<Item = glib::GString>>(&mut self, iter: T) {
531 iter.into_iter().for_each(|f| self.add(&f));
532 }
533}
534
535impl std::iter::Extend<glib::Quark> for CapsFeaturesRef {
536 fn extend<T: IntoIterator<Item = glib::Quark>>(&mut self, iter: T) {
537 iter.into_iter().for_each(|f| self.add_from_quark(f));
538 }
539}
540
541unsafe impl<'a> glib::value::FromValue<'a> for &'a CapsFeaturesRef {
542 type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
543
544 unsafe fn from_value(value: &'a glib::Value) -> Self {
545 skip_assert_initialized!();
546 &*(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const CapsFeaturesRef)
547 }
548}
549
550impl glib::value::ToValue for CapsFeaturesRef {
551 fn to_value(&self) -> glib::Value {
552 let mut value = glib::Value::for_value_type::<CapsFeatures>();
553 unsafe {
554 glib::gobject_ffi::g_value_set_boxed(
555 value.to_glib_none_mut().0,
556 self.as_mut_ptr() as *mut _,
557 )
558 }
559 value
560 }
561
562 fn value_type(&self) -> glib::Type {
563 Self::static_type()
564 }
565}
566
567impl glib::value::ToValueOptional for CapsFeaturesRef {
568 fn to_value_optional(s: Option<&Self>) -> glib::Value {
569 skip_assert_initialized!();
570 let mut value = glib::Value::for_value_type::<CapsFeatures>();
571 unsafe {
572 glib::gobject_ffi::g_value_set_boxed(
573 value.to_glib_none_mut().0,
574 s.map(|s| s.as_mut_ptr()).unwrap_or(ptr::null_mut()) as *mut _,
575 )
576 }
577 value
578 }
579}
580
581#[derive(Debug)]
582pub struct Iter<'a> {
583 caps_features: &'a CapsFeaturesRef,
584 idx: usize,
585 n_features: usize,
586}
587
588impl<'a> Iter<'a> {
589 fn new(caps_features: &'a CapsFeaturesRef) -> Iter<'a> {
590 skip_assert_initialized!();
591 let n_features = caps_features.size();
592
593 Iter {
594 caps_features,
595 idx: 0,
596 n_features,
597 }
598 }
599}
600
601impl<'a> Iterator for Iter<'a> {
602 type Item = &'a glib::GStr;
603
604 fn next(&mut self) -> Option<Self::Item> {
605 if self.idx >= self.n_features {
606 return None;
607 }
608
609 unsafe {
610 let feature =
611 ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.idx as u32);
612 debug_assert!(!feature.is_null());
613
614 self.idx += 1;
615
616 Some(glib::GStr::from_ptr(feature))
619 }
620 }
621
622 fn size_hint(&self) -> (usize, Option<usize>) {
623 let remaining = self.n_features - self.idx;
624
625 (remaining, Some(remaining))
626 }
627
628 fn count(self) -> usize {
629 self.n_features - self.idx
630 }
631
632 fn nth(&mut self, n: usize) -> Option<Self::Item> {
634 let (end, overflow) = self.idx.overflowing_add(n);
635 if end >= self.n_features || overflow {
636 self.idx = self.n_features;
637 None
638 } else {
639 unsafe {
640 self.idx = end + 1;
641 let feature =
642 ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), end as u32);
643 debug_assert!(!feature.is_null());
644
645 Some(glib::GStr::from_ptr(feature))
648 }
649 }
650 }
651
652 fn last(self) -> Option<Self::Item> {
653 if self.idx == self.n_features {
654 None
655 } else {
656 unsafe {
657 let feature = ffi::gst_caps_features_get_nth(
658 self.caps_features.as_ptr(),
659 self.n_features as u32 - 1,
660 );
661 debug_assert!(!feature.is_null());
662
663 Some(glib::GStr::from_ptr(feature))
666 }
667 }
668 }
669}
670
671impl DoubleEndedIterator for Iter<'_> {
672 fn next_back(&mut self) -> Option<Self::Item> {
673 if self.idx == self.n_features {
674 return None;
675 }
676
677 self.n_features -= 1;
678
679 unsafe {
680 let feature =
681 ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.n_features as u32);
682 debug_assert!(!feature.is_null());
683
684 Some(glib::GStr::from_ptr(feature))
687 }
688 }
689
690 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
691 let (end, overflow) = self.n_features.overflowing_sub(n);
692 if end <= self.idx || overflow {
693 self.idx = self.n_features;
694 None
695 } else {
696 unsafe {
697 self.n_features = end - 1;
698 let feature = ffi::gst_caps_features_get_nth(
699 self.caps_features.as_ptr(),
700 self.n_features as u32,
701 );
702 debug_assert!(!feature.is_null());
703
704 Some(glib::GStr::from_ptr(feature))
707 }
708 }
709 }
710}
711
712impl ExactSizeIterator for Iter<'_> {}
713
714impl std::iter::FusedIterator for Iter<'_> {}
715
716impl<'a> IntoIterator for &'a CapsFeaturesRef {
717 type IntoIter = Iter<'a>;
718 type Item = &'a glib::GStr;
719
720 fn into_iter(self) -> Self::IntoIter {
721 self.iter()
722 }
723}
724
725impl<'a> From<&'a str> for CapsFeatures {
726 fn from(value: &'a str) -> Self {
727 skip_assert_initialized!();
728 let mut features = CapsFeatures::new_empty();
729
730 features.add(value);
731
732 features
733 }
734}
735
736impl<'a> From<&'a glib::GStr> for CapsFeatures {
737 fn from(value: &'a glib::GStr) -> Self {
738 skip_assert_initialized!();
739 let mut features = CapsFeatures::new_empty();
740
741 features.add(value);
742
743 features
744 }
745}
746
747impl From<glib::Quark> for CapsFeatures {
748 fn from(value: glib::Quark) -> Self {
749 skip_assert_initialized!();
750 let mut features = CapsFeatures::new_empty();
751
752 features.add_from_quark(value);
753
754 features
755 }
756}
757
758impl<'a, const N: usize> From<[&'a str; N]> for CapsFeatures {
759 fn from(value: [&'a str; N]) -> Self {
760 skip_assert_initialized!();
761 let mut features = CapsFeatures::new_empty();
762
763 value.into_iter().for_each(|f| features.add(f));
764
765 features
766 }
767}
768
769impl<'a, const N: usize> From<[&'a glib::GStr; N]> for CapsFeatures {
770 fn from(value: [&'a glib::GStr; N]) -> Self {
771 skip_assert_initialized!();
772 let mut features = CapsFeatures::new_empty();
773
774 value.into_iter().for_each(|f| features.add(f));
775
776 features
777 }
778}
779
780impl<const N: usize> From<[String; N]> for CapsFeatures {
781 fn from(value: [String; N]) -> Self {
782 skip_assert_initialized!();
783 let mut features = CapsFeatures::new_empty();
784
785 value.into_iter().for_each(|f| features.add(&f));
786
787 features
788 }
789}
790
791impl<const N: usize> From<[glib::GString; N]> for CapsFeatures {
792 fn from(value: [glib::GString; N]) -> Self {
793 skip_assert_initialized!();
794 let mut features = CapsFeatures::new_empty();
795
796 value.into_iter().for_each(|f| features.add(&f));
797
798 features
799 }
800}
801
802impl<const N: usize> From<[glib::Quark; N]> for CapsFeatures {
803 fn from(value: [glib::Quark; N]) -> Self {
804 skip_assert_initialized!();
805 let mut features = CapsFeatures::new_empty();
806
807 value.into_iter().for_each(|f| features.add_from_quark(f));
808
809 features
810 }
811}
812
813impl<'a> std::iter::FromIterator<&'a str> for CapsFeatures {
814 fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
815 skip_assert_initialized!();
816 let mut features = CapsFeatures::new_empty();
817
818 iter.into_iter().for_each(|f| features.add(f));
819
820 features
821 }
822}
823
824impl<'a> std::iter::FromIterator<&'a glib::GStr> for CapsFeatures {
825 fn from_iter<T: IntoIterator<Item = &'a glib::GStr>>(iter: T) -> Self {
826 assert_initialized_main_thread!();
827
828 let mut features = CapsFeatures::new_empty();
829
830 iter.into_iter().for_each(|f| features.add(f));
831
832 features
833 }
834}
835
836impl std::iter::FromIterator<String> for CapsFeatures {
837 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
838 skip_assert_initialized!();
839 let mut features = CapsFeatures::new_empty();
840
841 iter.into_iter().for_each(|f| features.add(&f));
842
843 features
844 }
845}
846
847impl std::iter::FromIterator<glib::GString> for CapsFeatures {
848 fn from_iter<T: IntoIterator<Item = glib::GString>>(iter: T) -> Self {
849 assert_initialized_main_thread!();
850
851 let mut features = CapsFeatures::new_empty();
852
853 iter.into_iter().for_each(|f| features.add(&f));
854
855 features
856 }
857}
858
859impl std::iter::FromIterator<glib::Quark> for CapsFeatures {
860 fn from_iter<T: IntoIterator<Item = glib::Quark>>(iter: T) -> Self {
861 skip_assert_initialized!();
862 let mut features = CapsFeatures::new_empty();
863
864 iter.into_iter().for_each(|f| features.add_from_quark(f));
865
866 features
867 }
868}
869
870impl fmt::Debug for CapsFeaturesRef {
871 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
872 f.debug_tuple("CapsFeatures")
873 .field(&self.to_string())
874 .finish()
875 }
876}
877
878impl fmt::Display for CapsFeaturesRef {
879 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
880 let s = unsafe {
881 glib::GString::from_glib_full(ffi::gst_caps_features_to_string(self.as_ptr()))
882 };
883 f.write_str(&s)
884 }
885}
886
887impl ToOwned for CapsFeaturesRef {
888 type Owned = CapsFeatures;
889
890 #[inline]
891 fn to_owned(&self) -> CapsFeatures {
892 unsafe { from_glib_full(ffi::gst_caps_features_copy(self.as_ptr() as *const _) as *mut _) }
893 }
894}
895
896unsafe impl Sync for CapsFeaturesRef {}
897unsafe impl Send for CapsFeaturesRef {}
898
899pub static CAPS_FEATURE_MEMORY_SYSTEM_MEMORY: &glib::GStr =
900 unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY) };
901pub static CAPS_FEATURES_MEMORY_SYSTEM_MEMORY: Lazy<CapsFeatures> =
902 Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_MEMORY_SYSTEM_MEMORY]));
903
904#[cfg(test)]
905mod tests {
906 use super::*;
907
908 #[test]
909 fn test_from_value_optional() {
910 use glib::value::ToValue;
911
912 crate::init().unwrap();
913
914 let a = None::<CapsFeatures>.to_value();
915 assert!(a.get::<Option<CapsFeatures>>().unwrap().is_none());
916 let b = glib::value::Value::from(&CapsFeatures::new_empty());
917 assert!(b.get::<Option<CapsFeatures>>().unwrap().is_some());
918 }
919}