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