Add various glib::Value trait impls for borrowed versions of types

For SDPMessageRef, StructureRef and CapsFeatureRef this involves the
conversion from and to a glib::Value. Specifically this means that e.g.
a StructureRef can be retrieved from a glib::Value via borrowing, i.e.
without creating a copy of the structure first.

For all mini objects only retrieval from a glib::Value is implemented as
the other direction would allow to get multiple immutable references
from a mutable reference without borrowing, which is not allowed and
would make it possible to observe a mini object changing while having an
immutable reference to it.
This commit is contained in:
Sebastian Dröge 2020-05-27 13:07:32 +03:00
parent c2acb000b1
commit d21953ba66
4 changed files with 143 additions and 20 deletions

View file

@ -928,6 +928,45 @@ impl ToOwned for SDPMessageRef {
}
}
impl glib::types::StaticType for SDPMessageRef {
fn static_type() -> glib::types::Type {
unsafe { from_glib(gst_sdp_sys::gst_sdp_message_get_type()) }
}
}
impl<'a> glib::value::FromValueOptional<'a> for &'a SDPMessageRef {
unsafe fn from_value_optional(v: &'a glib::Value) -> Option<Self> {
let ptr = gobject_sys::g_value_get_boxed(v.to_glib_none().0);
if ptr.is_null() {
None
} else {
Some(&*(ptr as *const SDPMessageRef))
}
}
}
impl glib::value::SetValue for SDPMessageRef {
unsafe fn set_value(v: &mut glib::Value, s: &Self) {
gobject_sys::g_value_set_boxed(
v.to_glib_none_mut().0,
s as *const SDPMessageRef as glib_sys::gpointer,
);
}
}
impl glib::value::SetValueOptional for SDPMessageRef {
unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) {
if let Some(s) = s {
gobject_sys::g_value_set_boxed(
v.to_glib_none_mut().0,
s as *const SDPMessageRef as glib_sys::gpointer,
);
} else {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut());
}
}
}
macro_rules! define_iter(
($name:ident, $typ:ty, $get_item:expr, $get_len:expr) => {
#[derive(Debug)]

View file

@ -17,8 +17,8 @@ use std::str;
use glib;
use glib::translate::{
from_glib, from_glib_full, from_glib_none, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault,
Stash, StashMut, ToGlibPtr, ToGlibPtrMut,
from_glib, from_glib_full, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault, Stash, StashMut,
ToGlibPtr, ToGlibPtrMut,
};
use glib_sys::gpointer;
use gobject_sys;
@ -246,24 +246,23 @@ impl FromGlibPtrFull<*mut gst_sys::GstCapsFeatures> for CapsFeatures {
impl<'a> glib::value::FromValueOptional<'a> for CapsFeatures {
unsafe fn from_value_optional(v: &'a glib::Value) -> Option<Self> {
let ptr = gobject_sys::g_value_get_boxed(v.to_glib_none().0);
from_glib_none(ptr as *const gst_sys::GstCapsFeatures)
<&'a CapsFeaturesRef as glib::value::FromValueOptional<'a>>::from_value_optional(v)
.map(ToOwned::to_owned)
}
}
impl glib::value::SetValue for CapsFeatures {
unsafe fn set_value(v: &mut glib::Value, s: &Self) {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.0.as_ptr() as gpointer);
<CapsFeaturesRef as glib::value::SetValue>::set_value(v, s.as_ref())
}
}
impl glib::value::SetValueOptional for CapsFeatures {
unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) {
if let Some(s) = s {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer);
} else {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut());
}
<CapsFeaturesRef as glib::value::SetValueOptional>::set_value_optional(
v,
s.map(|s| s.as_ref()),
)
}
}
@ -358,6 +357,41 @@ impl CapsFeaturesRef {
}
}
impl glib::types::StaticType for CapsFeaturesRef {
fn static_type() -> glib::types::Type {
unsafe { from_glib(gst_sys::gst_structure_get_type()) }
}
}
impl<'a> glib::value::FromValueOptional<'a> for &'a CapsFeaturesRef {
unsafe fn from_value_optional(v: &'a glib::Value) -> Option<Self> {
let ptr = gobject_sys::g_value_get_boxed(v.to_glib_none().0);
if ptr.is_null() {
None
} else {
Some(CapsFeaturesRef::from_glib_borrow(
ptr as *const gst_sys::GstCapsFeatures,
))
}
}
}
impl glib::value::SetValue for CapsFeaturesRef {
unsafe fn set_value(v: &mut glib::Value, s: &Self) {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer);
}
}
impl glib::value::SetValueOptional for CapsFeaturesRef {
unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) {
if let Some(s) = s {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer);
} else {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut());
}
}
}
#[derive(Debug)]
pub struct Iter<'a> {
caps_features: &'a CapsFeaturesRef,

