From e9d95eda592b999791d26139f067c3fe14fc5edb Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Tue, 23 Aug 2022 22:07:10 -0400 Subject: [PATCH] gstreamer: Add extension trait to mark API as plugins API This adds an extension trait implemented for GType so we can add and check plugins API status. Required so we can document plugins written in rust. --- gstreamer/Gir.toml | 2 +- gstreamer/src/functions.rs | 22 --------- gstreamer/src/gtype.rs | 93 ++++++++++++++++++++++++++++++++++++++ gstreamer/src/lib.rs | 5 ++ 4 files changed, 99 insertions(+), 23 deletions(-) create mode 100644 gstreamer/src/gtype.rs diff --git a/gstreamer/Gir.toml b/gstreamer/Gir.toml index c66cb1a2c..ee8b77aa5 100644 --- a/gstreamer/Gir.toml +++ b/gstreamer/Gir.toml @@ -372,7 +372,7 @@ status = "generate" [[object.function]] name = "type_is_plugin_api" - # confusing return type + # We implement it in an extension Trait ignore = true [[object.function]] diff --git a/gstreamer/src/functions.rs b/gstreamer/src/functions.rs index 766e214f8..3c10ff069 100644 --- a/gstreamer/src/functions.rs +++ b/gstreamer/src/functions.rs @@ -169,28 +169,6 @@ pub fn calculate_linear_regression( } } -#[cfg(any(feature = "v1_18", feature = "dox"))] -#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] -#[doc(alias = "gst_type_is_plugin_api")] -pub fn type_is_plugin_api(type_: glib::types::Type) -> Option { - assert_initialized_main_thread!(); - unsafe { - use std::mem; - - let mut flags = mem::MaybeUninit::uninit(); - let ret = from_glib(ffi::gst_type_is_plugin_api( - type_.into_glib(), - flags.as_mut_ptr(), - )); - let flags = flags.assume_init(); - if ret { - Some(from_glib(flags)) - } else { - None - } - } -} - #[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] #[doc(alias = "gst_tracing_get_active_tracers")] diff --git a/gstreamer/src/gtype.rs b/gstreamer/src/gtype.rs new file mode 100644 index 000000000..7c22c0f17 --- /dev/null +++ b/gstreamer/src/gtype.rs @@ -0,0 +1,93 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::translate::*; +use std::ffi::c_void; + +pub trait PluginApiExt { + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + #[doc(alias = "gst_type_mark_as_plugin_api")] + fn mark_as_plugin_api(self, flags: crate::PluginAPIFlags); + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + #[doc(alias = "gst_type_is_plugin_api")] + fn plugin_api_flags(self) -> Option; + #[doc(alias = "gst_element_type_set_skip_documentation")] + fn set_skip_documentation(self); + #[doc(alias = "gst_element_factory_get_skip_documentation")] + fn skip_documentation(self) -> bool; +} + +impl PluginApiExt for glib::Type { + fn set_skip_documentation(self) { + let quark = glib::Quark::from_str("GST_ELEMENTCLASS_SKIP_DOCUMENTATION"); + unsafe { + crate::glib::gobject_ffi::g_type_set_qdata( + self.into_glib(), + quark.into_glib(), + 1 as *mut c_void, + ); + } + } + + fn skip_documentation(self) -> bool { + let quark = glib::Quark::from_str("GST_ELEMENTCLASS_SKIP_DOCUMENTATION"); + unsafe { + !crate::glib::gobject_ffi::g_type_get_qdata(self.into_glib(), quark.into_glib()) + .is_null() + } + } + + fn plugin_api_flags(self) -> Option { + assert_initialized_main_thread!(); + unsafe { + use std::mem; + + let mut flags = mem::MaybeUninit::uninit(); + let ret = from_glib(ffi::gst_type_is_plugin_api( + self.into_glib(), + flags.as_mut_ptr(), + )); + let flags = flags.assume_init(); + if ret { + Some(from_glib(flags)) + } else { + None + } + } + } + + fn mark_as_plugin_api(self, flags: crate::PluginAPIFlags) { + assert_initialized_main_thread!(); + + unsafe { ffi::gst_type_mark_as_plugin_api(self.into_glib(), flags.into_glib()) } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use glib::StaticType; + + #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, glib::Enum)] + #[repr(u32)] + #[enum_type(name = "GstTestEnum")] + pub enum TestEnum { + #[enum_value(name = "test", nick = "test")] + Test, + } + + #[test] + fn test_gtype_mark_as_api() { + crate::init().unwrap(); + + assert!(TestEnum::static_type().plugin_api_flags().is_none()); + assert!(!TestEnum::static_type().skip_documentation()); + + TestEnum::static_type().mark_as_plugin_api(crate::PluginAPIFlags::empty()); + TestEnum::static_type().set_skip_documentation(); + + assert!( + TestEnum::static_type().plugin_api_flags().unwrap() == crate::PluginAPIFlags::empty() + ); + assert!(TestEnum::static_type().skip_documentation()); + } +} diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index 6322c87aa..10c2a8666 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -261,6 +261,9 @@ pub use crate::functions::*; mod utils; +#[cfg(any(feature = "v1_18", feature = "dox"))] +mod gtype; + use std::ptr; #[doc(alias = "gst_init_check")] @@ -326,6 +329,8 @@ pub mod prelude { pub use crate::device_provider::DeviceProviderExtManual; pub use crate::element::{ElementClassExt, ElementExtManual}; pub use crate::gobject::GObjectExtManualGst; + #[cfg(any(feature = "v1_18", feature = "dox"))] + pub use crate::gtype::PluginApiExt; pub use crate::message::MessageErrorDomain; pub use crate::object::GstObjectExtManual; pub use crate::pad::PadExtManual;