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