1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::fmt;
4
5use glib::translate::*;
6
7pub trait IsMiniObject:
8 AsRef<Self::RefType> + FromGlibPtrFull<*mut Self::FfiType> + Send + Sync + 'static
9{
10 type RefType;
11 type FfiType;
12}
13
14#[macro_export]
15macro_rules! mini_object_wrapper (
16 ($name:ident, $ref_name:ident, $ffi_name:path) => {
17 #[repr(transparent)]
18 pub struct $name {
19 obj: std::ptr::NonNull<$ffi_name>,
20 }
21
22 #[repr(transparent)]
23 pub struct $ref_name($ffi_name);
24
25 impl $crate::miniobject::IsMiniObject for $name {
26 type RefType = $ref_name;
27 type FfiType = $ffi_name;
28 }
29
30 impl $name {
31 #[inline]
32 pub unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self {
33 skip_assert_initialized!();
34 debug_assert!(!ptr.is_null());
35
36 $crate::ffi::gst_mini_object_ref(ptr as *mut $crate::ffi::GstMiniObject);
37
38 $name {
39 obj: std::ptr::NonNull::new_unchecked(ptr as *mut $ffi_name),
40 }
41 }
42
43 #[inline]
44 pub unsafe fn from_glib_full(ptr: *const $ffi_name) -> Self {
45 skip_assert_initialized!();
46 debug_assert!(!ptr.is_null());
47
48 $name {
49 obj: std::ptr::NonNull::new_unchecked(ptr as *mut $ffi_name),
50 }
51 }
52
53 #[inline]
54 pub unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> $crate::glib::translate::Borrowed<Self> {
55 skip_assert_initialized!();
56 debug_assert!(!ptr.is_null());
57
58 $crate::glib::translate::Borrowed::new($name {
59 obj: std::ptr::NonNull::new_unchecked(ptr as *mut $ffi_name),
60 })
61 }
62
63 #[inline]
64 pub unsafe fn replace_ptr(&mut self, ptr: *mut $ffi_name) {
65 debug_assert!(!ptr.is_null());
66 self.obj = std::ptr::NonNull::new_unchecked(ptr);
67 }
68
69 #[inline]
70 #[doc(alias = "gst_mini_object_make_writable")]
71 pub fn make_mut(&mut self) -> &mut $ref_name {
72 unsafe {
73 if self.is_writable() {
74 return &mut *(self.obj.as_mut() as *mut $ffi_name as *mut $ref_name);
75 }
76
77 let ptr = $crate::ffi::gst_mini_object_make_writable(
78 self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject
79 );
80 self.replace_ptr(ptr as *mut $ffi_name);
81 debug_assert!(self.is_writable());
82
83 &mut *(self.obj.as_mut() as *mut $ffi_name as *mut $ref_name)
84 }
85 }
86
87 #[inline]
88 pub fn get_mut(&mut self) -> Option<&mut $ref_name> {
89 if self.is_writable() {
90 Some(unsafe { &mut *(self.obj.as_mut() as *mut $ffi_name as *mut $ref_name) })
91 } else {
92 None
93 }
94 }
95
96 #[doc(alias = "gst_mini_object_is_writable")]
97 #[inline]
98 pub fn is_writable(&self) -> bool {
99 unsafe {
100 $crate::glib::translate::from_glib($crate::ffi::gst_mini_object_is_writable(
101 self.as_ptr() as *const $crate::ffi::GstMiniObject
102 ))
103 }
104 }
105
106 #[must_use]
107 #[inline]
108 pub fn upcast(self) -> $crate::miniobject::MiniObject {
109 use $crate::glib::translate::IntoGlibPtr;
110
111 unsafe {
112 from_glib_full(self.into_glib_ptr() as *mut $crate::ffi::GstMiniObject)
113 }
114 }
115 }
116
117 impl $crate::glib::translate::IntoGlibPtr<*mut $ffi_name> for $name {
118 #[inline]
119 unsafe fn into_glib_ptr(self) -> *mut $ffi_name {
120 let s = std::mem::ManuallyDrop::new(self);
121 s.as_mut_ptr()
122 }
123 }
124
125 impl Clone for $name {
126 #[inline]
127 fn clone(&self) -> Self {
128 unsafe { $name::from_glib_none(self.as_ptr()) }
129 }
130 }
131
132 impl Drop for $name {
133 #[inline]
134 fn drop(&mut self) {
135 unsafe {
136 $crate::ffi::gst_mini_object_unref(self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject);
137 }
138 }
139 }
140
141 impl std::ops::Deref for $name {
142 type Target = $ref_name;
143
144 #[inline]
145 fn deref(&self) -> &Self::Target {
146 unsafe { &*(self.obj.as_ref() as *const $ffi_name as *const $ref_name) }
147 }
148 }
149
150 impl AsRef<$ref_name> for $name {
151 #[inline]
152 fn as_ref(&self) -> &$ref_name {
153 &*self
154 }
155 }
156
157 impl std::borrow::Borrow<$ref_name> for $name {
158 #[inline]
159 fn borrow(&self) -> &$ref_name {
160 &*self
161 }
162 }
163
164 impl<'a> $crate::glib::translate::ToGlibPtr<'a, *const $ffi_name> for $name {
165 type Storage = std::marker::PhantomData<&'a Self>;
166
167 #[inline]
168 fn to_glib_none(&'a self) -> $crate::glib::translate::Stash<'a, *const $ffi_name, Self> {
169 $crate::glib::translate::Stash(self.as_ptr(), std::marker::PhantomData)
170 }
171
172 #[inline]
173 fn to_glib_full(&self) -> *const $ffi_name {
174 unsafe {
175 $crate::ffi::gst_mini_object_ref(self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject);
176 self.as_ptr()
177 }
178 }
179 }
180
181 impl<'a> $crate::glib::translate::ToGlibPtr<'a, *mut $ffi_name> for $name {
182 type Storage = std::marker::PhantomData<&'a Self>;
183
184 #[inline]
185 fn to_glib_none(&'a self) -> $crate::glib::translate::Stash<'a, *mut $ffi_name, Self> {
186 $crate::glib::translate::Stash(self.as_mut_ptr(), std::marker::PhantomData)
187 }
188
189 #[inline]
190 fn to_glib_full(&self) -> *mut $ffi_name {
191 unsafe {
192 $crate::ffi::gst_mini_object_ref(self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject);
193 self.as_mut_ptr()
194 }
195 }
196 }
197
198 impl<'a> $crate::glib::translate::ToGlibPtrMut<'a, *mut $ffi_name> for $name {
199 type Storage = std::marker::PhantomData<&'a mut Self>;
200
201 #[inline]
202 fn to_glib_none_mut(&'a mut self) -> $crate::glib::translate::StashMut<*mut $ffi_name, Self> {
203 self.make_mut();
204 $crate::glib::translate::StashMut(self.as_mut_ptr(), std::marker::PhantomData)
205 }
206 }
207
208 impl<'a> $crate::glib::translate::ToGlibContainerFromSlice<'a, *mut *mut $ffi_name> for $name {
209 #[allow(clippy::type_complexity)]
210 type Storage = (
211 std::marker::PhantomData<&'a [$name]>,
212 Option<Vec<*mut $ffi_name>>,
213 );
214
215 fn to_glib_none_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) {
216 skip_assert_initialized!();
217 let mut v_ptr = Vec::with_capacity(t.len() + 1);
218 unsafe {
219 let ptr = v_ptr.as_mut_ptr();
220 std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, ptr, t.len());
221 std::ptr::write(ptr.add(t.len()), std::ptr::null_mut());
222 v_ptr.set_len(t.len() + 1);
223 }
224
225 (v_ptr.as_ptr() as *mut *mut $ffi_name, (std::marker::PhantomData, Some(v_ptr)))
226 }
227
228 fn to_glib_container_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) {
229 skip_assert_initialized!();
230
231 let v_ptr = unsafe {
232 let v_ptr = $crate::glib::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * t.len() + 1)
233 as *mut *mut $ffi_name;
234
235 std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, v_ptr, t.len());
236 std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
237
238 v_ptr
239 };
240
241 (v_ptr, (std::marker::PhantomData, None))
242 }
243
244 fn to_glib_full_from_slice(t: &[$name]) -> *mut *mut $ffi_name {
245 skip_assert_initialized!();
246 unsafe {
247 let v_ptr = $crate::glib::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * t.len() + 1)
248 as *mut *mut $ffi_name;
249
250 for (i, s) in t.iter().enumerate() {
251 std::ptr::write(v_ptr.add(i), $crate::glib::translate::ToGlibPtr::to_glib_full(s));
252 }
253 std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
254
255 v_ptr
256 }
257 }
258 }
259
260 impl<'a> $crate::glib::translate::ToGlibContainerFromSlice<'a, *const *mut $ffi_name>
261 for $name
262 {
263 #[allow(clippy::type_complexity)]
264 type Storage = (
265 std::marker::PhantomData<&'a [$name]>,
266 Option<Vec<*mut $ffi_name>>,
267 );
268
269 fn to_glib_none_from_slice(t: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) {
270 skip_assert_initialized!();
271 let (ptr, stash) =
272 $crate::glib::translate::ToGlibContainerFromSlice::<'a, *mut *mut $ffi_name>::to_glib_none_from_slice(t);
273 (ptr as *const *mut $ffi_name, stash)
274 }
275
276 fn to_glib_container_from_slice(_: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) {
277 skip_assert_initialized!();
278 // Can't have consumer free a *const pointer
279 unimplemented!()
280 }
281
282 fn to_glib_full_from_slice(_: &[$name]) -> *const *mut $ffi_name {
283 skip_assert_initialized!();
284 // Can't have consumer free a *const pointer
285 unimplemented!()
286 }
287 }
288
289 impl $crate::glib::translate::FromGlibPtrNone<*const $ffi_name> for $name {
290 #[inline]
291 unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self {
292 Self::from_glib_none(ptr)
293 }
294 }
295
296 impl $crate::glib::translate::FromGlibPtrNone<*mut $ffi_name> for $name {
297 #[inline]
298 unsafe fn from_glib_none(ptr: *mut $ffi_name) -> Self {
299 Self::from_glib_none(ptr)
300 }
301 }
302
303 impl $crate::glib::translate::FromGlibPtrFull<*const $ffi_name> for $name {
304 #[inline]
305 unsafe fn from_glib_full(ptr: *const $ffi_name) -> Self {
306 Self::from_glib_full(ptr)
307 }
308 }
309
310 impl $crate::glib::translate::FromGlibPtrFull<*mut $ffi_name> for $name {
311 #[inline]
312 unsafe fn from_glib_full(ptr: *mut $ffi_name) -> Self {
313 Self::from_glib_full(ptr)
314 }
315 }
316
317 impl $crate::glib::translate::FromGlibPtrBorrow<*const $ffi_name> for $name {
318 #[inline]
319 unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> $crate::glib::translate::Borrowed<Self> {
320 Self::from_glib_borrow(ptr)
321 }
322 }
323
324 impl $crate::glib::translate::FromGlibPtrBorrow<*mut $ffi_name> for $name {
325 #[inline]
326 unsafe fn from_glib_borrow(ptr: *mut $ffi_name) -> $crate::glib::translate::Borrowed<Self> {
327 Self::from_glib_borrow(ptr)
328 }
329 }
330
331 impl $crate::glib::translate::FromGlibContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name>
332 for $name
333 {
334 unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> {
335 if num == 0 || ptr.is_null() {
336 return Vec::new();
337 }
338
339 let mut res = Vec::<Self>::with_capacity(num);
340 let res_ptr = res.as_mut_ptr();
341 for i in 0..num {
342 ::std::ptr::write(res_ptr.add(i), $crate::glib::translate::from_glib_none(std::ptr::read(ptr.add(i))));
343 }
344 res.set_len(num);
345 res
346 }
347
348 unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> {
349 let res = $crate::glib::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num);
350 $crate::glib::ffi::g_free(ptr as *mut _);
351 res
352 }
353
354 unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> {
355 if num == 0 || ptr.is_null() {
356 return Vec::new();
357 }
358
359 let mut res = Vec::with_capacity(num);
360 let res_ptr = res.as_mut_ptr();
361 ::std::ptr::copy_nonoverlapping(ptr as *mut Self, res_ptr, num);
362 res.set_len(num);
363 $crate::glib::ffi::g_free(ptr as *mut _);
364 res
365 }
366 }
367
368 impl $crate::glib::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name>
369 for $name
370 {
371 unsafe fn from_glib_none_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> {
372 $crate::glib::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, glib::translate::c_ptr_array_len(ptr))
373 }
374
375 unsafe fn from_glib_container_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> {
376 $crate::glib::translate::FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, glib::translate::c_ptr_array_len(ptr))
377 }
378
379 unsafe fn from_glib_full_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> {
380 $crate::glib::translate::FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, glib::translate::c_ptr_array_len(ptr))
381 }
382 }
383
384 impl $crate::glib::translate::FromGlibContainerAsVec<*mut $ffi_name, *const *mut $ffi_name>
385 for $name
386 {
387 unsafe fn from_glib_none_num_as_vec(ptr: *const *mut $ffi_name, num: usize) -> Vec<Self> {
388 $crate::glib::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num)
389 }
390
391 unsafe fn from_glib_container_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> {
392 // Can't free a *const
393 unimplemented!()
394 }
395
396 unsafe fn from_glib_full_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> {
397 // Can't free a *const
398 unimplemented!()
399 }
400 }
401
402 impl $crate::glib::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name
403 {
404 unsafe fn from_glib_none_as_vec(ptr: *const *mut $ffi_name) -> Vec<Self> {
405 $crate::glib::translate::FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _)
406 }
407
408 unsafe fn from_glib_container_as_vec(_: *const *mut $ffi_name) -> Vec<Self> {
409 // Can't free a *const
410 unimplemented!()
411 }
412
413 unsafe fn from_glib_full_as_vec(_: *const *mut $ffi_name) -> Vec<Self> {
414 // Can't free a *const
415 unimplemented!()
416 }
417 }
418
419 impl $crate::glib::translate::GlibPtrDefault for $name {
420 type GlibType = *mut $ffi_name;
421 }
422
423 unsafe impl $crate::glib::translate::TransparentPtrType for $name {}
424
425 impl $ref_name {
426 #[inline]
427 pub fn as_ptr(&self) -> *const $ffi_name {
428 self as *const Self as *const $ffi_name
429 }
430
431 #[inline]
432 pub fn as_mut_ptr(&self) -> *mut $ffi_name {
433 self as *const Self as *mut $ffi_name
434 }
435
436 #[inline]
437 pub unsafe fn from_ptr<'a>(ptr: *const $ffi_name) -> &'a Self {
438 debug_assert!(!ptr.is_null());
439 &*(ptr as *const Self)
440 }
441
442 #[inline]
443 pub unsafe fn from_mut_ptr<'a>(ptr: *mut $ffi_name) -> &'a mut Self {
444 debug_assert!(!ptr.is_null());
445 debug_assert_ne!(
446 $crate::ffi::gst_mini_object_is_writable(ptr as *mut $crate::ffi::GstMiniObject),
447 $crate::glib::ffi::GFALSE
448 );
449 &mut *(ptr as *mut Self)
450 }
451
452 #[doc(alias = "gst_mini_object_copy")]
453 #[inline]
454 pub fn copy(&self) -> $name {
455 unsafe {
456 $name::from_glib_full($crate::ffi::gst_mini_object_copy(
457 self.as_ptr() as *const $crate::ffi::GstMiniObject
458 ) as *const $ffi_name)
459 }
460 }
461
462 #[inline]
463 pub fn upcast_ref(&self) -> &$crate::miniobject::MiniObjectRef {
464 unsafe {
465 &*(self.as_ptr() as *const $crate::miniobject::MiniObjectRef)
466 }
467 }
468
469 #[inline]
470 pub fn upcast_mut(&mut self) -> &mut $crate::miniobject::MiniObjectRef {
471 unsafe {
472 &mut *(self.as_mut_ptr() as *mut $crate::miniobject::MiniObjectRef)
473 }
474 }
475
476 #[inline]
477 pub fn ptr_eq(this: &$ref_name, other: &$ref_name) -> bool {
478 skip_assert_initialized!();
479 this.as_ptr() == other.as_ptr()
480 }
481 }
482
483 impl $crate::glib::translate::GlibPtrDefault for $ref_name {
484 type GlibType = *mut $ffi_name;
485 }
486
487 impl ToOwned for $ref_name {
488 type Owned = $name;
489
490 #[inline]
491 fn to_owned(&self) -> $name {
492 self.copy()
493 }
494 }
495
496 unsafe impl Sync for $ref_name {}
497 unsafe impl Send for $ref_name {}
498 unsafe impl Sync for $name {}
499 unsafe impl Send for $name {}
500 };
501 ($name:ident, $ref_name:ident, $ffi_name:path, $get_type:expr) => {
502 $crate::mini_object_wrapper!($name, $ref_name, $ffi_name);
503
504 impl $crate::glib::types::StaticType for $name {
505 #[inline]
506 fn static_type() -> $crate::glib::types::Type {
507 $ref_name::static_type()
508 }
509 }
510
511 #[allow(clippy::redundant_closure_call)]
512 impl $crate::glib::types::StaticType for $ref_name {
513 #[inline]
514 fn static_type() -> $crate::glib::types::Type {
515 unsafe { $crate::glib::translate::from_glib($get_type()) }
516 }
517 }
518
519 impl glib::value::ValueType for $name {
520 type Type = Self;
521 }
522
523 impl glib::value::ValueTypeOptional for $name { }
524
525 unsafe impl<'a> $crate::glib::value::FromValue<'a> for $name {
526 type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker<Self>;
527
528 #[inline]
529 unsafe fn from_value(value: &'a $crate::glib::Value) -> Self {
530 skip_assert_initialized!();
531 $crate::glib::translate::from_glib_none(
532 $crate::glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(value).0) as *mut $ffi_name
533 )
534 }
535 }
536
537 unsafe impl<'a> $crate::glib::value::FromValue<'a> for &'a $name {
538 type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker<Self>;
539
540 #[inline]
541 unsafe fn from_value(value: &'a $crate::glib::Value) -> Self {
542 skip_assert_initialized!();
543 assert_eq!(std::mem::size_of::<$name>(), std::mem::size_of::<$crate::glib::ffi::gpointer>());
544 let value = &*(value as *const $crate::glib::Value as *const $crate::glib::gobject_ffi::GValue);
545 let ptr = &value.data[0].v_pointer as *const $crate::glib::ffi::gpointer as *const *const $ffi_name;
546 debug_assert!(!(*ptr).is_null());
547 &*(ptr as *const $name)
548 }
549 }
550
551 impl $crate::glib::value::ToValue for $name {
552 #[inline]
553 fn to_value(&self) -> $crate::glib::Value {
554 let mut value = $crate::glib::Value::for_value_type::<Self>();
555 unsafe {
556 $crate::glib::gobject_ffi::g_value_set_boxed(
557 $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
558 $crate::glib::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(self).0 as *mut _,
559 )
560 }
561 value
562 }
563
564 #[inline]
565 fn value_type(&self) -> $crate::glib::Type {
566 <Self as $crate::glib::StaticType>::static_type()
567 }
568 }
569
570 impl $crate::glib::value::ToValueOptional for $name {
571 #[inline]
572 fn to_value_optional(s: Option<&Self>) -> $crate::glib::Value {
573 skip_assert_initialized!();
574 let mut value = $crate::glib::Value::for_value_type::<Self>();
575 unsafe {
576 $crate::glib::gobject_ffi::g_value_set_boxed(
577 $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
578 $crate::glib::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(&s).0 as *mut _,
579 )
580 }
581 value
582 }
583 }
584
585 impl From<$name> for $crate::glib::Value {
586 #[inline]
587 fn from(v: $name) -> $crate::glib::Value {
588 skip_assert_initialized!();
589 let mut value = $crate::glib::Value::for_value_type::<$name>();
590 unsafe {
591 $crate::glib::gobject_ffi::g_value_take_boxed(
592 $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
593 $crate::glib::translate::IntoGlibPtr::<*mut $ffi_name>::into_glib_ptr(v) as *mut _,
594 )
595 }
596 value
597 }
598 }
599
600 unsafe impl<'a> $crate::glib::value::FromValue<'a> for &'a $ref_name {
601 type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker<Self>;
602
603 #[inline]
604 unsafe fn from_value(value: &'a $crate::glib::Value) -> Self {
605 skip_assert_initialized!();
606 &*($crate::glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(value).0) as *const $ref_name)
607 }
608 }
609
610 // Can't have SetValue/SetValueOptional impls as otherwise one could use it to get
611 // immutable references from a mutable reference without borrowing via the value
612
613 impl $crate::glib::HasParamSpec for $name {
614 type ParamSpec = $crate::glib::ParamSpecBoxed;
615 type SetValue = Self;
616 type BuilderFn = fn(&str) -> $crate::glib::ParamSpecBoxedBuilder<Self>;
617
618 fn param_spec_builder() -> Self::BuilderFn {
619 |name| Self::ParamSpec::builder(name)
620 }
621 }
622 };
623);
624
625#[cfg(not(any(feature = "v1_20", docsrs)))]
626mini_object_wrapper!(MiniObject, MiniObjectRef, ffi::GstMiniObject);
627
628#[cfg(feature = "v1_20")]
629mini_object_wrapper!(MiniObject, MiniObjectRef, ffi::GstMiniObject, || {
630 ffi::gst_mini_object_get_type()
631});
632
633impl MiniObject {
634 #[inline]
635 pub fn downcast<T: IsMiniObject + glib::StaticType>(self) -> Result<T, Self> {
636 if self.type_().is_a(T::static_type()) {
637 unsafe { Ok(from_glib_full(self.into_glib_ptr() as *mut T::FfiType)) }
638 } else {
639 Err(self)
640 }
641 }
642}
643
644impl fmt::Debug for MiniObject {
645 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
646 self.as_ref().fmt(f)
647 }
648}
649
650impl fmt::Debug for MiniObjectRef {
651 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
652 f&mut DebugStruct<'_, '_>.debug_struct("MiniObject")
653 .field("ptr", &self.as_ptr())
654 .field(name:"type", &self.type_())
655 .finish()
656 }
657}
658
659impl MiniObjectRef {
660 #[inline]
661 pub fn type_(&self) -> glib::Type {
662 unsafe { from_glib((*self.as_ptr()).type_) }
663 }
664
665 #[inline]
666 pub fn downcast_ref<T: IsMiniObject + glib::StaticType>(&self) -> Option<&T::RefType> {
667 if self.type_().is_a(T::static_type()) {
668 unsafe { Some(&*(self as *const Self as *const T::RefType)) }
669 } else {
670 None
671 }
672 }
673
674 #[inline]
675 pub fn downcast_mut<T: IsMiniObject + glib::StaticType>(&mut self) -> Option<&mut T::RefType> {
676 if self.type_().is_a(T::static_type()) {
677 unsafe { Some(&mut *(self as *mut Self as *mut T::RefType)) }
678 } else {
679 None
680 }
681 }
682}
683