diff --git a/gstreamer-audio/src/audio_converter.rs b/gstreamer-audio/src/audio_converter.rs index cb24a79be..c9a732e34 100644 --- a/gstreamer-audio/src/audio_converter.rs +++ b/gstreamer-audio/src/audio_converter.rs @@ -127,20 +127,11 @@ impl AudioConverterConfig { 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 array = gst::Array::from_owned( - v.iter() - .map(|val| { - let val = val.as_ref(); - assert_eq!(val.len(), length); - gst::Array::from_owned( - val.iter() - .map(|val| val.to_send_value()) - .collect::>(), - ) - .to_send_value() - }) - .collect::>(), - ); + let array = gst::Array::from_values(v.iter().map(|val| { + let val = val.as_ref(); + assert_eq!(val.len(), length); + gst::Array::from_values(val.iter().map(|val| val.to_send_value())).to_send_value() + })); self.0.set("GstAudioConverter.mix-matrix", &array); } diff --git a/gstreamer-audio/src/functions.rs b/gstreamer-audio/src/functions.rs index 43c8af8be..dac9bc98a 100644 --- a/gstreamer-audio/src/functions.rs +++ b/gstreamer-audio/src/functions.rs @@ -51,17 +51,14 @@ pub fn audio_make_raw_caps( ) -> gst::caps::Builder { assert_initialized_main_thread!(); - let formats: Vec = formats - .iter() - .map(|f| match f { - crate::AudioFormat::Encoded => panic!("Invalid encoded format"), - crate::AudioFormat::Unknown => panic!("Invalid unknown format"), - _ => f.to_string().to_send_value(), - }) - .collect(); + let formats = formats.iter().map(|f| match f { + crate::AudioFormat::Encoded => panic!("Invalid encoded format"), + crate::AudioFormat::Unknown => panic!("Invalid unknown format"), + _ => f.to_string().to_send_value(), + }); 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::::new(1, i32::MAX)) .field("channels", gst::IntRange::::new(1, i32::MAX)); diff --git a/gstreamer-video/src/functions.rs b/gstreamer-video/src/functions.rs index 2699d5370..1972cf581 100644 --- a/gstreamer-video/src/functions.rs +++ b/gstreamer-video/src/functions.rs @@ -201,17 +201,14 @@ pub fn video_make_raw_caps( ) -> gst::caps::Builder { assert_initialized_main_thread!(); - let formats: Vec = formats - .iter() - .map(|f| match f { - crate::VideoFormat::Encoded => panic!("Invalid encoded format"), - crate::VideoFormat::Unknown => panic!("Invalid unknown format"), - _ => f.to_string().to_send_value(), - }) - .collect(); + let formats = formats.iter().map(|f| match f { + crate::VideoFormat::Encoded => panic!("Invalid encoded format"), + crate::VideoFormat::Unknown => panic!("Invalid unknown format"), + _ => f.to_string().to_send_value(), + }); 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::::new(1, i32::MAX)) .field("height", gst::IntRange::::new(1, i32::MAX)) .field( diff --git a/gstreamer/src/value.rs b/gstreamer/src/value.rs index 5cb8ebd69..9d6c515f4 100644 --- a/gstreamer/src/value.rs +++ b/gstreamer/src/value.rs @@ -1,7 +1,6 @@ // Take a look at the license at the top of the repository in the LICENSE file. use num_rational::Rational32; -use std::borrow::{Borrow, Cow}; use std::cmp; use std::fmt; use std::ops; @@ -622,40 +621,30 @@ impl glib::value::ToValue for Bitmask { } #[derive(Clone, Debug)] -pub struct Array<'a>(Cow<'a, [glib::SendValue]>); +pub struct Array(Vec); -unsafe impl<'a> Send for Array<'a> {} -unsafe impl<'a> Sync for Array<'a> {} +unsafe impl Send for Array {} +unsafe impl Sync for Array {} -impl<'a> Array<'a> { - pub fn new(values: &[&(dyn ToSendValue + Sync)]) -> Self { +impl Array { + pub fn new(values: impl IntoIterator) -> Self { 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) -> Self { assert_initialized_main_thread!(); - Array(Cow::Borrowed(values.as_ref())) - } - - pub fn from_owned(values: Vec) -> Self { - assert_initialized_main_thread!(); - - Array(Cow::Owned(values)) - } - - pub fn into_owned(self) -> Array<'static> { - Array(self.0.into_owned().into()) + Self(values.into_iter().collect()) } 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]; 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> { - fn from(values: &'a [&'a (dyn ToSendValue + Sync)]) -> Self { - skip_assert_initialized!(); - - Self::new(values) +impl AsRef<[glib::SendValue]> for Array { + fn as_ref(&self) -> &[glib::SendValue] { + self.as_slice() } } -impl<'a> From<&'a [glib::SendValue]> for Array<'a> { - fn from(values: &'a [glib::SendValue]) -> Self { +impl std::iter::FromIterator for Array { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + Self::from_values(iter) + } +} + +impl From> for Array { + fn from(values: Vec) -> Self { 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; } -unsafe impl<'a> glib::value::FromValue<'a> for Array<'a> { +unsafe impl<'a> glib::value::FromValue<'a> for Array { type Checker = glib::value::GenericValueTypeChecker; 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() { - Array(Cow::Borrowed(&[])) + Self(Vec::new()) } else { #[allow(clippy::cast_ptr_alignment)] - Array(Cow::Borrowed(slice::from_raw_parts( - (*arr).data as *const glib::SendValue, - (*arr).len as usize, - ))) + Self::from_values( + slice::from_raw_parts((*arr).data as *const glib::SendValue, (*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 { - let mut value = glib::Value::for_value_type::>(); + let mut value = glib::Value::for_value_type::(); unsafe { for v in self.as_slice() { 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 { unsafe { from_glib(ffi::gst_value_array_get_type()) } } } -#[derive(Clone, Debug)] -pub struct List<'a>(Cow<'a, [glib::SendValue]>); +#[derive(Debug, Clone)] +pub struct ArrayRef<'a>(&'a [glib::SendValue]); -unsafe impl<'a> Send for List<'a> {} -unsafe impl<'a> Sync for List<'a> {} +unsafe impl<'a> Send for ArrayRef<'a> {} +unsafe impl<'a> Sync for ArrayRef<'a> {} -impl<'a> List<'a> { - pub fn new(values: &[&(dyn ToSendValue + Sync)]) -> Self { +impl<'a> ArrayRef<'a> { + pub fn new(values: &'a [glib::SendValue]) -> Self { 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 { - assert_initialized_main_thread!(); - - List(Cow::Borrowed(values.as_ref())) - } - - pub fn from_owned(values: Vec) -> 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() + pub fn as_slice(&self) -> &'a [glib::SendValue] { + self.0 } } -impl<'a> ops::Deref for List<'a> { +impl<'a> ops::Deref for ArrayRef<'a> { type Target = [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> { - fn from(values: &'a [&'a (dyn ToSendValue + Sync)]) -> Self { - skip_assert_initialized!(); - - Self::new(values) +impl<'a> AsRef<[glib::SendValue]> for ArrayRef<'a> { + fn as_ref(&self) -> &[glib::SendValue] { + self.as_slice() } } -impl<'a> From<&'a [glib::SendValue]> for List<'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> { +unsafe impl<'a> glib::value::FromValue<'a> for ArrayRef<'a> { type Checker = glib::value::GenericValueTypeChecker; 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() { - List(Cow::Borrowed(&[])) + Self(&[]) } else { #[allow(clippy::cast_ptr_alignment)] - List(Cow::Borrowed(slice::from_raw_parts( + Self(slice::from_raw_parts( (*arr).data as *const glib::SendValue, (*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 { - let mut value = glib::Value::for_value_type::>(); + let mut value = glib::Value::for_value_type::(); + 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); + +unsafe impl Send for List {} +unsafe impl Sync for List {} + +impl List { + pub fn new(values: impl IntoIterator) -> Self { + assert_initialized_main_thread!(); + + Self(values.into_iter().map(|v| v.to_send_value()).collect()) + } + + pub fn from_values(values: impl IntoIterator) -> 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 for List { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + Self::from_values(iter) + } +} + +impl From> for List { + fn from(values: Vec) -> 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; + + 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::(); unsafe { for v in self.as_slice() { 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; + + 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::(); + 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 { unsafe { from_glib(ffi::gst_value_list_get_type()) } } diff --git a/gstreamer/src/value_serde.rs b/gstreamer/src/value_serde.rs index 22348ec79..170782b03 100644 --- a/gstreamer/src/value_serde.rs +++ b/gstreamer/src/value_serde.rs @@ -37,7 +37,7 @@ pub(crate) static LIST_OTHER_TYPE_ID: Lazy = Lazy::new(List::static_ pub(crate) static SAMPLE_OTHER_TYPE_ID: Lazy = Lazy::new(Sample::static_type); pub(crate) static BUFFER_OTHER_TYPE_ID: Lazy = Lazy::new(Buffer::static_type); -impl<'a> Serialize for Fraction { +impl Serialize for Fraction { fn serialize(&self, serializer: S) -> Result { self.0.serialize(serializer) } @@ -150,7 +150,7 @@ impl Serialize for SendValue { macro_rules! impl_ser_send_value_collection ( ($t:ident) => ( - impl<'a> Serialize for $t<'a> { + impl Serialize for $t { fn serialize(&self, serializer: S) -> Result { let send_value_vec = unsafe { &*(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 ( ($t:ident) => { - impl<'a, 'de> Deserialize<'de> for $t<'a> { + impl<'de> Deserialize<'de> for $t { fn deserialize>(deserializer: D) -> Result { skip_assert_initialized!(); let send_value_vec = Vec::::deserialize(deserializer)?; - Ok($t::from_owned(unsafe{ + Ok($t::from_values(unsafe{ mem::transmute::, Vec>(send_value_vec) })) } @@ -348,19 +348,8 @@ mod tests { // Array let value_13 = Fraction::new(1, 3); 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 = None; - let array = Array::new(&[ - &value_13, - &value_12, - &value_str, - &value_str_none, - &value_date, - &value_date_none, - ]); + let array = Array::new(&[&value_13, &value_12]); let res = ron::ser::to_string_pretty(&array, pretty_config.clone()); assert_eq!( @@ -368,10 +357,6 @@ mod tests { r#"["#, r#" ("Fraction", (1, 3)),"#, r#" ("Fraction", (1, 2)),"#, - r#" ("String", Some("test str")),"#, - r#" ("String", None),"#, - r#" ("Date", Some(YMD(2019, 8, 19))),"#, - r#" ("Date", None),"#, r#"]"# ) .to_owned()), @@ -379,39 +364,16 @@ mod tests { ); let res = serde_json::to_string(&array).unwrap(); - assert_eq!( - r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"],["String",null],["Date",{"YMD":[2019,8,19]}],["Date",null]]"# - .to_owned(), - res - ); + assert_eq!(r#"[["Fraction",[1,3]],["Fraction",[1,2]]]"#.to_owned(), res); // List 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 = None; - let list = List::new(&[ - &value_12, - &value_str, - &value_str_none, - &value_date_time, - &value_date_time_none, - ]); + let list = List::new(&[&value_12]); let res = ron::ser::to_string_pretty(&list, pretty_config); assert_eq!( - Ok(concat!( - 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()), + Ok(concat!(r#"["#, r#" ("Fraction", (1, 2)),"#, r#"]"#).to_owned()), res, ); } @@ -624,19 +586,8 @@ mod tests { // Array let value_13 = Fraction::new(1, 3); 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 = None; - let array = Array::new(&[ - &value_13, - &value_12, - &value_str, - &value_str_none, - &value_date, - &value_date_none, - ]); + let array = Array::new(&[&value_13, &value_12]); let array_ser = ron::ser::to_string(&array).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.0.denom(), fraction.0.denom()); - assert_eq!( - slice_de[2].get::().expect("slice_de[2]"), - slice[2].get::().expect("slice[2]") - ); - - assert!(slice[3] - .get::>() - .expect("slice[3]") - .is_none()); - - assert_eq!( - slice_de[4].get::().expect("slice_de[4]"), - slice[4].get::().expect("slice[4]") - ); - - assert!(slice[5].get::>().expect("slice[5]").is_none()); - // List 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 = None; - let list = List::new(&[ - &value_12, - &value_str, - &value_str_none, - &value_date_time, - &value_date_time_none, - ]); + let list = List::new(&[&value_12]); let list_ser = ron::ser::to_string(&list).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::().expect("slice[0]"); assert_eq!(fraction_de.0.numer(), fraction.0.numer()); assert_eq!(fraction_de.0.denom(), fraction.0.denom()); - - assert_eq!( - slice_de[1].get::().expect("slice_de[1]"), - slice[1].get::().expect("slice[1]") - ); - - assert!(slice[2] - .get::>() - .expect("slice[2]") - .is_none()); - - assert_eq!( - slice_de[3].get::().expect("slice_de[3]"), - slice[3].get::().expect("slice[3]") - ); - - assert!(slice[4] - .get::>() - .expect("slice[4]") - .is_none()); } }