View file

@ -851,6 +851,22 @@ macro_rules! gst_define_mini_object_wrapper(
}
}
impl<'a> $crate::glib::value::FromValueOptional<'a>
for &'a $ref_name
{
unsafe fn from_value_optional(v: &'a glib::Value) -> Option<Self> {
let ptr = gobject_sys::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(v).0);
if ptr.is_null() {
None
} else {
Some(&*(ptr as *const $ref_name))
}
}
}
// Can't have SetValue/SetValueOptional impls as otherwise one could use it to get
// immutable references from a mutable reference without borrowing via the value
impl ToOwned for $ref_name {
type Owned = $name;

View file

@ -20,8 +20,8 @@ use Fraction;
use glib;
use glib::translate::{
from_glib, from_glib_full, from_glib_none, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault,
Stash, StashMut, ToGlib, ToGlibPtr, ToGlibPtrMut,
from_glib, from_glib_full, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault, Stash, StashMut,
ToGlib, ToGlibPtr, ToGlibPtrMut,
};
use glib::value::{FromValue, FromValueOptional, SendValue, ToSendValue};
use glib_sys::gpointer;
@ -334,24 +334,23 @@ impl FromGlibPtrFull<*mut gst_sys::GstStructure> for Structure {
impl<'a> glib::value::FromValueOptional<'a> for Structure {
unsafe fn from_value_optional(v: &'a glib::Value) -> Option<Self> {
let ptr = gobject_sys::g_value_get_boxed(v.to_glib_none().0);
from_glib_none(ptr as *const gst_sys::GstStructure)
<&'a StructureRef as glib::value::FromValueOptional<'a>>::from_value_optional(v)
.map(ToOwned::to_owned)
}
}
impl glib::value::SetValue for Structure {
unsafe fn set_value(v: &mut glib::Value, s: &Self) {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.0.as_ptr() as gpointer);
<StructureRef as glib::value::SetValue>::set_value(v, s.as_ref())
}
}
impl glib::value::SetValueOptional for Structure {
unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) {
if let Some(s) = s {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer);
} else {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut());
}
<StructureRef as glib::value::SetValueOptional>::set_value_optional(
v,
s.map(|s| s.as_ref()),
)
}
}
@ -624,6 +623,41 @@ impl PartialEq for StructureRef {
impl Eq for StructureRef {}
impl glib::types::StaticType for StructureRef {
fn static_type() -> glib::types::Type {
unsafe { from_glib(gst_sys::gst_structure_get_type()) }
}
}
impl<'a> glib::value::FromValueOptional<'a> for &'a StructureRef {
unsafe fn from_value_optional(v: &'a glib::Value) -> Option<Self> {
let ptr = gobject_sys::g_value_get_boxed(v.to_glib_none().0);
if ptr.is_null() {
None
} else {
Some(StructureRef::from_glib_borrow(
ptr as *const gst_sys::GstStructure,
))
}
}
}
impl glib::value::SetValue for StructureRef {
unsafe fn set_value(v: &mut glib::Value, s: &Self) {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer);
}
}
impl glib::value::SetValueOptional for StructureRef {
unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) {
if let Some(s) = s {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer);
} else {
gobject_sys::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut());
}
}
}
#[derive(Debug)]
pub struct FieldIterator<'a> {
structure: &'a StructureRef,