Update for GLib Into<Value> changes

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1156>
This commit is contained in:
Sebastian Dröge 2022-11-26 13:56:53 +02:00
parent 0b013001b7
commit ae4dd88f3d
26 changed files with 393 additions and 153 deletions

View file

@ -365,6 +365,14 @@ impl glib::value::ToValueOptional for AudioFormatInfo {
}
}
#[doc(hidden)]
impl From<AudioFormatInfo> for glib::Value {
fn from(v: AudioFormatInfo) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[doc(hidden)]
impl glib::translate::GlibPtrDefault for AudioFormatInfo {
type GlibType = *mut ffi::GstAudioFormatInfo;

View file

@ -361,6 +361,14 @@ impl glib::value::ToValue for AudioInfo {
}
}
#[doc(hidden)]
impl From<AudioInfo> for glib::Value {
fn from(v: AudioInfo) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[doc(hidden)]
impl glib::value::ToValueOptional for AudioInfo {
fn to_value_optional(s: Option<&Self>) -> glib::Value {

View file

@ -1,5 +1,4 @@
use crate::{AudioFormat, AudioLayout};
use gst::prelude::*;
use gst::Caps;
use std::ops::Bound::*;
use std::ops::RangeBounds;
@ -134,7 +133,7 @@ impl<T> AudioCapsBuilder<T> {
}
}
pub fn field<V: ToSendValue + Sync>(self, name: &str, value: V) -> Self {
pub fn field(self, name: &str, value: impl Into<glib::Value> + Send) -> Self {
Self {
builder: self.builder.field(name, value),
}

View file

@ -136,7 +136,7 @@ pub struct ElementPropertiesGeneralBuilder {
impl ElementPropertiesGeneralBuilder {
pub fn field<T>(mut self, property_name: &str, value: T) -> Self
where
T: ToSendValue + Sync,
T: Into<glib::Value> + Send,
{
self.structure.set(property_name, value);
self
@ -167,7 +167,7 @@ impl ElementPropertiesMapBuilder {
pub fn build(self) -> ElementProperties {
ElementProperties(
gst::Structure::builder("element-properties-map")
.field("map", gst::List::from(self.map))
.field("map", gst::List::new(self.map))
.build(),
)
}
@ -239,7 +239,7 @@ pub struct ElementPropertiesMapItemBuilder {
impl ElementPropertiesMapItemBuilder {
pub fn field<T>(mut self, property_name: &str, value: T) -> Self
where
T: ToSendValue + Sync,
T: Into<glib::Value> + Send,
{
self.structure.set(property_name, value);
self

View file

@ -1,5 +1,4 @@
use crate::VideoFormat;
use gst::prelude::*;
use gst::Caps;
use std::ops::Bound::*;
use std::ops::RangeBounds;
@ -176,7 +175,7 @@ impl<T> VideoCapsBuilder<T> {
}
}
pub fn field<V: ToSendValue + Sync>(self, name: &str, value: V) -> Self {
pub fn field(self, name: &str, value: impl Into<glib::Value> + Send) -> Self {
Self {
builder: self.builder.field(name, value),
}

View file

@ -83,6 +83,13 @@ impl ToValue for VideoColorRange {
}
}
impl From<VideoColorRange> for glib::Value {
fn from(v: VideoColorRange) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[doc(alias = "GstVideoColorimetry")]
#[derive(Copy, Clone)]
pub struct VideoColorimetry(ffi::GstVideoColorimetry);
@ -892,6 +899,14 @@ impl glib::value::ToValueOptional for VideoInfo {
}
}
#[doc(hidden)]
impl From<VideoInfo> for glib::Value {
fn from(v: VideoInfo) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[doc(hidden)]
impl glib::translate::Uninitialized for VideoInfo {
unsafe fn uninitialized() -> Self {

View file

@ -485,6 +485,14 @@ macro_rules! generic_impl {
value
}
}
#[doc(hidden)]
impl From<$name> for glib::Value {
fn from(v: $name) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
};
}

View file

@ -255,3 +255,11 @@ impl glib::value::ToValueOptional for VideoTimeCodeInterval {
value
}
}
#[doc(hidden)]
impl From<VideoTimeCodeInterval> for glib::Value {
fn from(v: VideoTimeCodeInterval) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}

View file

@ -953,7 +953,7 @@ impl Builder<NoFeature> {
}
impl<T> Builder<T> {
pub fn field<V: ToSendValue + Sync>(mut self, name: &str, value: V) -> Self {
pub fn field(mut self, name: &str, value: impl Into<glib::Value> + Send) -> Self {
self.s.set(name, value);
self
}

View file

@ -281,6 +281,20 @@ impl glib::value::ToValueOptional for CapsFeatures {
}
}
impl From<CapsFeatures> for glib::Value {
fn from(v: CapsFeatures) -> glib::Value {
skip_assert_initialized!();
let mut value = glib::Value::for_value_type::<CapsFeatures>();
unsafe {
glib::gobject_ffi::g_value_take_boxed(
value.to_glib_none_mut().0,
IntoGlibPtr::<*mut ffi::GstCapsFeatures>::into_glib_ptr(v) as *mut _,
)
}
value
}
}
impl GlibPtrDefault for CapsFeatures {
type GlibType = *mut ffi::GstCapsFeatures;
}

View file

@ -17,7 +17,7 @@ pub trait ChildProxyExtManual: 'static {
fn child_property_value(&self, name: &str) -> glib::Value;
#[doc(alias = "gst_child_proxy_set")]
fn set_child_property<V: glib::ToValue>(&self, name: &str, value: V);
fn set_child_property(&self, name: &str, value: impl Into<glib::Value>);
#[doc(alias = "gst_child_proxy_set_property")]
fn set_child_property_from_value(&self, name: &str, value: &glib::Value);
}
@ -54,7 +54,7 @@ impl<O: IsA<ChildProxy>> ChildProxyExtManual for O {
}
#[track_caller]
fn set_child_property<V: glib::ToValue>(&self, name: &str, value: V) {
fn set_child_property(&self, name: &str, value: impl Into<glib::Value>) {
let (child, pspec) = self.lookup(name).unwrap();
child.set_property(pspec.name(), value)
}

View file

@ -56,6 +56,13 @@ impl StaticType for Date {
}
}
impl From<Date> for glib::Value {
fn from(v: Date) -> glib::Value {
skip_assert_initialized!();
v.0.into()
}
}
impl Serialize for Date {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
DateTimeVariants::YMD(

View file

@ -251,12 +251,12 @@ impl<'a> ElementBuilder<'a> {
// rustdoc-stripper-ignore-next
/// Set property `name` to the given value `value`.
pub fn property<T: glib::ToValue + 'a>(self, name: &'a str, value: T) -> Self {
pub fn property(self, name: &'a str, value: impl Into<glib::Value> + 'a) -> Self {
Self {
name_or_factory: self.name_or_factory,
properties: {
let mut properties = self.properties;
properties.push((name, ValueOrStr::Value(value.to_value())));
properties.push((name, ValueOrStr::Value(value.into())));
properties
},
}

View file

@ -643,6 +643,13 @@ impl ToValue for MessageType {
}
}
impl From<MessageType> for glib::Value {
fn from(v: MessageType) -> glib::Value {
skip_assert_initialized!();
ToValue::to_value(&v)
}
}
impl State {
#[must_use]
pub fn next(self, pending: Self) -> Self {

View file

@ -323,6 +323,12 @@ impl glib::value::ToValueOptional for ClockTime {
}
}
impl From<ClockTime> for glib::Value {
fn from(v: ClockTime) -> glib::Value {
glib::value::ToValue::to_value(&v)
}
}
#[doc(hidden)]
impl glib::StaticType for ClockTime {
fn static_type() -> glib::Type {

View file

@ -44,7 +44,7 @@ impl<O: IsA<glib::Object>> GObjectExtManualGst for O {
}
};
self.set_property_from_value(name, &value)
self.set_property(name, value)
}
}

View file

@ -206,10 +206,7 @@ where
}
}
impl<T> IntoGlibPtr<*mut ffi::GstIterator> for Iterator<T>
where
for<'a> T: FromValue<'a> + 'static,
{
impl<T: 'static> IntoGlibPtr<*mut ffi::GstIterator> for Iterator<T> {
unsafe fn into_glib_ptr(self) -> *mut ffi::GstIterator {
let s = mem::ManuallyDrop::new(self);
let it = s.to_glib_none().0;
@ -552,6 +549,20 @@ impl<T: StaticType + 'static> glib::value::ToValueOptional for Iterator<T> {
}
}
impl<T: StaticType + 'static> From<Iterator<T>> for glib::Value {
fn from(v: Iterator<T>) -> glib::Value {
skip_assert_initialized!();
let mut value = glib::Value::for_value_type::<Iterator<T>>();
unsafe {
glib::gobject_ffi::g_value_take_boxed(
value.to_glib_none_mut().0,
v.into_glib_ptr() as *mut _,
)
}
value
}
}
#[doc(hidden)]
impl<T> glib::translate::GlibPtrDefault for Iterator<T> {
type GlibType = *mut ffi::GstIterator;

View file

@ -820,6 +820,20 @@ macro_rules! memory_object_wrapper {
}
}
impl From<$name> for $crate::glib::Value {
fn from(v: $name) -> $crate::glib::Value {
skip_assert_initialized!();
let mut value = $crate::glib::Value::for_value_type::<$name>();
unsafe {
$crate::glib::gobject_ffi::g_value_take_boxed(
$crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
$crate::glib::translate::IntoGlibPtr::<*mut $ffi_name>::into_glib_ptr(v) as *mut _,
)
}
value
}
}
unsafe impl<'a> $crate::glib::value::FromValue<'a> for &'a $ref_name {
type Checker = $crate::memory::MemoryTypeValueTypeChecker<$name>;

View file

@ -531,6 +531,20 @@ macro_rules! mini_object_wrapper (
}
}
impl From<$name> for $crate::glib::Value {
fn from(v: $name) -> $crate::glib::Value {
skip_assert_initialized!();
let mut value = $crate::glib::Value::for_value_type::<$name>();
unsafe {
$crate::glib::gobject_ffi::g_value_take_boxed(
$crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0,
$crate::glib::translate::IntoGlibPtr::<*mut $ffi_name>::into_glib_ptr(v) as *mut _,
)
}
value
}
}
unsafe impl<'a> $crate::glib::value::FromValue<'a> for &'a $ref_name {
type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker<Self>;

View file

@ -643,7 +643,14 @@ impl<T: FormattedValueIntrinsic> glib::value::ToValueOptional for FormattedSegme
value
}
}
#[doc(hidden)]
impl<T: FormattedValueIntrinsic> From<FormattedSegment<T>> for glib::Value {
fn from(v: FormattedSegment<T>) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[doc(hidden)]
impl<T: FormattedValueIntrinsic> glib::translate::GlibPtrDefault for FormattedSegment<T> {
type GlibType = *mut ffi::GstSegment;

View file

@ -72,6 +72,13 @@ impl glib::value::ToValue for StaticCaps {
}
}
impl From<StaticCaps> for glib::Value {
fn from(v: StaticCaps) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[doc(hidden)]
impl glib::value::ToValueOptional for StaticCaps {
fn to_value_optional(s: Option<&Self>) -> glib::Value {

View file

@ -118,6 +118,13 @@ impl glib::value::ToValueOptional for StaticPadTemplate {
}
}
impl From<StaticPadTemplate> for glib::Value {
fn from(v: StaticPadTemplate) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[doc(hidden)]
impl glib::translate::GlibPtrDefault for StaticPadTemplate {
type GlibType = *mut ffi::GstStaticPadTemplate;

View file

@ -349,6 +349,20 @@ impl glib::value::ToValueOptional for Structure {
}
}
impl From<Structure> for glib::Value {
fn from(v: Structure) -> glib::Value {
skip_assert_initialized!();
let mut value = glib::Value::for_value_type::<Structure>();
unsafe {
glib::gobject_ffi::g_value_take_boxed(
value.to_glib_none_mut().0,
glib::translate::IntoGlibPtr::<*mut ffi::GstStructure>::into_glib_ptr(v) as *mut _,
)
}
value
}
}
impl GlibPtrDefault for Structure {
type GlibType = *mut ffi::GstStructure;
}
@ -457,8 +471,8 @@ impl StructureRef {
}
#[doc(alias = "gst_structure_set")]
pub fn set<T: ToSendValue + Sync>(&mut self, name: &str, value: T) {
let value = value.to_send_value();
pub fn set(&mut self, name: &str, value: impl Into<glib::Value> + Send) {
let value = unsafe { glib::SendValue::unsafe_from(value.into().into_raw()) };
self.set_value(name, value);
}
@ -474,8 +488,8 @@ impl StructureRef {
}
#[doc(alias = "gst_structure_id_set")]
pub fn set_by_quark<T: ToSendValue + Sync>(&mut self, name: glib::Quark, value: T) {
let value = value.to_send_value();
pub fn set_by_quark(&mut self, name: glib::Quark, value: impl Into<glib::Value> + Send) {
let value = unsafe { glib::SendValue::unsafe_from(value.into().into_raw()) };
self.set_value_by_quark(name, value);
}
@ -1035,7 +1049,7 @@ impl Builder {
}
}
pub fn field<V: ToSendValue + Sync>(mut self, name: &str, value: V) -> Self {
pub fn field(mut self, name: &str, value: impl Into<glib::Value> + Send) -> Self {
self.s.set(name, value);
self
}

View file

@ -7,9 +7,7 @@ use std::mem;
use once_cell::sync::Lazy;
use glib::translate::{
from_glib, from_glib_full, FromGlibPtrFull, IntoGlib, ToGlibPtr, ToGlibPtrMut,
};
use glib::translate::*;
use glib::value::{FromValue, SendValue, ToSendValue, Value};
use glib::StaticType;
@ -376,14 +374,13 @@ impl TagListRef {
}
#[doc(alias = "gst_tag_list_add")]
pub fn add_generic<T: ToSendValue + Sync>(
pub fn add_generic(
&mut self,
tag_name: &str,
value: T,
value: impl ToSendValue,
mode: TagMergeMode,
) -> Result<(), TagError> {
let v = value.to_send_value();
self.add_value(tag_name, &v, mode)
self.add_value(tag_name, &value.to_send_value(), mode)
}
#[doc(alias = "gst_tag_list_add_value")]
@ -1107,8 +1104,6 @@ pub fn merge_use_first(src: &Value) -> Value {
assert_eq!(src.type_(), crate::List::static_type());
unsafe {
use glib::translate::Uninitialized;
let mut res = Value::uninitialized();
ffi::gst_tag_merge_use_first(res.to_glib_none_mut().0, src.to_glib_none().0);
res
@ -1121,8 +1116,6 @@ pub fn merge_strings_with_comma(src: &Value) -> Value {
assert_eq!(src.type_(), crate::List::static_type());
unsafe {
use glib::translate::Uninitialized;
let mut res = Value::uninitialized();
ffi::gst_tag_merge_strings_with_comma(res.to_glib_none_mut().0, src.to_glib_none().0);
res

View file

@ -6,8 +6,7 @@ use std::fmt;
use std::ops;
use std::slice;
use glib::translate::{from_glib, FromGlibPtrFull, ToGlibPtr, ToGlibPtrMut, Uninitialized};
use glib::value::ToSendValue;
use glib::translate::*;
use glib::StaticType;
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
@ -281,6 +280,13 @@ impl glib::value::ToValue for Fraction {
}
}
impl From<Fraction> for glib::Value {
fn from(v: Fraction) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct IntRange<T> {
@ -423,6 +429,13 @@ impl glib::value::ToValue for IntRange<i32> {
}
}
impl From<IntRange<i32>> for glib::Value {
fn from(v: IntRange<i32>) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
impl glib::types::StaticType for IntRange<i64> {
fn static_type() -> glib::types::Type {
unsafe { from_glib(ffi::gst_int64_range_get_type()) }
@ -465,6 +478,13 @@ impl glib::value::ToValue for IntRange<i64> {
}
}
impl From<IntRange<i64>> for glib::Value {
fn from(v: IntRange<i64>) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FractionRange {
@ -548,6 +568,13 @@ impl glib::value::ToValue for FractionRange {
}
}
impl From<FractionRange> for glib::Value {
fn from(v: FractionRange) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Bitmask(pub u64);
@ -646,27 +673,56 @@ impl glib::value::ToValue for Bitmask {
}
}
#[derive(Clone, Debug)]
pub struct Array(Vec<glib::SendValue>);
impl From<Bitmask> for glib::Value {
fn from(v: Bitmask) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
#[derive(Clone)]
pub struct Array(glib::SendValue);
unsafe impl Send for Array {}
unsafe impl Sync for Array {}
impl fmt::Debug for Array {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Array").field(&self.as_slice()).finish()
}
}
impl Array {
pub fn new(values: impl IntoIterator<Item = impl ToSendValue + Send>) -> Self {
pub fn new(values: impl IntoIterator<Item = impl Into<glib::Value> + Send>) -> Self {
assert_initialized_main_thread!();
Self(values.into_iter().map(|v| v.to_send_value()).collect())
unsafe {
let mut value = glib::Value::for_value_type::<Array>();
for v in values.into_iter() {
let mut v = v.into().into_raw();
ffi::gst_value_array_append_and_take_value(value.to_glib_none_mut().0, &mut v);
}
Self(glib::SendValue::unsafe_from(value.into_raw()))
}
}
pub fn from_values(values: impl IntoIterator<Item = glib::SendValue>) -> Self {
assert_initialized_main_thread!();
Self(values.into_iter().collect())
Self::new(values)
}
pub fn as_slice(&self) -> &[glib::SendValue] {
self.0.as_slice()
unsafe {
let arr = (*self.0.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() || (*arr).len == 0 {
&[]
} else {
#[allow(clippy::cast_ptr_alignment)]
slice::from_raw_parts((*arr).data as *const glib::SendValue, (*arr).len as usize)
}
}
}
}
@ -691,14 +747,6 @@ impl std::iter::FromIterator<glib::SendValue> for Array {
}
}
impl From<Vec<glib::SendValue>> for Array {
fn from(values: Vec<glib::SendValue>) -> Self {
assert_initialized_main_thread!();
Self(values)
}
}
impl glib::value::ValueType for Array {
type Type = Self;
}
@ -708,29 +756,13 @@ unsafe impl<'a> glib::value::FromValue<'a> for Array {
unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() || (*arr).len == 0 {
Self(Vec::new())
} else {
#[allow(clippy::cast_ptr_alignment)]
Self::from_values(
slice::from_raw_parts((*arr).data as *const glib::SendValue, (*arr).len as usize)
.iter()
.cloned(),
)
}
Self(glib::SendValue::unsafe_from(value.clone().into_raw()))
}
}
impl glib::value::ToValue for Array {
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Array>();
unsafe {
for v in self.as_slice() {
ffi::gst_value_array_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
}
}
value
self.0.clone().into()
}
fn value_type(&self) -> glib::Type {
@ -738,6 +770,13 @@ impl glib::value::ToValue for Array {
}
}
impl From<Array> for glib::Value {
fn from(v: Array) -> glib::Value {
skip_assert_initialized!();
v.0.into()
}
}
impl glib::types::StaticType for Array {
fn static_type() -> glib::types::Type {
unsafe { from_glib(ffi::gst_value_array_get_type()) }
@ -781,7 +820,7 @@ unsafe impl<'a> glib::value::FromValue<'a> for ArrayRef<'a> {
unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
let arr = (*value.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() || (*arr).len == 0 {
Self(&[])
} else {
@ -810,33 +849,62 @@ impl<'a> glib::value::ToValue for ArrayRef<'a> {
}
}
impl<'a> From<ArrayRef<'a>> for glib::Value {
fn from(v: ArrayRef<'a>) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
impl<'a> glib::types::StaticType for ArrayRef<'a> {
fn static_type() -> glib::types::Type {
unsafe { from_glib(ffi::gst_value_array_get_type()) }
}
}
#[derive(Clone, Debug)]
pub struct List(Vec<glib::SendValue>);
#[derive(Clone)]
pub struct List(glib::SendValue);
unsafe impl Send for List {}
unsafe impl Sync for List {}
impl fmt::Debug for List {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("List").field(&self.as_slice()).finish()
}
}
impl List {
pub fn new(values: impl IntoIterator<Item = impl ToSendValue + Send>) -> Self {
pub fn new(values: impl IntoIterator<Item = impl Into<glib::Value> + Send>) -> Self {
assert_initialized_main_thread!();
Self(values.into_iter().map(|v| v.to_send_value()).collect())
unsafe {
let mut value = glib::Value::for_value_type::<List>();
for v in values.into_iter() {
let mut v = v.into().into_raw();
ffi::gst_value_list_append_and_take_value(value.to_glib_none_mut().0, &mut v);
}
Self(glib::SendValue::unsafe_from(value.into_raw()))
}
}
pub fn from_values(values: impl IntoIterator<Item = glib::SendValue>) -> Self {
assert_initialized_main_thread!();
Self(values.into_iter().collect())
Self::new(values)
}
pub fn as_slice(&self) -> &[glib::SendValue] {
self.0.as_slice()
unsafe {
let arr = (*self.0.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() || (*arr).len == 0 {
&[]
} else {
#[allow(clippy::cast_ptr_alignment)]
slice::from_raw_parts((*arr).data as *const glib::SendValue, (*arr).len as usize)
}
}
}
}
@ -861,14 +929,6 @@ impl std::iter::FromIterator<glib::SendValue> for List {
}
}
impl From<Vec<glib::SendValue>> for List {
fn from(values: Vec<glib::SendValue>) -> Self {
assert_initialized_main_thread!();
Self(values)
}
}
impl glib::value::ValueType for List {
type Type = Self;
}
@ -878,29 +938,13 @@ unsafe impl<'a> glib::value::FromValue<'a> for List {
unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() || (*arr).len == 0 {
Self(Vec::new())
} else {
#[allow(clippy::cast_ptr_alignment)]
Self::from_values(
slice::from_raw_parts((*arr).data as *const glib::SendValue, (*arr).len as usize)
.iter()
.cloned(),
)
}
Self(glib::SendValue::unsafe_from(value.clone().into_raw()))
}
}
impl glib::value::ToValue for List {
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<List>();
unsafe {
for v in self.as_slice() {
ffi::gst_value_list_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
}
}
value
self.0.clone().into()
}
fn value_type(&self) -> glib::Type {
@ -908,6 +952,13 @@ impl glib::value::ToValue for List {
}
}
impl From<List> for glib::Value {
fn from(v: List) -> glib::Value {
skip_assert_initialized!();
v.0.into()
}
}
impl glib::types::StaticType for List {
fn static_type() -> glib::types::Type {
unsafe { from_glib(ffi::gst_value_list_get_type()) }
@ -951,7 +1002,7 @@ unsafe impl<'a> glib::value::FromValue<'a> for ListRef<'a> {
unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!();
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
let arr = (*value.as_ptr()).data[0].v_pointer as *const glib::ffi::GArray;
if arr.is_null() || (*arr).len == 0 {
Self(&[])
} else {
@ -980,6 +1031,13 @@ impl<'a> glib::value::ToValue for ListRef<'a> {
}
}
impl<'a> From<ListRef<'a>> for glib::Value {
fn from(v: ListRef<'a>) -> glib::Value {
skip_assert_initialized!();
glib::value::ToValue::to_value(&v)
}
}
impl<'a> glib::types::StaticType for ListRef<'a> {
fn static_type() -> glib::types::Type {
unsafe { from_glib(ffi::gst_value_list_get_type()) }

View file

@ -17,6 +17,7 @@ use once_cell::sync::Lazy;
use crate::Buffer;
use crate::DateTime;
use crate::List;
use crate::Sample;
use crate::Structure;
@ -106,7 +107,7 @@ macro_rules! ser_value (
} else if *INT_RANGE_I64_OTHER_TYPE_ID == type_id {
ser_some_value!($value, IntRange<i64>, $ser_closure)
} else if *LIST_OTHER_TYPE_ID == type_id {
ser_some_value!($value, List, $ser_closure)
ser_some_value!($value, crate::List, $ser_closure)
} else if *SAMPLE_OTHER_TYPE_ID == type_id {
ser_opt_value!($value, Sample, $ser_closure)
} else if *BUFFER_OTHER_TYPE_ID == type_id {
@ -523,48 +524,61 @@ mod tests {
fn test_deserialize_collections() {
crate::init().unwrap();
// Array
// Array of fractions
let array_ron = r#"[
("Fraction", (1, 3)),
("Fraction", (1, 2)),
]"#;
let array: Array = ron::de::from_str(array_ron).unwrap();
let slice = array.as_slice();
assert_eq!(2, slice.len());
let fraction = slice[0].get::<Fraction>().expect("slice[0]");
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction = slice[1].get::<Fraction>().expect("slice[1]");
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
// Array of strings
let array_ron = r#"[
("String", Some("test str")),
("String", None),
]"#;
let array: Array = ron::de::from_str(array_ron).unwrap();
let slice = array.as_slice();
assert_eq!(2, slice.len());
assert_eq!(
"test str".to_owned(),
slice[0].get::<String>().expect("slice[0]")
);
assert!(slice[1]
.get::<Option<String>>()
.expect("slice[1]")
.is_none());
// Array of dates
let array_ron = r#"[
("Date", Some(YMD(2019, 8, 19))),
("Date", None),
]"#;
let array: Array = ron::de::from_str(array_ron).unwrap();
let slice = array.as_slice();
assert_eq!(6, slice.len());
let fraction = slice[0].get::<Fraction>().expect("slice[0]");
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction = slice[1].get::<Fraction>().expect("slice[1]");
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!(
"test str".to_owned(),
slice[2].get::<String>().expect("slice[2]")
);
assert!(slice[3]
.get::<Option<String>>()
.expect("slice[3]")
.is_none());
assert_eq!(2, slice.len());
assert_eq!(
Date::from_dmy(19, DateMonth::August, 2019).unwrap(),
slice[4].get::<Date>().expect("slice[4]")
slice[0].get::<Date>().expect("slice[0]")
);
assert!(slice[5].get::<Option<Date>>().expect("slice[5]").is_none());
assert!(slice[1].get::<Option<Date>>().expect("slice[1]").is_none());
let array_json = r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"],["String",null],["Date",{"YMD":[2019,8,19]}],["Date",null]]"#;
// Array of fractions
let array_json = r#"[["Fraction",[1,3]],["Fraction",[1,2]]]"#;
let array: Array = serde_json::from_str(array_json).unwrap();
let slice = array.as_slice();
assert_eq!(6, slice.len());
assert_eq!(2, slice.len());
let fraction = slice[0].get::<Fraction>().expect("slice[0]");
assert_eq!(fraction.0.numer(), &1);
@ -574,57 +588,79 @@ mod tests {
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
// Array of strings
let array_json = r#"[["String","test str"],["String",null]]"#;
let array: Array = serde_json::from_str(array_json).unwrap();
let slice = array.as_slice();
assert_eq!(2, slice.len());
assert_eq!(
"test str".to_owned(),
slice[2].get::<String>().expect("slice[2]")
slice[0].get::<String>().expect("slice[0]")
);
assert!(slice[3]
assert!(slice[1]
.get::<Option<String>>()
.expect("slice[3]")
.expect("slice[1]")
.is_none());
// Array of dates
let array_json = r#"[["Date",{"YMD":[2019,8,19]}],["Date",null]]"#;
let array: Array = serde_json::from_str(array_json).unwrap();
let slice = array.as_slice();
assert_eq!(2, slice.len());
assert_eq!(
Date::from_dmy(19, DateMonth::August, 2019).unwrap(),
slice[4].get::<Date>().expect("slice[4]")
slice[0].get::<Date>().expect("slice[0]")
);
assert!(slice[5].get::<Option<Date>>().expect("slice[5]").is_none());
assert!(slice[1].get::<Option<Date>>().expect("slice[1]").is_none());
// List
// List of fractions
let list_ron = r#"[
("Fraction", (1, 2)),
]"#;
let list: List = ron::de::from_str(list_ron).unwrap();
let slice = list.as_slice();
assert_eq!(1, slice.len());
let fraction = slice[0].get::<Fraction>().expect("slice[0]");
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
// List of strings
let list_ron = r#"[
("String", Some("test str")),
("String", None),
]"#;
let list: List = ron::de::from_str(list_ron).unwrap();
let slice = list.as_slice();
assert_eq!(2, slice.len());
assert_eq!(
"test str".to_owned(),
slice[0].get::<String>().expect("slice[0]")
);
assert!(slice[1]
.get::<Option<String>>()
.expect("slice[1]")
.is_none());
// List of date times
let list_ron = r#"[
("DateTime", Some(YMDhmsTz(2019, 8, 19, 13, 34, 42, 2))),
("DateTime", None),
]"#;
let list: List = ron::de::from_str(list_ron).unwrap();
let slice = list.as_slice();
assert_eq!(5, slice.len());
let fraction = slice[0].get::<Fraction>().expect("slice[0]");
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!(
"test str".to_owned(),
slice[1].get::<String>().expect("slice[1]")
);
assert!(slice[2]
.get::<Option<String>>()
.expect("slice[2]")
.is_none());
assert_eq!(2, slice.len());
assert_eq!(
DateTime::new(2f32, 2019, 8, 19, 13, 34, 42f64).unwrap(),
slice[3].get::<DateTime>().expect("slice[3]")
slice[0].get::<DateTime>().expect("slice[0]")
);
assert!(slice[4]
assert!(slice[1]
.get::<Option<DateTime>>()
.expect("slice[4]")
.expect("slice[1]")
.is_none());
}