Implement ValueRef and TypedValueRef for wrapping around a unowned GValue pointer without copying

Also rename new_from*() functions to from*() for consistency.
This commit is contained in:
Sebastian Dröge 2017-04-19 11:58:51 +01:00
parent 2d97baaf96
commit 1bf20bfea4
7 changed files with 266 additions and 123 deletions

View file

@ -63,14 +63,14 @@ unsafe impl MiniObject for Buffer {
self.0 = ptr
}
unsafe fn new_from_ptr(ptr: *mut gst::GstBuffer) -> Self {
unsafe fn from_ptr(ptr: *mut gst::GstBuffer) -> Self {
Buffer(ptr)
}
}
impl Buffer {
pub fn new() -> GstRc<Buffer> {
unsafe { GstRc::new_from_owned_ptr(gst::gst_buffer_new()) }
unsafe { GstRc::from_owned_ptr(gst::gst_buffer_new()) }
}
pub fn new_with_size(size: usize) -> Option<GstRc<Buffer>> {
@ -78,7 +78,7 @@ impl Buffer {
if raw.is_null() {
None
} else {
Some(unsafe { GstRc::new_from_owned_ptr(raw) })
Some(unsafe { GstRc::from_owned_ptr(raw) })
}
}
@ -87,7 +87,7 @@ impl Buffer {
drop(vec);
}
pub fn new_from_vec(vec: Vec<u8>) -> Option<GstRc<Buffer>> {
pub fn from_vec(vec: Vec<u8>) -> Option<GstRc<Buffer>> {
let raw = unsafe {
let mut vec = Box::new(vec);
let maxsize = vec.capacity();
@ -106,7 +106,7 @@ impl Buffer {
if raw.is_null() {
None
} else {
Some(unsafe { GstRc::new_from_owned_ptr(raw) })
Some(unsafe { GstRc::from_owned_ptr(raw) })
}
}
@ -164,10 +164,8 @@ impl Buffer {
pub fn append(buffer: GstRc<Buffer>, other: GstRc<Buffer>) -> GstRc<Buffer> {
unsafe {
GstRc::new_from_owned_ptr(gst::gst_buffer_append(buffer.into_ptr() as
*mut gst::GstBuffer,
other.into_ptr() as
*mut gst::GstBuffer))
GstRc::from_owned_ptr(gst::gst_buffer_append(buffer.into_ptr() as *mut gst::GstBuffer,
other.into_ptr() as *mut gst::GstBuffer))
}
}
@ -181,7 +179,7 @@ impl Buffer {
if raw.is_null() {
None
} else {
Some(unsafe { GstRc::new_from_owned_ptr(raw) })
Some(unsafe { GstRc::from_owned_ptr(raw) })
}
}
@ -514,7 +512,7 @@ mod tests {
fn test_writability() {
init();
let mut buffer = Buffer::new_from_vec(vec![1, 2, 3, 4]).unwrap();
let mut buffer = Buffer::from_vec(vec![1, 2, 3, 4]).unwrap();
{
let data = buffer.map_read().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());

View file

@ -29,18 +29,18 @@ unsafe impl MiniObject for Caps {
self.0 = ptr
}
unsafe fn new_from_ptr(ptr: *mut gst::GstCaps) -> Self {
unsafe fn from_ptr(ptr: *mut gst::GstCaps) -> Self {
Caps(ptr)
}
}
impl Caps {
pub fn new_empty() -> GstRc<Self> {
unsafe { GstRc::new_from_owned_ptr(gst::gst_caps_new_empty()) }
unsafe { GstRc::from_owned_ptr(gst::gst_caps_new_empty()) }
}
pub fn new_any() -> GstRc<Self> {
unsafe { GstRc::new_from_owned_ptr(gst::gst_caps_new_any()) }
unsafe { GstRc::from_owned_ptr(gst::gst_caps_new_any()) }
}
pub fn new_simple(name: &str, values: &[(&str, &Value)]) -> GstRc<Self> {
@ -67,7 +67,7 @@ impl Caps {
if caps_ptr.is_null() {
None
} else {
Some(GstRc::new_from_owned_ptr(caps_ptr))
Some(GstRc::from_owned_ptr(caps_ptr))
}
}
}

View file

@ -487,7 +487,7 @@ pub unsafe extern "C" fn demuxer_handle_buffer(ptr: *mut DemuxerWrapper,
let wrap: &mut DemuxerWrapper = &mut *ptr;
panic_to_error!(wrap, gst::GST_FLOW_ERROR, {
let buffer = GstRc::new_from_owned_ptr(buffer);
let buffer = GstRc::from_owned_ptr(buffer);
wrap.handle_buffer(buffer)
})
}

View file

@ -28,12 +28,12 @@ impl<T: MiniObject> GstRc<T> {
GstRc { obj: obj }
}
pub unsafe fn new_from_owned_ptr(ptr: *mut T::PtrType) -> Self {
Self::new(T::new_from_ptr(ptr), true)
pub unsafe fn from_owned_ptr(ptr: *mut T::PtrType) -> Self {
Self::new(T::from_ptr(ptr), true)
}
pub unsafe fn new_from_unowned_ptr(ptr: *mut T::PtrType) -> Self {
Self::new(T::new_from_ptr(ptr), false)
pub unsafe fn from_unowned_ptr(ptr: *mut T::PtrType) -> Self {
Self::new(T::from_ptr(ptr), false)
}
pub fn make_mut(&mut self) -> &mut T {
@ -63,9 +63,9 @@ impl<T: MiniObject> GstRc<T> {
pub fn copy(&self) -> Self {
unsafe {
GstRc::new_from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
*const gst::GstMiniObject) as
*mut T::PtrType)
GstRc::from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
*const gst::GstMiniObject) as
*mut T::PtrType)
}
}
@ -101,7 +101,7 @@ impl<T: MiniObject> borrow::Borrow<T> for GstRc<T> {
impl<T: MiniObject> Clone for GstRc<T> {
fn clone(&self) -> GstRc<T> {
unsafe { GstRc::new_from_unowned_ptr(self.obj.as_ptr()) }
unsafe { GstRc::from_unowned_ptr(self.obj.as_ptr()) }
}
}
@ -137,18 +137,18 @@ pub unsafe trait MiniObject {
ptr
}
unsafe fn new_from_ptr(ptr: *mut Self::PtrType) -> Self;
unsafe fn from_ptr(ptr: *mut Self::PtrType) -> Self;
}
impl<'a, T: MiniObject> From<&'a T> for GstRc<T> {
fn from(f: &'a T) -> GstRc<T> {
unsafe { GstRc::new_from_unowned_ptr(f.as_ptr()) }
unsafe { GstRc::from_unowned_ptr(f.as_ptr()) }
}
}
impl<'a, T: MiniObject> From<&'a mut T> for GstRc<T> {
fn from(f: &'a mut T) -> GstRc<T> {
unsafe { GstRc::new_from_unowned_ptr(f.as_ptr()) }
unsafe { GstRc::from_unowned_ptr(f.as_ptr()) }
}
}
@ -162,7 +162,7 @@ pub struct GstRef<'a, T: 'a + MiniObject> {
impl<'a, T: MiniObject> GstRef<'a, T> {
pub unsafe fn new(ptr: *mut T::PtrType) -> GstRef<'a, T> {
GstRef {
obj: T::new_from_ptr(ptr),
obj: T::from_ptr(ptr),
phantom: PhantomData,
}
}
@ -177,9 +177,9 @@ impl<'a, T: MiniObject> GstRef<'a, T> {
pub fn copy(&self) -> GstRc<T> {
unsafe {
GstRc::new_from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
*const gst::GstMiniObject) as
*mut T::PtrType)
GstRc::from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
*const gst::GstMiniObject) as
*mut T::PtrType)
}
}

View file

@ -67,7 +67,7 @@ impl Stream {
return None;
}
Some(unsafe { GstRc::new_from_owned_ptr(ptr) })
Some(unsafe { GstRc::from_owned_ptr(ptr) })
}
pub fn get_stream_flags(&self) -> StreamFlags {
@ -90,7 +90,7 @@ impl Stream {
return None;
}
Some(unsafe { TagList::new_from_ptr(ptr) })
Some(unsafe { TagList::from_ptr(ptr) })
}
pub fn set_caps(&self, caps: Option<GstRc<Caps>>) {

View file

@ -82,14 +82,14 @@ unsafe impl MiniObject for TagList {
self.0 = ptr
}
unsafe fn new_from_ptr(ptr: *mut gst::GstTagList) -> Self {
unsafe fn from_ptr(ptr: *mut gst::GstTagList) -> Self {
TagList(ptr)
}
}
impl TagList {
pub fn new() -> GstRc<Self> {
unsafe { GstRc::new_from_owned_ptr(gst::gst_tag_list_new_empty()) }
unsafe { GstRc::from_owned_ptr(gst::gst_tag_list_new_empty()) }
}
pub fn add<'a, T: Tag<'a>>(&mut self, value: T::TagType, mode: MergeMode)
@ -128,6 +128,27 @@ impl TagList {
}
}
pub fn get_index<'a, T: Tag<'a>>(&'a self, idx: u32) -> Option<TypedValueRef<'a, T::TagType>>
where Value: From<<T as Tag<'a>>::TagType>
{
unsafe {
let tag_name = CString::new(T::tag_name()).unwrap();
let value = gst::gst_tag_list_get_value_index(self.0, tag_name.as_ptr(), idx);
if value.is_null() {
return None;
}
let res = match ValueRef::from_ptr(value) {
Some(value) => TypedValueRef::from_value_ref(value),
None => None,
};
res
}
}
pub fn to_string(&self) -> String {
unsafe {
let ptr = gst::gst_tag_list_to_string(self.0);
@ -195,5 +216,8 @@ mod tests {
assert_eq!(tags.get::<Title>().unwrap().get(), "some title");
assert_eq!(tags.get::<Duration>().unwrap().get(),
(1000u64 * 1000 * 1000 * 120));
assert_eq!(tags.get_index::<Title>(0).unwrap().get(), "some title");
assert_eq!(tags.get_index::<Duration>(0).unwrap().get(),
(1000u64 * 1000 * 1000 * 120));
}
}

View file

@ -27,7 +27,7 @@ use gst;
pub struct Value(gobject::GValue);
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ValueRef<'a> {
pub enum ValueView<'a> {
Bool(bool),
Int(i32),
UInt(u32),
@ -39,9 +39,9 @@ pub enum ValueRef<'a> {
Array(Cow<'a, [Value]>),
}
impl<'a> ValueRef<'a> {
impl<'a> ValueView<'a> {
pub fn try_get<T: ValueType<'a>>(&'a self) -> Option<T> {
T::from_value_ref(&self)
T::from_value_view(&self)
}
}
@ -50,8 +50,8 @@ pub trait ValueType<'a>
{
fn g_type() -> glib::GType;
fn from_value(v: &'a Value) -> Option<Self>;
fn from_value_ref(v: &'a ValueRef<'a>) -> Option<Self>;
fn from_value(v: &'a gobject::GValue) -> Option<Self>;
fn from_value_view(v: &'a ValueView<'a>) -> Option<Self>;
}
lazy_static! {
@ -77,6 +77,10 @@ impl Value {
Some(value)
}
pub fn from_value_ref<'a>(v: &ValueRef<'a>) -> Value {
unsafe { Value::from_ptr(v.0) }.unwrap()
}
pub unsafe fn from_raw(value: gobject::GValue) -> Option<Value> {
if !Value::is_supported_type(value.g_type) {
return None;
@ -107,45 +111,46 @@ impl Value {
v.into()
}
pub fn new_from_value_ref(v: ValueRef) -> Value {
pub fn from_value_view(v: ValueView) -> Value {
match v {
ValueRef::Bool(v) => Value::from(v),
ValueRef::Int(v) => Value::from(v),
ValueRef::UInt(v) => Value::from(v),
ValueRef::Int64(v) => Value::from(v),
ValueRef::UInt64(v) => Value::from(v),
ValueRef::Fraction(v) => Value::from(v),
ValueRef::String(v) => Value::from(v),
ValueRef::Array(v) => Value::from(v),
ValueRef::Buffer(v) => Value::from(v),
ValueView::Bool(v) => Value::from(v),
ValueView::Int(v) => Value::from(v),
ValueView::UInt(v) => Value::from(v),
ValueView::Int64(v) => Value::from(v),
ValueView::UInt64(v) => Value::from(v),
ValueView::Fraction(v) => Value::from(v),
ValueView::String(v) => Value::from(v),
ValueView::Array(v) => Value::from(v),
ValueView::Buffer(v) => Value::from(v),
}
}
pub fn get(&self) -> ValueRef {
pub fn get(&self) -> ValueView {
match self.0.g_type {
gobject::G_TYPE_BOOLEAN => ValueRef::Bool(bool::from_value(&self).unwrap()),
gobject::G_TYPE_INT => ValueRef::Int(i32::from_value(&self).unwrap()),
gobject::G_TYPE_UINT => ValueRef::UInt(u32::from_value(&self).unwrap()),
gobject::G_TYPE_INT64 => ValueRef::Int64(i64::from_value(&self).unwrap()),
gobject::G_TYPE_UINT64 => ValueRef::UInt64(u64::from_value(&self).unwrap()),
gobject::G_TYPE_BOOLEAN => ValueView::Bool(bool::from_value(&self.0).unwrap()),
gobject::G_TYPE_INT => ValueView::Int(i32::from_value(&self.0).unwrap()),
gobject::G_TYPE_UINT => ValueView::UInt(u32::from_value(&self.0).unwrap()),
gobject::G_TYPE_INT64 => ValueView::Int64(i64::from_value(&self.0).unwrap()),
gobject::G_TYPE_UINT64 => ValueView::UInt64(u64::from_value(&self.0).unwrap()),
typ if typ == *TYPE_FRACTION => {
ValueRef::Fraction(Rational32::from_value(&self).unwrap())
ValueView::Fraction(Rational32::from_value(&self.0).unwrap())
}
gobject::G_TYPE_STRING => {
ValueRef::String(Cow::Borrowed(<&str as ValueType>::from_value(&self).unwrap()))
ValueView::String(Cow::Borrowed(<&str as ValueType>::from_value(&self.0).unwrap()))
}
typ if typ == *TYPE_GST_VALUE_ARRAY => {
ValueRef::Array(Cow::Borrowed(<&[Value] as ValueType>::from_value(&self).unwrap()))
ValueView::Array(Cow::Borrowed(<&[Value] as ValueType>::from_value(&self.0)
.unwrap()))
}
typ if typ == *TYPE_BUFFER => {
ValueRef::Buffer(<GstRc<Buffer> as ValueType>::from_value(&self).unwrap())
ValueView::Buffer(<GstRc<Buffer> as ValueType>::from_value(&self.0).unwrap())
}
_ => unreachable!(),
}
}
pub fn try_get<'a, T: ValueType<'a>>(&'a self) -> Option<T> {
T::from_value(self)
T::from_value(&self.0)
}
}
@ -184,6 +189,68 @@ impl Drop for Value {
}
}
#[derive(Clone)]
pub struct ValueRef<'a>(&'a gobject::GValue);
impl<'a> ValueRef<'a> {
pub unsafe fn as_ptr(&self) -> *const gobject::GValue {
self.0
}
pub fn from_value(v: &'a Value) -> ValueRef<'a> {
ValueRef(&v.0)
}
pub unsafe fn from_ptr(ptr: *const gobject::GValue) -> Option<ValueRef<'a>> {
if ptr.is_null() || !Value::is_supported_type((*ptr).g_type) {
return None;
}
Some(ValueRef(&*ptr))
}
pub fn get(&self) -> ValueView {
match self.0.g_type {
gobject::G_TYPE_BOOLEAN => ValueView::Bool(bool::from_value(self.0).unwrap()),
gobject::G_TYPE_INT => ValueView::Int(i32::from_value(self.0).unwrap()),
gobject::G_TYPE_UINT => ValueView::UInt(u32::from_value(self.0).unwrap()),
gobject::G_TYPE_INT64 => ValueView::Int64(i64::from_value(self.0).unwrap()),
gobject::G_TYPE_UINT64 => ValueView::UInt64(u64::from_value(self.0).unwrap()),
typ if typ == *TYPE_FRACTION => {
ValueView::Fraction(Rational32::from_value(&self.0).unwrap())
}
gobject::G_TYPE_STRING => {
ValueView::String(Cow::Borrowed(<&str as ValueType>::from_value(self.0).unwrap()))
}
typ if typ == *TYPE_GST_VALUE_ARRAY => {
ValueView::Array(Cow::Borrowed(<&[Value] as ValueType>::from_value(self.0)
.unwrap()))
}
typ if typ == *TYPE_BUFFER => {
ValueView::Buffer(<GstRc<Buffer> as ValueType>::from_value(self.0).unwrap())
}
_ => unreachable!(),
}
}
pub fn try_get<T: ValueType<'a>>(&self) -> Option<T> {
T::from_value(self.0)
}
}
impl<'a> PartialEq for ValueRef<'a> {
fn eq(&self, other: &ValueRef<'a>) -> bool {
self.get().eq(&other.get())
}
}
impl<'a> Eq for ValueRef<'a> {}
impl<'a> fmt::Debug for ValueRef<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.get().fmt(f)
}
}
macro_rules! impl_value_type_simple(
($typ:ty, $variant:ident, $g_type:expr, $getter:expr, $setter:expr) => {
impl<'a> ValueType<'a> for $typ {
@ -191,18 +258,18 @@ macro_rules! impl_value_type_simple(
$g_type
}
fn from_value(value: &'a Value) -> Option<Self> {
if value.0.g_type != Self::g_type() {
fn from_value(value: &'a gobject::GValue) -> Option<Self> {
if value.g_type != Self::g_type() {
return None;
}
unsafe {
Some($getter(value))
Some($getter(&value))
}
}
fn from_value_ref(value_ref: &'a ValueRef<'a>) -> Option<Self> {
if let ValueRef::$variant(ref v) = *value_ref {
fn from_value_view(value_view: &'a ValueView<'a>) -> Option<Self> {
if let ValueView::$variant(ref v) = *value_view {
Some(*v)
} else {
None
@ -216,7 +283,7 @@ macro_rules! impl_value_type_simple(
let mut value = Value(mem::zeroed());
gobject::g_value_init(&mut value.0, <$typ as ValueType>::g_type());
$setter(&mut value, v);
$setter(&mut value.0, v);
value
}
@ -228,40 +295,40 @@ macro_rules! impl_value_type_simple(
impl_value_type_simple!(bool,
Bool,
gobject::G_TYPE_BOOLEAN,
|value: &Value| !(gobject::g_value_get_boolean(&value.0) == 0),
|value: &mut Value, v| {
gobject::g_value_set_boolean(&mut value.0,
|value: &gobject::GValue| !(gobject::g_value_get_boolean(value) == 0),
|value: &mut gobject::GValue, v| {
gobject::g_value_set_boolean(value,
if v { glib::GTRUE } else { glib::GFALSE })
});
impl_value_type_simple!(i32,
Int,
gobject::G_TYPE_INT,
|value: &Value| gobject::g_value_get_int(&value.0),
|value: &mut Value, v| gobject::g_value_set_int(&mut value.0, v));
|value: &gobject::GValue| gobject::g_value_get_int(value),
|value: &mut gobject::GValue, v| gobject::g_value_set_int(value, v));
impl_value_type_simple!(u32,
UInt,
gobject::G_TYPE_UINT,
|value: &Value| gobject::g_value_get_uint(&value.0),
|value: &mut Value, v| gobject::g_value_set_uint(&mut value.0, v));
|value: &gobject::GValue| gobject::g_value_get_uint(value),
|value: &mut gobject::GValue, v| gobject::g_value_set_uint(value, v));
impl_value_type_simple!(i64,
Int64,
gobject::G_TYPE_INT64,
|value: &Value| gobject::g_value_get_int64(&value.0),
|value: &mut Value, v| gobject::g_value_set_int64(&mut value.0, v));
|value: &gobject::GValue| gobject::g_value_get_int64(value),
|value: &mut gobject::GValue, v| gobject::g_value_set_int64(value, v));
impl_value_type_simple!(u64,
UInt64,
gobject::G_TYPE_UINT64,
|value: &Value| gobject::g_value_get_uint64(&value.0),
|value: &mut Value, v| gobject::g_value_set_uint64(&mut value.0, v));
|value: &gobject::GValue| gobject::g_value_get_uint64(value),
|value: &mut gobject::GValue, v| gobject::g_value_set_uint64(value, v));
impl_value_type_simple!(Rational32,
Fraction,
*TYPE_FRACTION,
|value: &Value| {
Rational32::new(gst::gst_value_get_fraction_numerator(&value.0),
gst::gst_value_get_fraction_denominator(&value.0))
|value: &gobject::GValue| {
Rational32::new(gst::gst_value_get_fraction_numerator(value),
gst::gst_value_get_fraction_denominator(value))
},
|value: &mut Value, v: Rational32| {
gst::gst_value_set_fraction(&mut value.0, *v.numer(), *v.denom())
|value: &mut gobject::GValue, v: Rational32| {
gst::gst_value_set_fraction(value, *v.numer(), *v.denom())
});
impl<'a> ValueType<'a> for &'a str {
@ -269,13 +336,13 @@ impl<'a> ValueType<'a> for &'a str {
gobject::G_TYPE_STRING
}
fn from_value(value: &'a Value) -> Option<Self> {
if value.0.g_type != Self::g_type() {
fn from_value(value: &'a gobject::GValue) -> Option<Self> {
if value.g_type != Self::g_type() {
return None;
}
unsafe {
let s = gobject::g_value_get_string(&value.0);
let s = gobject::g_value_get_string(value);
if s.is_null() {
return Some(&"");
}
@ -285,8 +352,8 @@ impl<'a> ValueType<'a> for &'a str {
}
}
fn from_value_ref(value_ref: &'a ValueRef<'a>) -> Option<Self> {
if let ValueRef::String(ref v) = *value_ref {
fn from_value_view(value_view: &'a ValueView<'a>) -> Option<Self> {
if let ValueView::String(ref v) = *value_view {
Some(v.as_ref())
} else {
None
@ -325,19 +392,19 @@ impl<'a> ValueType<'a> for GstRc<Buffer> {
*TYPE_BUFFER
}
fn from_value(value: &'a Value) -> Option<Self> {
if value.0.g_type != Self::g_type() {
fn from_value(value: &'a gobject::GValue) -> Option<Self> {
if value.g_type != Self::g_type() {
return None;
}
unsafe {
let buffer = gobject::g_value_get_boxed(&value.0) as *mut gst::GstBuffer;
Some(GstRc::new_from_unowned_ptr(buffer))
let buffer = gobject::g_value_get_boxed(value) as *mut gst::GstBuffer;
Some(GstRc::from_unowned_ptr(buffer))
}
}
fn from_value_ref(value_ref: &'a ValueRef<'a>) -> Option<Self> {
if let ValueRef::Buffer(ref v) = *value_ref {
fn from_value_view(value_view: &'a ValueView<'a>) -> Option<Self> {
if let ValueView::Buffer(ref v) = *value_view {
Some(v.clone())
} else {
None
@ -375,13 +442,13 @@ impl<'a> ValueType<'a> for &'a [Value] {
*TYPE_GST_VALUE_ARRAY
}
fn from_value(value: &'a Value) -> Option<Self> {
if value.0.g_type != Self::g_type() {
fn from_value(value: &'a gobject::GValue) -> Option<Self> {
if value.g_type != Self::g_type() {
return None;
}
unsafe {
let arr = value.0.data[0] as *const glib::GArray;
let arr = value.data[0] as *const glib::GArray;
if arr.is_null() {
Some(&[])
@ -392,8 +459,8 @@ impl<'a> ValueType<'a> for &'a [Value] {
}
}
fn from_value_ref(value_ref: &'a ValueRef<'a>) -> Option<Self> {
if let ValueRef::Array(ref v) = *value_ref {
fn from_value_view(value_view: &'a ValueView<'a>) -> Option<Self> {
if let ValueView::Array(ref v) = *value_view {
Some(v.as_ref())
} else {
None
@ -448,15 +515,15 @@ impl<'a> From<&'a [Value]> for Value {
}
}
impl<'a> From<ValueRef<'a>> for Value {
fn from(value_ref: ValueRef<'a>) -> Value {
Value::new_from_value_ref(value_ref)
impl<'a> From<ValueView<'a>> for Value {
fn from(value_view: ValueView<'a>) -> Value {
Value::from_value_view(value_view)
}
}
impl<'a> From<&'a ValueRef<'a>> for Value {
fn from(value_ref: &'a ValueRef<'a>) -> Value {
Value::new_from_value_ref(value_ref.clone())
impl<'a> From<&'a ValueView<'a>> for Value {
fn from(value_view: &'a ValueView<'a>) -> Value {
Value::from_value_view(value_view.clone())
}
}
@ -490,6 +557,13 @@ impl<'a, T> TypedValue<T>
})
}
pub fn from_typed_value_ref(v: &'a TypedValueRef<'a, T>) -> TypedValue<T> {
TypedValue {
value: Value::from_value_ref(&v.value),
phantom: PhantomData,
}
}
pub fn get(&'a self) -> T {
self.value.try_get::<T>().unwrap()
}
@ -571,6 +645,53 @@ impl<'a> From<&'a Buffer> for TypedValue<GstRc<Buffer>> {
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TypedValueRef<'a, T> {
value: ValueRef<'a>,
phantom: PhantomData<T>,
}
impl<'a, T> TypedValueRef<'a, T>
where T: ValueType<'a>
{
pub fn from_typed_value(v: &'a TypedValue<T>) -> TypedValueRef<'a, T> {
TypedValueRef {
value: ValueRef::from_value(&v.value),
phantom: PhantomData,
}
}
pub fn from_value_ref(value: ValueRef<'a>) -> Option<TypedValueRef<'a, T>> {
if value.0.g_type != T::g_type() {
return None;
}
Some(TypedValueRef {
value: value,
phantom: PhantomData,
})
}
pub fn get(&'a self) -> T {
self.value.try_get::<T>().unwrap()
}
pub fn into_value(self) -> ValueRef<'a> {
self.value
}
pub unsafe fn as_ptr(&self) -> *const gobject::GValue {
self.value.0
}
pub unsafe fn from_ptr(ptr: *const gobject::GValue) -> Option<TypedValueRef<'a, T>> {
if let Some(value) = ValueRef::from_ptr(ptr) {
return TypedValueRef::from_value_ref(value);
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -583,7 +704,7 @@ mod tests {
unsafe { gst::gst_init(ptr::null_mut(), ptr::null_mut()) };
let value = Value::new($value);
if let ValueRef::$variant(v) = value.get() {
if let ValueView::$variant(v) = value.get() {
assert_eq!(v, $value);
} else {
unreachable!();
@ -596,13 +717,13 @@ mod tests {
}
let value2 = value.clone();
if let ValueRef::$variant(v) = value2.get() {
if let ValueView::$variant(v) = value2.get() {
assert_eq!(v, $value);
} else {
unreachable!();
}
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value3 = TypedValue::new($value);
@ -631,7 +752,7 @@ mod tests {
let orig_v = String::from("foo");
let value = Value::new(orig_v.clone());
if let ValueRef::String(v) = value.get() {
if let ValueView::String(v) = value.get() {
assert_eq!(v, orig_v);
} else {
unreachable!();
@ -644,17 +765,17 @@ mod tests {
}
let value2 = value.clone();
if let ValueRef::String(v) = value2.get() {
if let ValueView::String(v) = value2.get() {
assert_eq!(v, orig_v);
} else {
unreachable!();
}
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value3 = TypedValue::new(orig_v.clone());
@ -674,7 +795,7 @@ mod tests {
let orig_v = "foo";
let value = Value::new(orig_v);
if let ValueRef::String(v) = value.get() {
if let ValueView::String(v) = value.get() {
assert_eq!(v, orig_v);
} else {
unreachable!();
@ -687,13 +808,13 @@ mod tests {
}
let value2 = value.clone();
if let ValueRef::String(v) = value2.get() {
if let ValueView::String(v) = value2.get() {
assert_eq!(v, orig_v);
} else {
unreachable!();
}
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value3 = TypedValue::new(orig_v);
@ -713,7 +834,7 @@ mod tests {
let orig_v = vec![Value::new("a"), Value::new("b")];
let value = Value::new(orig_v.clone());
if let ValueRef::Array(arr) = value.get() {
if let ValueView::Array(arr) = value.get() {
assert_eq!(arr, orig_v.as_slice());
} else {
unreachable!();
@ -725,10 +846,10 @@ mod tests {
unreachable!();
}
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value3 = TypedValue::new(orig_v.clone());
@ -748,7 +869,7 @@ mod tests {
let orig_v = vec![Value::new("a"), Value::new("b")];
let value = Value::new(&orig_v);
if let ValueRef::Array(arr) = value.get() {
if let ValueView::Array(arr) = value.get() {
assert_eq!(arr, orig_v.as_slice());
} else {
unreachable!();
@ -760,7 +881,7 @@ mod tests {
unreachable!();
}
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value3 = TypedValue::new(orig_v.as_slice());
@ -777,10 +898,10 @@ mod tests {
fn buffer() {
unsafe { gst::gst_init(ptr::null_mut(), ptr::null_mut()) };
let orig_v = Buffer::new_from_vec(vec![1, 2, 3, 4]).unwrap();
let orig_v = Buffer::from_vec(vec![1, 2, 3, 4]).unwrap();
let value = Value::new(orig_v.clone());
if let ValueRef::Buffer(buf) = value.get() {
if let ValueView::Buffer(buf) = value.get() {
assert_eq!(buf, orig_v);
} else {
unreachable!();
@ -792,7 +913,7 @@ mod tests {
unreachable!();
}
let value2 = Value::new_from_value_ref(value.get());
let value2 = Value::from_value_view(value.get());
assert_eq!(value2, value);
let value3 = TypedValue::new(&orig_v);