1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use std::{ |
4 | borrow::{Borrow, BorrowMut, ToOwned}, |
5 | fmt, |
6 | marker::PhantomData, |
7 | mem, |
8 | ops::{Deref, DerefMut}, |
9 | ptr, str, |
10 | }; |
11 | |
12 | use glib::once_cell::sync::Lazy; |
13 | use glib::{translate::*, IntoGStr, StaticType}; |
14 | |
15 | #[doc (alias = "GstCapsFeatures" )] |
16 | #[repr (transparent)] |
17 | pub struct CapsFeatures(ptr::NonNull<ffi::GstCapsFeatures>); |
18 | unsafe impl Send for CapsFeatures {} |
19 | unsafe impl Sync for CapsFeatures {} |
20 | |
21 | impl 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 | |
63 | impl 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 | |
71 | impl 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 | |
80 | impl 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 | |
87 | impl AsRef<CapsFeaturesRef> for CapsFeatures { |
88 | #[inline ] |
89 | fn as_ref(&self) -> &CapsFeaturesRef { |
90 | self.deref() |
91 | } |
92 | } |
93 | |
94 | impl AsMut<CapsFeaturesRef> for CapsFeatures { |
95 | #[inline ] |
96 | fn as_mut(&mut self) -> &mut CapsFeaturesRef { |
97 | self.deref_mut() |
98 | } |
99 | } |
100 | |
101 | impl 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 | |
112 | impl Drop for CapsFeatures { |
113 | #[inline ] |
114 | fn drop(&mut self) { |
115 | unsafe { ffi::gst_caps_features_free(self.0.as_mut()) } |
116 | } |
117 | } |
118 | |
119 | impl 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 | |
127 | impl 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 | |
135 | impl 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 | |
154 | impl Borrow<CapsFeaturesRef> for CapsFeatures { |
155 | #[inline ] |
156 | fn borrow(&self) -> &CapsFeaturesRef { |
157 | self.as_ref() |
158 | } |
159 | } |
160 | |
161 | impl BorrowMut<CapsFeaturesRef> for CapsFeatures { |
162 | #[inline ] |
163 | fn borrow_mut(&mut self) -> &mut CapsFeaturesRef { |
164 | self.as_mut() |
165 | } |
166 | } |
167 | |
168 | impl 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 | |
175 | impl<'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 | |
189 | impl<'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 | |
208 | impl<'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 | |
217 | impl 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 | |
227 | impl 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 | |
237 | impl 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 | |
247 | impl 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 | |
255 | impl glib::value::ValueType for CapsFeatures { |
256 | type Type = Self; |
257 | } |
258 | |
259 | impl glib::value::ValueTypeOptional for CapsFeatures {} |
260 | |
261 | unsafe 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 | |
271 | impl 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 | |
288 | impl 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 | |
302 | impl 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 | |
316 | impl GlibPtrDefault for CapsFeatures { |
317 | type GlibType = *mut ffi::GstCapsFeatures; |
318 | } |
319 | |
320 | unsafe impl TransparentPtrType for CapsFeatures {} |
321 | |
322 | #[repr (transparent)] |
323 | #[doc (alias = "GstCapsFeatures" )] |
324 | pub struct CapsFeaturesRef(ffi::GstCapsFeatures); |
325 | |
326 | impl 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 | |
463 | impl 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 | |
470 | impl<'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 | |
476 | impl<'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 | |
482 | impl 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 | |
488 | impl 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 | |
494 | impl 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 | |
500 | unsafe 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 | |
509 | impl 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 | |
526 | impl 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)] |
541 | pub struct Iter<'a> { |
542 | caps_features: &'a CapsFeaturesRef, |
543 | idx: usize, |
544 | n_features: usize, |
545 | } |
546 | |
547 | impl<'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 | |
560 | impl<'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 | |
622 | impl<'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 | |
659 | impl<'a> ExactSizeIterator for Iter<'a> {} |
660 | |
661 | impl<'a> std::iter::FusedIterator for Iter<'a> {} |
662 | |
663 | impl<'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 | |
672 | impl<'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 | |
683 | impl<'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 | |
694 | impl 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 | |
705 | impl<'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 | |
716 | impl<'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 | |
727 | impl<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 | |
738 | impl<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 | |
749 | impl<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 | |
760 | impl<'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 | |
771 | impl<'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 | |
783 | impl 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 | |
794 | impl 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 | |
806 | impl 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 | |
817 | impl 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 | |
825 | impl 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 | |
834 | impl 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 | |
843 | unsafe impl Sync for CapsFeaturesRef {} |
844 | unsafe impl Send for CapsFeaturesRef {} |
845 | |
846 | pub 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) }; |
848 | pub static CAPS_FEATURES_MEMORY_SYSTEM_MEMORY: Lazy<CapsFeatures> = |
849 | Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_MEMORY_SYSTEM_MEMORY])); |
850 | |
851 | #[cfg (test)] |
852 | mod 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 | |