mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-25 11:01:10 +00:00
gstreamer: Refactor gst::Array / gst::List bindings to work correctly with the refactored traits in glib
Also allow only a single type inside them. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/360
This commit is contained in:
parent
30bb699cbc
commit
9901f0c6a2
5 changed files with 251 additions and 227 deletions
|
@ -127,20 +127,11 @@ impl AudioConverterConfig {
|
||||||
|
|
||||||
pub fn set_mix_matrix(&mut self, v: &[impl AsRef<[f32]>]) {
|
pub fn set_mix_matrix(&mut self, v: &[impl AsRef<[f32]>]) {
|
||||||
let length = v.get(0).map(|v| v.as_ref().len()).unwrap_or(0);
|
let length = v.get(0).map(|v| v.as_ref().len()).unwrap_or(0);
|
||||||
let array = gst::Array::from_owned(
|
let array = gst::Array::from_values(v.iter().map(|val| {
|
||||||
v.iter()
|
let val = val.as_ref();
|
||||||
.map(|val| {
|
assert_eq!(val.len(), length);
|
||||||
let val = val.as_ref();
|
gst::Array::from_values(val.iter().map(|val| val.to_send_value())).to_send_value()
|
||||||
assert_eq!(val.len(), length);
|
}));
|
||||||
gst::Array::from_owned(
|
|
||||||
val.iter()
|
|
||||||
.map(|val| val.to_send_value())
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)
|
|
||||||
.to_send_value()
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
);
|
|
||||||
self.0.set("GstAudioConverter.mix-matrix", &array);
|
self.0.set("GstAudioConverter.mix-matrix", &array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,17 +51,14 @@ pub fn audio_make_raw_caps(
|
||||||
) -> gst::caps::Builder<gst::caps::NoFeature> {
|
) -> gst::caps::Builder<gst::caps::NoFeature> {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
let formats: Vec<glib::SendValue> = formats
|
let formats = formats.iter().map(|f| match f {
|
||||||
.iter()
|
crate::AudioFormat::Encoded => panic!("Invalid encoded format"),
|
||||||
.map(|f| match f {
|
crate::AudioFormat::Unknown => panic!("Invalid unknown format"),
|
||||||
crate::AudioFormat::Encoded => panic!("Invalid encoded format"),
|
_ => f.to_string().to_send_value(),
|
||||||
crate::AudioFormat::Unknown => panic!("Invalid unknown format"),
|
});
|
||||||
_ => f.to_string().to_send_value(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let builder = gst::caps::Caps::builder("audio/x-raw")
|
let builder = gst::caps::Caps::builder("audio/x-raw")
|
||||||
.field("format", gst::List::from_owned(formats))
|
.field("format", gst::List::from_values(formats))
|
||||||
.field("rate", gst::IntRange::<i32>::new(1, i32::MAX))
|
.field("rate", gst::IntRange::<i32>::new(1, i32::MAX))
|
||||||
.field("channels", gst::IntRange::<i32>::new(1, i32::MAX));
|
.field("channels", gst::IntRange::<i32>::new(1, i32::MAX));
|
||||||
|
|
||||||
|
|
|
@ -201,17 +201,14 @@ pub fn video_make_raw_caps(
|
||||||
) -> gst::caps::Builder<gst::caps::NoFeature> {
|
) -> gst::caps::Builder<gst::caps::NoFeature> {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
let formats: Vec<glib::SendValue> = formats
|
let formats = formats.iter().map(|f| match f {
|
||||||
.iter()
|
crate::VideoFormat::Encoded => panic!("Invalid encoded format"),
|
||||||
.map(|f| match f {
|
crate::VideoFormat::Unknown => panic!("Invalid unknown format"),
|
||||||
crate::VideoFormat::Encoded => panic!("Invalid encoded format"),
|
_ => f.to_string().to_send_value(),
|
||||||
crate::VideoFormat::Unknown => panic!("Invalid unknown format"),
|
});
|
||||||
_ => f.to_string().to_send_value(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
gst::caps::Caps::builder("video/x-raw")
|
gst::caps::Caps::builder("video/x-raw")
|
||||||
.field("format", gst::List::from_owned(formats))
|
.field("format", gst::List::from_values(formats))
|
||||||
.field("width", gst::IntRange::<i32>::new(1, i32::MAX))
|
.field("width", gst::IntRange::<i32>::new(1, i32::MAX))
|
||||||
.field("height", gst::IntRange::<i32>::new(1, i32::MAX))
|
.field("height", gst::IntRange::<i32>::new(1, i32::MAX))
|
||||||
.field(
|
.field(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// Take a look at the license at the top of the repository in the LICENSE file.
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
use num_rational::Rational32;
|
use num_rational::Rational32;
|
||||||
use std::borrow::{Borrow, Cow};
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
@ -622,40 +621,30 @@ impl glib::value::ToValue for Bitmask {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Array<'a>(Cow<'a, [glib::SendValue]>);
|
pub struct Array(Vec<glib::SendValue>);
|
||||||
|
|
||||||
unsafe impl<'a> Send for Array<'a> {}
|
unsafe impl Send for Array {}
|
||||||
unsafe impl<'a> Sync for Array<'a> {}
|
unsafe impl Sync for Array {}
|
||||||
|
|
||||||
impl<'a> Array<'a> {
|
impl Array {
|
||||||
pub fn new(values: &[&(dyn ToSendValue + Sync)]) -> Self {
|
pub fn new(values: impl IntoIterator<Item = impl ToSendValue + Sync>) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
Array(values.iter().map(|v| v.to_send_value()).collect())
|
Self(values.into_iter().map(|v| v.to_send_value()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_borrowed(values: &'a impl AsRef<[glib::SendValue]>) -> Self {
|
pub fn from_values(values: impl IntoIterator<Item = glib::SendValue>) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
Array(Cow::Borrowed(values.as_ref()))
|
Self(values.into_iter().collect())
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_owned(values: Vec<glib::SendValue>) -> Self {
|
|
||||||
assert_initialized_main_thread!();
|
|
||||||
|
|
||||||
Array(Cow::Owned(values))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_owned(self) -> Array<'static> {
|
|
||||||
Array(self.0.into_owned().into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &[glib::SendValue] {
|
pub fn as_slice(&self) -> &[glib::SendValue] {
|
||||||
self.0.borrow()
|
self.0.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ops::Deref for Array<'a> {
|
impl ops::Deref for Array {
|
||||||
type Target = [glib::SendValue];
|
type Target = [glib::SendValue];
|
||||||
|
|
||||||
fn deref(&self) -> &[glib::SendValue] {
|
fn deref(&self) -> &[glib::SendValue] {
|
||||||
|
@ -663,47 +652,53 @@ impl<'a> ops::Deref for Array<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [&'a (dyn ToSendValue + Sync)]> for Array<'a> {
|
impl AsRef<[glib::SendValue]> for Array {
|
||||||
fn from(values: &'a [&'a (dyn ToSendValue + Sync)]) -> Self {
|
fn as_ref(&self) -> &[glib::SendValue] {
|
||||||
skip_assert_initialized!();
|
self.as_slice()
|
||||||
|
|
||||||
Self::new(values)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [glib::SendValue]> for Array<'a> {
|
impl std::iter::FromIterator<glib::SendValue> for Array {
|
||||||
fn from(values: &'a [glib::SendValue]) -> Self {
|
fn from_iter<T: IntoIterator<Item = glib::SendValue>>(iter: T) -> Self {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
Self::from_values(iter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<glib::SendValue>> for Array {
|
||||||
|
fn from(values: Vec<glib::SendValue>) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
Array(Cow::Borrowed(values))
|
Self(values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> glib::value::ValueType for Array<'static> {
|
impl glib::value::ValueType for Array {
|
||||||
type Type = Self;
|
type Type = Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a> glib::value::FromValue<'a> for Array<'a> {
|
unsafe impl<'a> glib::value::FromValue<'a> for Array {
|
||||||
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
||||||
|
|
||||||
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
|
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
|
||||||
if arr.is_null() {
|
if arr.is_null() {
|
||||||
Array(Cow::Borrowed(&[]))
|
Self(Vec::new())
|
||||||
} else {
|
} else {
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
Array(Cow::Borrowed(slice::from_raw_parts(
|
Self::from_values(
|
||||||
(*arr).data as *const glib::SendValue,
|
slice::from_raw_parts((*arr).data as *const glib::SendValue, (*arr).len as usize)
|
||||||
(*arr).len as usize,
|
.iter()
|
||||||
)))
|
.cloned(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> glib::value::ToValue for Array<'a> {
|
impl glib::value::ToValue for Array {
|
||||||
fn to_value(&self) -> glib::Value {
|
fn to_value(&self) -> glib::Value {
|
||||||
let mut value = glib::Value::for_value_type::<Array<'static>>();
|
let mut value = glib::Value::for_value_type::<Array>();
|
||||||
unsafe {
|
unsafe {
|
||||||
for v in self.as_slice() {
|
for v in self.as_slice() {
|
||||||
ffi::gst_value_array_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
|
ffi::gst_value_array_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
|
||||||
|
@ -717,47 +712,31 @@ impl<'a> glib::value::ToValue for Array<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> glib::types::StaticType for Array<'a> {
|
impl glib::types::StaticType for Array {
|
||||||
fn static_type() -> glib::types::Type {
|
fn static_type() -> glib::types::Type {
|
||||||
unsafe { from_glib(ffi::gst_value_array_get_type()) }
|
unsafe { from_glib(ffi::gst_value_array_get_type()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct List<'a>(Cow<'a, [glib::SendValue]>);
|
pub struct ArrayRef<'a>(&'a [glib::SendValue]);
|
||||||
|
|
||||||
unsafe impl<'a> Send for List<'a> {}
|
unsafe impl<'a> Send for ArrayRef<'a> {}
|
||||||
unsafe impl<'a> Sync for List<'a> {}
|
unsafe impl<'a> Sync for ArrayRef<'a> {}
|
||||||
|
|
||||||
impl<'a> List<'a> {
|
impl<'a> ArrayRef<'a> {
|
||||||
pub fn new(values: &[&(dyn ToSendValue + Sync)]) -> Self {
|
pub fn new(values: &'a [glib::SendValue]) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
List(values.iter().map(|v| v.to_send_value()).collect())
|
Self(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_borrowed(values: &'a impl AsRef<[glib::SendValue]>) -> Self {
|
pub fn as_slice(&self) -> &'a [glib::SendValue] {
|
||||||
assert_initialized_main_thread!();
|
self.0
|
||||||
|
|
||||||
List(Cow::Borrowed(values.as_ref()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_owned(values: Vec<glib::SendValue>) -> Self {
|
|
||||||
assert_initialized_main_thread!();
|
|
||||||
|
|
||||||
List(Cow::Owned(values))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_owned(self) -> List<'static> {
|
|
||||||
List(self.0.into_owned().into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &[glib::SendValue] {
|
|
||||||
self.0.borrow()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ops::Deref for List<'a> {
|
impl<'a> ops::Deref for ArrayRef<'a> {
|
||||||
type Target = [glib::SendValue];
|
type Target = [glib::SendValue];
|
||||||
|
|
||||||
fn deref(&self) -> &[glib::SendValue] {
|
fn deref(&self) -> &[glib::SendValue] {
|
||||||
|
@ -765,47 +744,131 @@ impl<'a> ops::Deref for List<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [&'a (dyn ToSendValue + Sync)]> for List<'a> {
|
impl<'a> AsRef<[glib::SendValue]> for ArrayRef<'a> {
|
||||||
fn from(values: &'a [&'a (dyn ToSendValue + Sync)]) -> Self {
|
fn as_ref(&self) -> &[glib::SendValue] {
|
||||||
skip_assert_initialized!();
|
self.as_slice()
|
||||||
|
|
||||||
Self::new(values)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [glib::SendValue]> for List<'a> {
|
unsafe impl<'a> glib::value::FromValue<'a> for ArrayRef<'a> {
|
||||||
fn from(values: &'a [glib::SendValue]) -> Self {
|
|
||||||
assert_initialized_main_thread!();
|
|
||||||
|
|
||||||
List(Cow::Borrowed(values))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl glib::value::ValueType for List<'static> {
|
|
||||||
type Type = Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<'a> glib::value::FromValue<'a> for List<'a> {
|
|
||||||
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
||||||
|
|
||||||
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
|
let arr = (*value.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray;
|
||||||
if arr.is_null() {
|
if arr.is_null() {
|
||||||
List(Cow::Borrowed(&[]))
|
Self(&[])
|
||||||
} else {
|
} else {
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
List(Cow::Borrowed(slice::from_raw_parts(
|
Self(slice::from_raw_parts(
|
||||||
(*arr).data as *const glib::SendValue,
|
(*arr).data as *const glib::SendValue,
|
||||||
(*arr).len as usize,
|
(*arr).len as usize,
|
||||||
)))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> glib::value::ToValue for List<'a> {
|
impl<'a> glib::value::ToValue for ArrayRef<'a> {
|
||||||
fn to_value(&self) -> glib::Value {
|
fn to_value(&self) -> glib::Value {
|
||||||
let mut value = glib::Value::for_value_type::<List<'static>>();
|
let mut value = glib::Value::for_value_type::<Array>();
|
||||||
|
unsafe {
|
||||||
|
for v in self.0 {
|
||||||
|
ffi::gst_value_array_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value_type(&self) -> glib::Type {
|
||||||
|
Self::static_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>);
|
||||||
|
|
||||||
|
unsafe impl Send for List {}
|
||||||
|
unsafe impl Sync for List {}
|
||||||
|
|
||||||
|
impl List {
|
||||||
|
pub fn new(values: impl IntoIterator<Item = impl ToSendValue + Sync>) -> Self {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
Self(values.into_iter().map(|v| v.to_send_value()).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_values(values: impl IntoIterator<Item = glib::SendValue>) -> Self {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
Self(values.into_iter().collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice(&self) -> &[glib::SendValue] {
|
||||||
|
self.0.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Deref for List {
|
||||||
|
type Target = [glib::SendValue];
|
||||||
|
|
||||||
|
fn deref(&self) -> &[glib::SendValue] {
|
||||||
|
self.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[glib::SendValue]> for List {
|
||||||
|
fn as_ref(&self) -> &[glib::SendValue] {
|
||||||
|
self.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::iter::FromIterator<glib::SendValue> for List {
|
||||||
|
fn from_iter<T: IntoIterator<Item = glib::SendValue>>(iter: T) -> Self {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
Self::from_values(iter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> glib::value::FromValue<'a> for List {
|
||||||
|
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
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(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl glib::value::ToValue for List {
|
||||||
|
fn to_value(&self) -> glib::Value {
|
||||||
|
let mut value = glib::Value::for_value_type::<List>();
|
||||||
unsafe {
|
unsafe {
|
||||||
for v in self.as_slice() {
|
for v in self.as_slice() {
|
||||||
ffi::gst_value_list_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
|
ffi::gst_value_list_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
|
||||||
|
@ -819,7 +882,79 @@ impl<'a> glib::value::ToValue for List<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> glib::types::StaticType for List<'a> {
|
impl glib::types::StaticType for List {
|
||||||
|
fn static_type() -> glib::types::Type {
|
||||||
|
unsafe { from_glib(ffi::gst_value_list_get_type()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ListRef<'a>(&'a [glib::SendValue]);
|
||||||
|
|
||||||
|
unsafe impl<'a> Send for ListRef<'a> {}
|
||||||
|
unsafe impl<'a> Sync for ListRef<'a> {}
|
||||||
|
|
||||||
|
impl<'a> ListRef<'a> {
|
||||||
|
pub fn new(values: &'a [glib::SendValue]) -> Self {
|
||||||
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
Self(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice(&self) -> &'a [glib::SendValue] {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ops::Deref for ListRef<'a> {
|
||||||
|
type Target = [glib::SendValue];
|
||||||
|
|
||||||
|
fn deref(&self) -> &[glib::SendValue] {
|
||||||
|
self.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> AsRef<[glib::SendValue]> for ListRef<'a> {
|
||||||
|
fn as_ref(&self) -> &[glib::SendValue] {
|
||||||
|
self.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> glib::value::FromValue<'a> for ListRef<'a> {
|
||||||
|
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
Self(&[])
|
||||||
|
} else {
|
||||||
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
|
Self(slice::from_raw_parts(
|
||||||
|
(*arr).data as *const glib::SendValue,
|
||||||
|
(*arr).len as usize,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> glib::value::ToValue for ListRef<'a> {
|
||||||
|
fn to_value(&self) -> glib::Value {
|
||||||
|
let mut value = glib::Value::for_value_type::<List>();
|
||||||
|
unsafe {
|
||||||
|
for v in self.0 {
|
||||||
|
ffi::gst_value_list_append_value(value.to_glib_none_mut().0, v.to_glib_none().0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value_type(&self) -> glib::Type {
|
||||||
|
Self::static_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> glib::types::StaticType for ListRef<'a> {
|
||||||
fn static_type() -> glib::types::Type {
|
fn static_type() -> glib::types::Type {
|
||||||
unsafe { from_glib(ffi::gst_value_list_get_type()) }
|
unsafe { from_glib(ffi::gst_value_list_get_type()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub(crate) static LIST_OTHER_TYPE_ID: Lazy<glib::Type> = Lazy::new(List::static_
|
||||||
pub(crate) static SAMPLE_OTHER_TYPE_ID: Lazy<glib::Type> = Lazy::new(Sample::static_type);
|
pub(crate) static SAMPLE_OTHER_TYPE_ID: Lazy<glib::Type> = Lazy::new(Sample::static_type);
|
||||||
pub(crate) static BUFFER_OTHER_TYPE_ID: Lazy<glib::Type> = Lazy::new(Buffer::static_type);
|
pub(crate) static BUFFER_OTHER_TYPE_ID: Lazy<glib::Type> = Lazy::new(Buffer::static_type);
|
||||||
|
|
||||||
impl<'a> Serialize for Fraction {
|
impl Serialize for Fraction {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
self.0.serialize(serializer)
|
self.0.serialize(serializer)
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ impl Serialize for SendValue {
|
||||||
|
|
||||||
macro_rules! impl_ser_send_value_collection (
|
macro_rules! impl_ser_send_value_collection (
|
||||||
($t:ident) => (
|
($t:ident) => (
|
||||||
impl<'a> Serialize for $t<'a> {
|
impl Serialize for $t {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
let send_value_vec = unsafe {
|
let send_value_vec = unsafe {
|
||||||
&*(self.as_slice() as *const [glib::SendValue] as *const [SendValue])
|
&*(self.as_slice() as *const [glib::SendValue] as *const [SendValue])
|
||||||
|
@ -270,11 +270,11 @@ impl<'de> Deserialize<'de> for SendValue {
|
||||||
|
|
||||||
macro_rules! impl_de_send_value_collection (
|
macro_rules! impl_de_send_value_collection (
|
||||||
($t:ident) => {
|
($t:ident) => {
|
||||||
impl<'a, 'de> Deserialize<'de> for $t<'a> {
|
impl<'de> Deserialize<'de> for $t {
|
||||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
let send_value_vec = Vec::<SendValue>::deserialize(deserializer)?;
|
let send_value_vec = Vec::<SendValue>::deserialize(deserializer)?;
|
||||||
Ok($t::from_owned(unsafe{
|
Ok($t::from_values(unsafe{
|
||||||
mem::transmute::<Vec<SendValue>, Vec<glib::SendValue>>(send_value_vec)
|
mem::transmute::<Vec<SendValue>, Vec<glib::SendValue>>(send_value_vec)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -348,19 +348,8 @@ mod tests {
|
||||||
// Array
|
// Array
|
||||||
let value_13 = Fraction::new(1, 3);
|
let value_13 = Fraction::new(1, 3);
|
||||||
let value_12 = Fraction::new(1, 2);
|
let value_12 = Fraction::new(1, 2);
|
||||||
let value_str = "test str";
|
|
||||||
let value_str_none: Option<&str> = None;
|
|
||||||
let value_date = Date::new_dmy(19, DateMonth::August, 2019).unwrap();
|
|
||||||
let value_date_none: Option<Date> = None;
|
|
||||||
|
|
||||||
let array = Array::new(&[
|
let array = Array::new(&[&value_13, &value_12]);
|
||||||
&value_13,
|
|
||||||
&value_12,
|
|
||||||
&value_str,
|
|
||||||
&value_str_none,
|
|
||||||
&value_date,
|
|
||||||
&value_date_none,
|
|
||||||
]);
|
|
||||||
|
|
||||||
let res = ron::ser::to_string_pretty(&array, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&array, pretty_config.clone());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -368,10 +357,6 @@ mod tests {
|
||||||
r#"["#,
|
r#"["#,
|
||||||
r#" ("Fraction", (1, 3)),"#,
|
r#" ("Fraction", (1, 3)),"#,
|
||||||
r#" ("Fraction", (1, 2)),"#,
|
r#" ("Fraction", (1, 2)),"#,
|
||||||
r#" ("String", Some("test str")),"#,
|
|
||||||
r#" ("String", None),"#,
|
|
||||||
r#" ("Date", Some(YMD(2019, 8, 19))),"#,
|
|
||||||
r#" ("Date", None),"#,
|
|
||||||
r#"]"#
|
r#"]"#
|
||||||
)
|
)
|
||||||
.to_owned()),
|
.to_owned()),
|
||||||
|
@ -379,39 +364,16 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let res = serde_json::to_string(&array).unwrap();
|
let res = serde_json::to_string(&array).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(r#"[["Fraction",[1,3]],["Fraction",[1,2]]]"#.to_owned(), res);
|
||||||
r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"],["String",null],["Date",{"YMD":[2019,8,19]}],["Date",null]]"#
|
|
||||||
.to_owned(),
|
|
||||||
res
|
|
||||||
);
|
|
||||||
|
|
||||||
// List
|
// List
|
||||||
let value_12 = Fraction::new(1, 2);
|
let value_12 = Fraction::new(1, 2);
|
||||||
let value_str = "test str";
|
|
||||||
let value_str_none: Option<&str> = None;
|
|
||||||
let value_date_time = DateTime::new(2f32, 2019, 8, 19, 13, 34, 42f64).unwrap();
|
|
||||||
let value_date_time_none: Option<DateTime> = None;
|
|
||||||
|
|
||||||
let list = List::new(&[
|
let list = List::new(&[&value_12]);
|
||||||
&value_12,
|
|
||||||
&value_str,
|
|
||||||
&value_str_none,
|
|
||||||
&value_date_time,
|
|
||||||
&value_date_time_none,
|
|
||||||
]);
|
|
||||||
|
|
||||||
let res = ron::ser::to_string_pretty(&list, pretty_config);
|
let res = ron::ser::to_string_pretty(&list, pretty_config);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok(concat!(
|
Ok(concat!(r#"["#, r#" ("Fraction", (1, 2)),"#, r#"]"#).to_owned()),
|
||||||
r#"["#,
|
|
||||||
r#" ("Fraction", (1, 2)),"#,
|
|
||||||
r#" ("String", Some("test str")),"#,
|
|
||||||
r#" ("String", None),"#,
|
|
||||||
r#" ("DateTime", Some(YMDhmsTz(2019, 8, 19, 13, 34, 42, 2))),"#,
|
|
||||||
r#" ("DateTime", None),"#,
|
|
||||||
r#"]"#
|
|
||||||
)
|
|
||||||
.to_owned()),
|
|
||||||
res,
|
res,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -624,19 +586,8 @@ mod tests {
|
||||||
// Array
|
// Array
|
||||||
let value_13 = Fraction::new(1, 3);
|
let value_13 = Fraction::new(1, 3);
|
||||||
let value_12 = Fraction::new(1, 2);
|
let value_12 = Fraction::new(1, 2);
|
||||||
let value_str = "test str";
|
|
||||||
let value_str_none: Option<&str> = None;
|
|
||||||
let value_date = Date::new_dmy(19, DateMonth::August, 2019).unwrap();
|
|
||||||
let value_date_none: Option<Date> = None;
|
|
||||||
|
|
||||||
let array = Array::new(&[
|
let array = Array::new(&[&value_13, &value_12]);
|
||||||
&value_13,
|
|
||||||
&value_12,
|
|
||||||
&value_str,
|
|
||||||
&value_str_none,
|
|
||||||
&value_date,
|
|
||||||
&value_date_none,
|
|
||||||
]);
|
|
||||||
let array_ser = ron::ser::to_string(&array).unwrap();
|
let array_ser = ron::ser::to_string(&array).unwrap();
|
||||||
|
|
||||||
let array_de: Array = ron::de::from_str(array_ser.as_str()).unwrap();
|
let array_de: Array = ron::de::from_str(array_ser.as_str()).unwrap();
|
||||||
|
@ -654,37 +605,10 @@ mod tests {
|
||||||
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
||||||
assert_eq!(fraction.0.denom(), fraction.0.denom());
|
assert_eq!(fraction.0.denom(), fraction.0.denom());
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
slice_de[2].get::<String>().expect("slice_de[2]"),
|
|
||||||
slice[2].get::<String>().expect("slice[2]")
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(slice[3]
|
|
||||||
.get::<Option<String>>()
|
|
||||||
.expect("slice[3]")
|
|
||||||
.is_none());
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
slice_de[4].get::<Date>().expect("slice_de[4]"),
|
|
||||||
slice[4].get::<Date>().expect("slice[4]")
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(slice[5].get::<Option<Date>>().expect("slice[5]").is_none());
|
|
||||||
|
|
||||||
// List
|
// List
|
||||||
let value_12 = Fraction::new(1, 2);
|
let value_12 = Fraction::new(1, 2);
|
||||||
let value_str = "test str";
|
|
||||||
let value_str_none: Option<&str> = None;
|
|
||||||
let value_date_time = DateTime::new(2f32, 2019, 8, 19, 13, 34, 42f64).unwrap();
|
|
||||||
let value_date_time_none: Option<DateTime> = None;
|
|
||||||
|
|
||||||
let list = List::new(&[
|
let list = List::new(&[&value_12]);
|
||||||
&value_12,
|
|
||||||
&value_str,
|
|
||||||
&value_str_none,
|
|
||||||
&value_date_time,
|
|
||||||
&value_date_time_none,
|
|
||||||
]);
|
|
||||||
let list_ser = ron::ser::to_string(&list).unwrap();
|
let list_ser = ron::ser::to_string(&list).unwrap();
|
||||||
|
|
||||||
let list_de: List = ron::de::from_str(list_ser.as_str()).unwrap();
|
let list_de: List = ron::de::from_str(list_ser.as_str()).unwrap();
|
||||||
|
@ -696,25 +620,5 @@ mod tests {
|
||||||
let fraction = slice[0].get::<Fraction>().expect("slice[0]");
|
let fraction = slice[0].get::<Fraction>().expect("slice[0]");
|
||||||
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
||||||
assert_eq!(fraction_de.0.denom(), fraction.0.denom());
|
assert_eq!(fraction_de.0.denom(), fraction.0.denom());
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
slice_de[1].get::<String>().expect("slice_de[1]"),
|
|
||||||
slice[1].get::<String>().expect("slice[1]")
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(slice[2]
|
|
||||||
.get::<Option<String>>()
|
|
||||||
.expect("slice[2]")
|
|
||||||
.is_none());
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
slice_de[3].get::<DateTime>().expect("slice_de[3]"),
|
|
||||||
slice[3].get::<DateTime>().expect("slice[3]")
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(slice[4]
|
|
||||||
.get::<Option<DateTime>>()
|
|
||||||
.expect("slice[4]")
|
|
||||||
.is_none());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue