From 1b46bca2dbe68fb9122ba5b0839d7550b732d54f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 8 Jan 2022 21:39:31 +0200 Subject: [PATCH] structure: Add bindings for `foreach()`, map_in_place()` and `filter_map_in_place()` --- gstreamer/src/structure.rs | 91 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/gstreamer/src/structure.rs b/gstreamer/src/structure.rs index 787ba5a3d..668ee920f 100644 --- a/gstreamer/src/structure.rs +++ b/gstreamer/src/structure.rs @@ -685,6 +685,97 @@ impl StructureRef { pub fn serialize(&self, flags: crate::SerializeFlags) -> glib::GString { unsafe { from_glib_full(ffi::gst_structure_serialize(&self.0, flags.into_glib())) } } + + #[doc(alias = "gst_structure_foreach")] + pub fn foreach std::ops::ControlFlow<()>>( + &self, + mut func: F, + ) -> bool { + unsafe { + unsafe extern "C" fn trampoline< + F: FnMut(glib::Quark, &glib::Value) -> std::ops::ControlFlow<()>, + >( + quark: glib::ffi::GQuark, + value: *const glib::gobject_ffi::GValue, + user_data: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let func = &mut *(user_data as *mut F); + let res = func(from_glib(quark), &*(value as *const glib::Value)); + + matches!(res, std::ops::ControlFlow::Continue(_)).into_glib() + } + let func = &mut func as *mut F; + from_glib(ffi::gst_structure_foreach( + self.as_ptr(), + Some(trampoline::), + func as glib::ffi::gpointer, + )) + } + } + + #[doc(alias = "gst_structure_map_in_place")] + pub fn map_in_place std::ops::ControlFlow<()>>( + &mut self, + mut func: F, + ) -> bool { + unsafe { + unsafe extern "C" fn trampoline< + F: FnMut(glib::Quark, &mut glib::Value) -> std::ops::ControlFlow<()>, + >( + quark: glib::ffi::GQuark, + value: *mut glib::gobject_ffi::GValue, + user_data: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let func = &mut *(user_data as *mut F); + let res = func(from_glib(quark), &mut *(value as *mut glib::Value)); + + matches!(res, std::ops::ControlFlow::Continue(_)).into_glib() + } + let func = &mut func as *mut F; + from_glib(ffi::gst_structure_map_in_place( + self.as_mut_ptr(), + Some(trampoline::), + func as glib::ffi::gpointer, + )) + } + } + + #[doc(alias = "gst_structure_filter_and_map_in_place")] + pub fn filter_map_in_place Option>( + &mut self, + mut func: F, + ) { + unsafe { + unsafe extern "C" fn trampoline< + F: FnMut(glib::Quark, glib::Value) -> Option, + >( + quark: glib::ffi::GQuark, + value: *mut glib::gobject_ffi::GValue, + user_data: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let func = &mut *(user_data as *mut F); + + let v = mem::replace( + &mut *(value as *mut glib::Value), + glib::Value::uninitialized(), + ); + match func(from_glib(quark), v) { + None => glib::ffi::GFALSE, + Some(v) => { + *value = v.into_raw(); + glib::ffi::GTRUE + } + } + } + + let func = &mut func as *mut F; + ffi::gst_structure_filter_and_map_in_place( + self.as_mut_ptr(), + Some(trampoline::), + func as glib::ffi::gpointer, + ); + } + } } impl fmt::Display for StructureRef {