diff --git a/examples/src/bin/custom_events.rs b/examples/src/bin/custom_events.rs index 0d3b07e0e..c9e97f442 100644 --- a/examples/src/bin/custom_events.rs +++ b/examples/src/bin/custom_events.rs @@ -34,7 +34,7 @@ impl ExampleCustomEvent { _ => return None, // No structure in this event, or the name didn't match }; - let send_eos = s.get_some::("send_eos").unwrap(); + let send_eos = s.get::("send_eos").unwrap(); Some(ExampleCustomEvent { send_eos }) } _ => None, // Not a custom event diff --git a/examples/src/bin/decodebin.rs b/examples/src/bin/decodebin.rs index 49687d914..454544300 100644 --- a/examples/src/bin/decodebin.rs +++ b/examples/src/bin/decodebin.rs @@ -255,7 +255,11 @@ fn example_main() -> Result<(), Error> { Some(details) if details.name() == "error-details" => details .get::<&ErrorValue>("error") .unwrap() - .and_then(|v| v.0.lock().unwrap().take()) + .clone() + .0 + .lock() + .unwrap() + .take() .map(Result::Err) .expect("error-details message without actual error"), _ => Err(ErrorMessage { diff --git a/examples/src/bin/encodebin.rs b/examples/src/bin/encodebin.rs index 530d9a1d2..0864823d4 100644 --- a/examples/src/bin/encodebin.rs +++ b/examples/src/bin/encodebin.rs @@ -276,8 +276,11 @@ fn example_main() -> Result<(), Error> { Some(details) if details.name() == "error-details" => details .get::<&ErrorValue>("error") .unwrap() - .cloned() - .and_then(|v| v.0.lock().unwrap().take()) + .clone() + .0 + .lock() + .unwrap() + .take() .map(Result::Err) .expect("error-details message without actual error"), _ => Err(ErrorMessage { diff --git a/examples/src/bin/gtksink.rs b/examples/src/bin/gtksink.rs index 7c39a877d..1035ba227 100644 --- a/examples/src/bin/gtksink.rs +++ b/examples/src/bin/gtksink.rs @@ -37,7 +37,7 @@ fn create_ui(app: >k::Application) { // The gtkglsink creates the gtk widget for us. This is accessible through a property. // So we get it and use it later to add it to our gui. let widget = gtkglsink.property("widget").unwrap(); - (glsinkbin, widget.get::().unwrap().unwrap()) + (glsinkbin, widget.get::().unwrap()) } else { // Unfortunately, using the OpenGL widget didn't work out, so we will have to render // our frames manually, using the CPU. An example why this may fail is, when @@ -46,7 +46,7 @@ fn create_ui(app: >k::Application) { // The gtksink creates the gtk widget for us. This is accessible through a property. // So we get it and use it later to add it to our gui. let widget = sink.property("widget").unwrap(); - (sink, widget.get::().unwrap().unwrap()) + (sink, widget.get::().unwrap()) }; pipeline.add_many(&[&src, &sink]).unwrap(); diff --git a/examples/src/bin/overlay-composition.rs b/examples/src/bin/overlay-composition.rs index c48ee753f..6ac1ad958 100644 --- a/examples/src/bin/overlay-composition.rs +++ b/examples/src/bin/overlay-composition.rs @@ -139,8 +139,8 @@ fn create_pipeline() -> Result { let drawer = drawer.lock().unwrap(); // Get the signal's arguments - let _overlay = args[0].get::().unwrap().unwrap(); - let sample = args[1].get::().unwrap().unwrap(); + let _overlay = args[0].get::().unwrap(); + let sample = args[1].get::().unwrap(); let buffer = sample.buffer().unwrap(); let timestamp = buffer.pts(); @@ -276,8 +276,8 @@ fn create_pipeline() -> Result { // stream that dynamically changes resolution when enough bandwith is available. overlay .connect("caps-changed", false, move |args| { - let _overlay = args[0].get::().unwrap().unwrap(); - let caps = args[1].get::().unwrap().unwrap(); + let _overlay = args[0].get::().unwrap(); + let caps = args[1].get::().unwrap(); let mut drawer = drawer.lock().unwrap(); drawer.info = Some(gst_video::VideoInfo::from_caps(&caps).unwrap()); diff --git a/examples/src/bin/pango-cairo.rs b/examples/src/bin/pango-cairo.rs index 645097584..4763a8e7a 100644 --- a/examples/src/bin/pango-cairo.rs +++ b/examples/src/bin/pango-cairo.rs @@ -133,12 +133,12 @@ fn create_pipeline() -> Result { let drawer = drawer.lock().unwrap(); // Get the signal's arguments - let _overlay = args[0].get::().unwrap().unwrap(); + let _overlay = args[0].get::().unwrap(); // This is the cairo context. This is the root of all of cairo's // drawing functionality. - let cr = args[1].get::().unwrap().unwrap(); - let timestamp = args[2].get_some::().unwrap(); - let _duration = args[3].get_some::().unwrap(); + let cr = args[1].get::().unwrap(); + let timestamp = args[2].get::().unwrap(); + let _duration = args[3].get::().unwrap(); let info = drawer.info.as_ref().unwrap(); let layout = drawer.layout.borrow(); @@ -207,8 +207,8 @@ fn create_pipeline() -> Result { // stream that dynamically changes resolution when enough bandwith is available. overlay .connect("caps-changed", false, move |args| { - let _overlay = args[0].get::().unwrap().unwrap(); - let caps = args[1].get::().unwrap().unwrap(); + let _overlay = args[0].get::().unwrap(); + let caps = args[1].get::().unwrap(); let mut drawer = drawer.lock().unwrap(); drawer.info = Some(gst_video::VideoInfo::from_caps(&caps).unwrap()); diff --git a/examples/src/bin/playbin.rs b/examples/src/bin/playbin.rs index 4c8593277..954002c4e 100644 --- a/examples/src/bin/playbin.rs +++ b/examples/src/bin/playbin.rs @@ -57,12 +57,11 @@ fn example_main() { // mark the beginning of a new track, or a new DJ. let playbin = values[0] .get::() - .expect("playbin \"audio-tags-changed\" signal values[1]") - .unwrap(); + .expect("playbin \"audio-tags-changed\" signal values[1]"); // This gets the index of the stream that changed. This is neccessary, since // there could e.g. be multiple audio streams (english, spanish, ...). let idx = values[1] - .get_some::() + .get::() .expect("playbin \"audio-tags-changed\" signal values[1]"); println!("audio tags of audio stream {} changed:", idx); @@ -81,18 +80,18 @@ fn example_main() { .emit_by_name("get-audio-tags", &[&idx]) .unwrap() .unwrap(); - let tags = tags.get::().expect("tags").unwrap(); + let tags = tags.get::().expect("tags"); if let Some(artist) = tags.get::() { - println!(" Artist: {}", artist.get().unwrap()); + println!(" Artist: {}", artist.get()); } if let Some(title) = tags.get::() { - println!(" Title: {}", title.get().unwrap()); + println!(" Title: {}", title.get()); } if let Some(album) = tags.get::() { - println!(" Album: {}", album.get().unwrap()); + println!(" Album: {}", album.get()); } None diff --git a/examples/src/bin/rtpfecclient.rs b/examples/src/bin/rtpfecclient.rs index 579405614..37017753f 100644 --- a/examples/src/bin/rtpfecclient.rs +++ b/examples/src/bin/rtpfecclient.rs @@ -87,8 +87,7 @@ fn make_fec_decoder(rtpbin: &gst::Element, sess_id: u32) -> Result() - .unwrap() - .expect("No internal-storage"); + .unwrap(); fecdec.set_property("storage", &internal_storage)?; fecdec.set_property("pt", &100u32)?; @@ -145,8 +144,7 @@ fn example_main() -> Result<(), Error> { rtpbin.connect("new-storage", false, |values| { let storage = values[1] .get::() - .expect("rtpbin \"new-storage\" signal values[1]") - .expect("rtpbin \"new-storage\" signal values[1]: no `Element`"); + .expect("rtpbin \"new-storage\" signal values[1]"); storage.set_property("size-time", &250_000_000u64).unwrap(); None @@ -154,7 +152,7 @@ fn example_main() -> Result<(), Error> { rtpbin.connect("request-pt-map", false, |values| { let pt = values[2] - .get_some::() + .get::() .expect("rtpbin \"new-storage\" signal values[2]"); match pt { 100 => Some( @@ -186,10 +184,9 @@ fn example_main() -> Result<(), Error> { rtpbin.connect("request-fec-decoder", false, |values| { let rtpbin = values[0] .get::() - .expect("rtpbin \"request-fec-decoder\" signal values[0]") - .expect("rtpbin \"request-fec-decoder\" signal values[0]: no `Element`"); + .expect("rtpbin \"request-fec-decoder\" signal values[0]"); let sess_id = values[1] - .get_some::() + .get::() .expect("rtpbin \"request-fec-decoder\" signal values[1]"); match make_fec_decoder(&rtpbin, sess_id) { diff --git a/examples/src/bin/rtpfecserver.rs b/examples/src/bin/rtpfecserver.rs index a8b92e4a9..28bb3af9f 100644 --- a/examples/src/bin/rtpfecserver.rs +++ b/examples/src/bin/rtpfecserver.rs @@ -109,8 +109,7 @@ fn example_main() -> Result<(), Error> { rtpbin.connect("request-fec-encoder", false, move |values| { let rtpbin = values[0] .get::() - .expect("rtpbin \"request-fec-encoder\" signal values[0]") - .expect("rtpbin \"request-fec-encoder\" signal values[0]: no `Element`"); + .expect("rtpbin \"request-fec-encoder\" signal values[0]"); match make_fec_encoder(fec_percentage) { Ok(elem) => Some(elem.to_value()), diff --git a/examples/src/bin/transmux.rs b/examples/src/bin/transmux.rs index 9c3c8fa87..977ea6666 100644 --- a/examples/src/bin/transmux.rs +++ b/examples/src/bin/transmux.rs @@ -100,8 +100,7 @@ fn example_main() -> Result<(), Error> { // much more corner-cases. This is just for the sake of being an example. let caps = values[2] .get::() - .expect("typefinder \"have-type\" signal values[2]") - .expect("typefinder \"have-type\" signal values[2]: no `caps`"); + .expect("typefinder \"have-type\" signal values[2]"); let format_name = caps.structure(0).expect("Failed to get format name").name(); let demuxer = match format_name { diff --git a/examples/src/glupload.rs b/examples/src/glupload.rs index 9cb4848b0..170ee5100 100644 --- a/examples/src/glupload.rs +++ b/examples/src/glupload.rs @@ -683,7 +683,7 @@ pub(crate) fn main_loop(app: App) -> Result<(), Error> { gst_gl_context = glupload .property("context") .unwrap() - .get::() + .get::>() .unwrap(); } diff --git a/gstreamer-audio/src/audio_converter.rs b/gstreamer-audio/src/audio_converter.rs index e3fd409f4..fc5080f00 100644 --- a/gstreamer-audio/src/audio_converter.rs +++ b/gstreamer-audio/src/audio_converter.rs @@ -150,15 +150,12 @@ impl AudioConverterConfig { .as_slice() .iter() .map(|val| { - let array = val - .get::() - .expect("Wrong type") - .unwrap_or_else(|| gst::Array::from_owned(Vec::new())); + let array = val.get::().expect("Wrong type"); array .as_slice() .iter() - .map(|val| val.get_some::().expect("Wrong type")) + .map(|val| val.get::().expect("Wrong type")) .collect::>() }) .collect::>() diff --git a/gstreamer-audio/src/audio_format_info.rs b/gstreamer-audio/src/audio_format_info.rs index c28db2b45..4dbe79557 100644 --- a/gstreamer-audio/src/audio_format_info.rs +++ b/gstreamer-audio/src/audio_format_info.rs @@ -5,7 +5,8 @@ use std::ffi::CStr; use std::fmt; use std::str; -use glib::translate::{from_glib, FromGlib, FromGlibPtrNone, ToGlib, ToGlibPtr, ToGlibPtrMut}; +use glib::translate::{from_glib, from_glib_none, FromGlib, ToGlib, ToGlibPtr, ToGlibPtrMut}; +use glib::StaticType; #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] pub enum AudioEndianness { @@ -313,34 +314,51 @@ impl glib::types::StaticType for AudioFormatInfo { } } +impl glib::value::ValueType for AudioFormatInfo { + type Type = Self; +} + #[doc(hidden)] -impl<'a> glib::value::FromValueOptional<'a> for AudioFormatInfo { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstAudioFormatInfo) +unsafe impl<'a> glib::value::FromValue<'a> for AudioFormatInfo { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) + as *mut ffi::GstAudioFormatInfo) } } #[doc(hidden)] -impl glib::value::SetValue for AudioFormatInfo { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstAudioFormatInfo>::to_glib_none(this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for AudioFormatInfo { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } #[doc(hidden)] -impl glib::value::SetValueOptional for AudioFormatInfo { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstAudioFormatInfo>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValueOptional for AudioFormatInfo { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } diff --git a/gstreamer-audio/src/audio_info.rs b/gstreamer-audio/src/audio_info.rs index 356bc3890..78abf1a0c 100644 --- a/gstreamer-audio/src/audio_info.rs +++ b/gstreamer-audio/src/audio_info.rs @@ -1,8 +1,6 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use glib::translate::{ - from_glib, from_glib_full, from_glib_none, FromGlibPtrNone, ToGlib, ToGlibPtr, ToGlibPtrMut, -}; +use glib::translate::{from_glib, from_glib_full, from_glib_none, ToGlib, ToGlibPtr, ToGlibPtrMut}; use gst::prelude::*; use std::fmt; @@ -324,34 +322,52 @@ impl glib::types::StaticType for AudioInfo { } } -#[doc(hidden)] -impl<'a> glib::value::FromValueOptional<'a> for AudioInfo { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstAudioInfo) - } +impl glib::value::ValueType for AudioInfo { + type Type = Self; } #[doc(hidden)] -impl glib::value::SetValue for AudioInfo { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstAudioInfo>::to_glib_none(this).0 - as glib::ffi::gpointer, +unsafe impl<'a> glib::value::FromValue<'a> for AudioInfo { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none( + glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstAudioInfo ) } } #[doc(hidden)] -impl glib::value::SetValueOptional for AudioInfo { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstAudioInfo>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for AudioInfo { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[doc(hidden)] +impl glib::value::ToValueOptional for AudioInfo { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } diff --git a/gstreamer-base/src/aggregator.rs b/gstreamer-base/src/aggregator.rs index f332d0b7b..8a7772312 100644 --- a/gstreamer-base/src/aggregator.rs +++ b/gstreamer-base/src/aggregator.rs @@ -135,7 +135,6 @@ impl> AggregatorExtManual for O { value .get() .expect("AggregatorExtManual::min_upstream_latency") - .unwrap() } } diff --git a/gstreamer-editing-services/src/lib.rs b/gstreamer-editing-services/src/lib.rs index 4bc1b23df..f23e56c96 100644 --- a/gstreamer-editing-services/src/lib.rs +++ b/gstreamer-editing-services/src/lib.rs @@ -51,6 +51,7 @@ macro_rules! skip_assert_initialized { #[allow(clippy::unreadable_literal)] #[allow(clippy::too_many_arguments)] #[allow(clippy::match_same_arms)] +#[allow(unused_imports)] mod auto; pub use crate::auto::*; diff --git a/gstreamer-gl/src/lib.rs b/gstreamer-gl/src/lib.rs index e15b83009..06dd442d0 100644 --- a/gstreamer-gl/src/lib.rs +++ b/gstreamer-gl/src/lib.rs @@ -22,6 +22,7 @@ macro_rules! skip_assert_initialized { #[allow(clippy::unreadable_literal)] #[allow(clippy::too_many_arguments)] #[allow(clippy::match_same_arms)] +#[allow(unused_imports)] mod auto; pub use crate::auto::*; diff --git a/gstreamer-net/src/lib.rs b/gstreamer-net/src/lib.rs index 4132907d3..387f96763 100644 --- a/gstreamer-net/src/lib.rs +++ b/gstreamer-net/src/lib.rs @@ -21,6 +21,7 @@ macro_rules! skip_assert_initialized { #[allow(clippy::unreadable_literal)] #[allow(clippy::too_many_arguments)] #[allow(clippy::match_same_arms)] +#[allow(unused_imports)] mod auto; pub use crate::auto::*; mod net_client_clock; diff --git a/gstreamer-pbutils/src/discoverer.rs b/gstreamer-pbutils/src/discoverer.rs index 494361bab..08be0c006 100644 --- a/gstreamer-pbutils/src/discoverer.rs +++ b/gstreamer-pbutils/src/discoverer.rs @@ -32,10 +32,7 @@ impl Discoverer { value.to_glib_none_mut().0, ); } - value - .get() - .expect("Discoverer::get_property_timeout") - .unwrap() + value.get().expect("Discoverer::get_property_timeout") } pub fn connect_property_timeout_notify( diff --git a/gstreamer-player/src/lib.rs b/gstreamer-player/src/lib.rs index e92e12eec..a7a89b47d 100644 --- a/gstreamer-player/src/lib.rs +++ b/gstreamer-player/src/lib.rs @@ -19,6 +19,7 @@ macro_rules! assert_initialized_main_thread { #[allow(clippy::match_same_arms)] #[allow(clippy::type_complexity)] #[allow(clippy::cast_ptr_alignment)] +#[allow(unused_imports)] mod auto; pub use crate::auto::*; diff --git a/gstreamer-rtsp-server/src/rtsp_token.rs b/gstreamer-rtsp-server/src/rtsp_token.rs index f3181725d..c52955371 100644 --- a/gstreamer-rtsp-server/src/rtsp_token.rs +++ b/gstreamer-rtsp-server/src/rtsp_token.rs @@ -15,7 +15,7 @@ impl RTSPToken { unsafe { from_glib_full(ffi::gst_rtsp_token_new_empty()) } } - pub fn new(values: &[(&str, &dyn ToSendValue)]) -> Self { + pub fn new(values: &[(&str, &(dyn ToSendValue + Sync))]) -> Self { assert_initialized_main_thread!(); let mut token = RTSPToken::new_empty(); diff --git a/gstreamer-sdp/src/sdp_message.rs b/gstreamer-sdp/src/sdp_message.rs index 485e6a27e..ff079cef8 100644 --- a/gstreamer-sdp/src/sdp_message.rs +++ b/gstreamer-sdp/src/sdp_message.rs @@ -8,6 +8,7 @@ use std::ops; use std::ptr; use glib::translate::*; +use glib::StaticType; use crate::sdp_attribute::SDPAttribute; use crate::sdp_bandwidth::SDPBandwidth; @@ -882,36 +883,44 @@ impl glib::types::StaticType for SDPMessageRef { } } -impl<'a> glib::value::FromValueOptional<'a> for &'a SDPMessageRef { - unsafe fn from_value_optional(v: &'a glib::Value) -> Option { - let ptr = glib::gobject_ffi::g_value_get_boxed(v.to_glib_none().0); - if ptr.is_null() { - None - } else { - Some(&*(ptr as *const SDPMessageRef)) - } +unsafe impl<'a> glib::value::FromValue<'a> for &'a SDPMessageRef { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + &*(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut SDPMessageRef) } } -impl glib::value::SetValue for SDPMessageRef { - unsafe fn set_value(v: &mut glib::Value, s: &Self) { - glib::gobject_ffi::g_value_set_boxed( - v.to_glib_none_mut().0, - s as *const SDPMessageRef as glib::ffi::gpointer, - ); - } -} - -impl glib::value::SetValueOptional for SDPMessageRef { - unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) { - if let Some(s) = s { +impl glib::value::ToValue for SDPMessageRef { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { glib::gobject_ffi::g_value_set_boxed( - v.to_glib_none_mut().0, - s as *const SDPMessageRef as glib::ffi::gpointer, - ); - } else { - glib::gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut()); + value.to_glib_none_mut().0, + &self.0 as *const ffi::GstSDPMessage as *mut _, + ) } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl glib::value::ToValueOptional for SDPMessageRef { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.map(|s| &s.0 as *const ffi::GstSDPMessage) + .unwrap_or(ptr::null()) as *mut _, + ) + } + value } } diff --git a/gstreamer-video/src/video_event.rs b/gstreamer-video/src/video_event.rs index 5810319e9..e9713fc6b 100644 --- a/gstreamer-video/src/video_event.rs +++ b/gstreamer-video/src/video_event.rs @@ -21,7 +21,10 @@ macro_rules! event_builder_generic_impl { } } - pub fn other_fields(self, other_fields: &[(&'a str, &'a dyn ToSendValue)]) -> Self { + pub fn other_fields( + self, + other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))], + ) -> Self { Self { other_fields: self .other_fields @@ -64,7 +67,7 @@ macro_rules! event_builder_generic_impl { pub struct DownstreamForceKeyUnitEventBuilder<'a> { seqnum: Option, running_time_offset: Option, - other_fields: Vec<(&'a str, &'a dyn ToSendValue)>, + other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>, timestamp: gst::ClockTime, stream_time: gst::ClockTime, running_time: gst::ClockTime, @@ -178,7 +181,7 @@ impl DownstreamForceKeyUnitEvent { pub struct UpstreamForceKeyUnitEventBuilder<'a> { seqnum: Option, running_time_offset: Option, - other_fields: Vec<(&'a str, &'a dyn ToSendValue)>, + other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>, running_time: gst::ClockTime, all_headers: bool, count: u32, @@ -289,7 +292,7 @@ impl ForceKeyUnitEvent { pub struct StillFrameEventBuilder<'a> { seqnum: Option, running_time_offset: Option, - other_fields: Vec<(&'a str, &'a dyn ToSendValue)>, + other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>, in_still: bool, } diff --git a/gstreamer-video/src/video_info.rs b/gstreamer-video/src/video_info.rs index 50340555e..a6605c002 100644 --- a/gstreamer-video/src/video_info.rs +++ b/gstreamer-video/src/video_info.rs @@ -1,8 +1,8 @@ // Take a look at the license at the top of the repository in the LICENSE file. use glib::translate::{ - from_glib, from_glib_full, from_glib_none, FromGlib, FromGlibPtrFull, FromGlibPtrNone, ToGlib, - ToGlibPtr, ToGlibPtrMut, + from_glib, from_glib_full, from_glib_none, FromGlib, FromGlibPtrFull, ToGlib, ToGlibPtr, + ToGlibPtrMut, }; use gst::prelude::*; @@ -55,21 +55,28 @@ impl glib::StaticType for VideoColorRange { } } -impl<'a> glib::value::FromValueOptional<'a> for VideoColorRange { - unsafe fn from_value_optional(value: &glib::value::Value) -> Option { - Some(glib::value::FromValue::from_value(value)) - } +impl glib::value::ValueType for VideoColorRange { + type Type = Self; } -impl<'a> glib::value::FromValue<'a> for VideoColorRange { - unsafe fn from_value(value: &glib::value::Value) -> Self { +unsafe impl<'a> glib::value::FromValue<'a> for VideoColorRange { + type Checker = glib::value::GenericValueTypeChecker; + + unsafe fn from_value(value: &glib::Value) -> Self { + skip_assert_initialized!(); from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) } } -impl glib::value::SetValue for VideoColorRange { - unsafe fn set_value(value: &mut glib::value::Value, this: &Self) { - glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib() as i32) +impl glib::value::ToValue for VideoColorRange { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.to_glib()) } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } @@ -858,34 +865,52 @@ impl glib::types::StaticType for VideoInfo { } } -#[doc(hidden)] -impl<'a> glib::value::FromValueOptional<'a> for VideoInfo { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstVideoInfo) - } +impl glib::value::ValueType for VideoInfo { + type Type = Self; } #[doc(hidden)] -impl glib::value::SetValue for VideoInfo { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstVideoInfo>::to_glib_none(this).0 - as glib::ffi::gpointer, +unsafe impl<'a> glib::value::FromValue<'a> for VideoInfo { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none( + glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstVideoInfo ) } } #[doc(hidden)] -impl glib::value::SetValueOptional for VideoInfo { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstVideoInfo>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for VideoInfo { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[doc(hidden)] +impl glib::value::ToValueOptional for VideoInfo { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } diff --git a/gstreamer-video/src/video_time_code.rs b/gstreamer-video/src/video_time_code.rs index bcc1bd3e6..9db363c20 100644 --- a/gstreamer-video/src/video_time_code.rs +++ b/gstreamer-video/src/video_time_code.rs @@ -2,7 +2,6 @@ use glib::prelude::*; use glib::translate::*; -use glib::value; use gst::prelude::*; use std::cmp; use std::convert::{TryFrom, TryInto}; @@ -429,34 +428,51 @@ macro_rules! generic_impl { } } + impl glib::value::ValueType for $name { + type Type = Self; + } + #[doc(hidden)] - impl<'a> value::FromValueOptional<'a> for $name { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::<$name>::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstVideoTimeCode) + unsafe impl<'a> glib::value::FromValue<'a> for $name { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) + as *mut ffi::GstVideoTimeCode) } } #[doc(hidden)] - impl value::SetValue for $name { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - ToGlibPtr::<*const ffi::GstVideoTimeCode>::to_glib_none(this).0 - as glib::ffi::gpointer, - ) + impl glib::value::ToValue for $name { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<$name>(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } #[doc(hidden)] - impl value::SetValueOptional for $name { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - ToGlibPtr::<*const ffi::GstVideoTimeCode>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) + impl glib::value::ToValueOptional for $name { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::<$name>(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } }; diff --git a/gstreamer-video/src/video_time_code_interval.rs b/gstreamer-video/src/video_time_code_interval.rs index a1b916e4d..8f272d924 100644 --- a/gstreamer-video/src/video_time_code_interval.rs +++ b/gstreamer-video/src/video_time_code_interval.rs @@ -2,7 +2,6 @@ use glib::prelude::*; use glib::translate::*; -use glib::value; use std::cmp; use std::fmt; use std::mem; @@ -201,34 +200,50 @@ impl StaticType for VideoTimeCodeInterval { } } +impl glib::value::ValueType for VideoTimeCodeInterval { + type Type = Self; +} + #[doc(hidden)] -impl<'a> value::FromValueOptional<'a> for VideoTimeCodeInterval { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::::from_glib_full(glib::gobject_ffi::g_value_dup_boxed( - value.to_glib_none().0, - ) +unsafe impl<'a> glib::value::FromValue<'a> for VideoTimeCodeInterval { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstVideoTimeCodeInterval) } } #[doc(hidden)] -impl value::SetValue for VideoTimeCodeInterval { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - ToGlibPtr::<*const ffi::GstVideoTimeCodeInterval>::to_glib_none(this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for VideoTimeCodeInterval { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } #[doc(hidden)] -impl value::SetValueOptional for VideoTimeCodeInterval { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - ToGlibPtr::<*const ffi::GstVideoTimeCodeInterval>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValueOptional for VideoTimeCodeInterval { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } diff --git a/gstreamer-webrtc/src/lib.rs b/gstreamer-webrtc/src/lib.rs index 454e916f6..b988f7f03 100644 --- a/gstreamer-webrtc/src/lib.rs +++ b/gstreamer-webrtc/src/lib.rs @@ -22,6 +22,7 @@ macro_rules! skip_assert_initialized { #[allow(clippy::unreadable_literal)] #[allow(clippy::too_many_arguments)] #[allow(clippy::match_same_arms)] +#[allow(unused_imports)] mod auto; pub use crate::auto::*; diff --git a/gstreamer/src/caps.rs b/gstreamer/src/caps.rs index f22c19620..d50d214d0 100644 --- a/gstreamer/src/caps.rs +++ b/gstreamer/src/caps.rs @@ -45,7 +45,7 @@ impl Caps { unsafe { from_glib_full(ffi::gst_caps_new_any()) } } - pub fn new_simple(name: &str, values: &[(&str, &dyn ToSendValue)]) -> Self { + pub fn new_simple(name: &str, values: &[(&str, &(dyn ToSendValue + Sync))]) -> Self { assert_initialized_main_thread!(); let mut caps = Caps::new_empty(); @@ -165,7 +165,7 @@ impl str::FromStr for Caps { } impl CapsRef { - pub fn set_simple(&mut self, values: &[(&str, &dyn ToSendValue)]) { + pub fn set_simple(&mut self, values: &[(&str, &(dyn ToSendValue + Sync))]) { for &(name, value) in values { let value = value.to_value(); @@ -610,7 +610,7 @@ impl Builder { } impl Builder { - pub fn field<'b, V: ToSendValue>(mut self, name: &'b str, value: &'b V) -> Self { + pub fn field(mut self, name: &str, value: V) -> Self { self.s.set(name, value); self } @@ -777,11 +777,11 @@ mod tests { crate::init().unwrap(); let caps = Caps::builder("foo/bar") - .field("int", &12) - .field("bool", &true) - .field("string", &"bla") - .field("fraction", &Fraction::new(1, 2)) - .field("array", &Array::new(&[&1, &2])) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) .build(); assert_eq!( caps.to_string(), diff --git a/gstreamer/src/caps_features.rs b/gstreamer/src/caps_features.rs index 74af9265a..a4d471c39 100644 --- a/gstreamer/src/caps_features.rs +++ b/gstreamer/src/caps_features.rs @@ -10,11 +10,8 @@ use std::str; use once_cell::sync::Lazy; -use glib::ffi::gpointer; -use glib::translate::{ - from_glib, from_glib_full, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault, Stash, StashMut, - ToGlibPtr, ToGlibPtrMut, -}; +use glib::translate::*; +use glib::StaticType; pub struct CapsFeatures(ptr::NonNull); unsafe impl Send for CapsFeatures {} @@ -217,25 +214,48 @@ impl FromGlibPtrFull<*mut ffi::GstCapsFeatures> for CapsFeatures { } } -impl<'a> glib::value::FromValueOptional<'a> for CapsFeatures { - unsafe fn from_value_optional(v: &'a glib::Value) -> Option { - <&'a CapsFeaturesRef as glib::value::FromValueOptional<'a>>::from_value_optional(v) - .map(ToOwned::to_owned) +impl glib::value::ValueType for CapsFeatures { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for CapsFeatures { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) + as *mut ffi::GstCapsFeatures) } } -impl glib::value::SetValue for CapsFeatures { - unsafe fn set_value(v: &mut glib::Value, s: &Self) { - ::set_value(v, s.as_ref()) +impl glib::value::ToValue for CapsFeatures { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + ToGlibPtr::<*mut ffi::GstCapsFeatures>::to_glib_none(self).0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } -impl glib::value::SetValueOptional for CapsFeatures { - unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) { - ::set_value_optional( - v, - s.map(|s| s.as_ref()), - ) +impl glib::value::ToValueOptional for CapsFeatures { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + ToGlibPtr::<*mut ffi::GstCapsFeatures>::to_glib_none(&s).0 as *mut _, + ) + } + value } } @@ -334,32 +354,43 @@ impl glib::types::StaticType for CapsFeaturesRef { } } -impl<'a> glib::value::FromValueOptional<'a> for &'a CapsFeaturesRef { - unsafe fn from_value_optional(v: &'a glib::Value) -> Option { - let ptr = glib::gobject_ffi::g_value_get_boxed(v.to_glib_none().0); - if ptr.is_null() { - None - } else { - Some(CapsFeaturesRef::from_glib_borrow( - ptr as *const ffi::GstCapsFeatures, - )) - } +unsafe impl<'a> glib::value::FromValue<'a> for &'a CapsFeaturesRef { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + &*(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const CapsFeaturesRef) } } -impl glib::value::SetValue for CapsFeaturesRef { - unsafe fn set_value(v: &mut glib::Value, s: &Self) { - glib::gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer); +impl glib::value::ToValue for CapsFeaturesRef { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.as_mut_ptr() as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } -impl glib::value::SetValueOptional for CapsFeaturesRef { - unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) { - if let Some(s) = s { - glib::gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer); - } else { - glib::gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut()); +impl glib::value::ToValueOptional for CapsFeaturesRef { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.map(|s| s.as_mut_ptr()).unwrap_or(ptr::null_mut()) as *mut _, + ) } + value } } @@ -478,11 +509,13 @@ mod tests { #[test] fn test_from_value_optional() { + use glib::ToValue; + crate::init().unwrap(); - let a = glib::value::Value::from(None::<&CapsFeatures>); - assert!(a.get::().unwrap().is_none()); + let a = None::.to_value(); + assert!(a.get::>().unwrap().is_none()); let b = glib::value::Value::from(&CapsFeatures::new_empty()); - assert!(b.get::().unwrap().is_some()); + assert!(b.get::>().unwrap().is_some()); } } diff --git a/gstreamer/src/caps_serde.rs b/gstreamer/src/caps_serde.rs index 62d31cd97..a36f0aa23 100644 --- a/gstreamer/src/caps_serde.rs +++ b/gstreamer/src/caps_serde.rs @@ -233,11 +233,11 @@ mod tests { crate::init().unwrap(); let caps = Caps::builder("foo/bar") - .field("int", &12) - .field("bool", &true) - .field("string", &"bla") - .field("fraction", &Fraction::new(1, 2)) - .field("array", &Array::new(&[&1, &2])) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) .build(); let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string()); @@ -263,11 +263,11 @@ mod tests { ); let caps = Caps::builder("foo/bar") - .field("int", &12) - .field("bool", &true) - .field("string", &"bla") - .field("fraction", &Fraction::new(1, 2)) - .field("array", &Array::new(&[&1, &2])) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) .features(&["foo:bar", "foo:baz"]) .build(); @@ -297,11 +297,11 @@ mod tests { ); let caps = Caps::builder("foo/bar") - .field("int", &12) - .field("bool", &true) - .field("string", &"bla") - .field("fraction", &Fraction::new(1, 2)) - .field("array", &Array::new(&[&1, &2])) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) .any_features() .build(); @@ -370,17 +370,14 @@ mod tests { let s = caps.structure(0).unwrap(); assert_eq!( s, - Structure::new( - "foo/bar", - &[ - ("int", &12), - ("bool", &true), - ("string", &"bla"), - ("fraction", &Fraction::new(1, 2)), - ("array", &Array::new(&[&1, &2])), - ], - ) - .as_ref() + Structure::builder("foo/bar",) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) + .build() + .as_ref() ); let caps_ron = r#" @@ -404,17 +401,14 @@ mod tests { let str_none: Option<&str> = None; assert_eq!( s, - Structure::new( - "foo/bar", - &[ - ("int", &12), - ("bool", &true), - ("string", &str_none), - ("fraction", &Fraction::new(1, 2)), - ("array", &Array::new(&[&1, &2])), - ], - ) - .as_ref() + Structure::builder("foo/bar",) + .field("int", 12) + .field("bool", true) + .field("string", str_none) + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) + .build() + .as_ref() ); let f = caps.features(0).unwrap(); assert!(f.is_equal(CapsFeatures::new(&["foo:bar", "foo:baz"]).as_ref())); @@ -439,17 +433,14 @@ mod tests { let s = caps.structure(0).unwrap(); assert_eq!( s, - Structure::new( - "foo/bar", - &[ - ("int", &12), - ("bool", &true), - ("string", &"bla"), - ("fraction", &Fraction::new(1, 2)), - ("array", &Array::new(&[&1, &2])), - ], - ) - .as_ref() + Structure::builder("foo/bar",) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) + .build() + .as_ref() ); let f = caps.features(0).unwrap(); assert!(f.is_any()); @@ -470,22 +461,22 @@ mod tests { assert!(caps_de.is_empty()); let caps = Caps::builder("foo/bar") - .field("int", &12) - .field("bool", &true) - .field("string", &"bla") - .field("fraction", &Fraction::new(1, 2)) - .field("array", &Array::new(&[&1, &2])) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) .build(); let caps_ser = ron::ser::to_string(&caps).unwrap(); let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap(); assert!(caps_de.is_strictly_equal(&caps)); let caps = Caps::builder("foo/bar") - .field("int", &12) - .field("bool", &true) - .field("string", &"bla") - .field("fraction", &Fraction::new(1, 2)) - .field("array", &Array::new(&[&1, &2])) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) .features(&["foo:bar", "foo:baz"]) .build(); let caps_ser = ron::ser::to_string(&caps).unwrap(); @@ -493,11 +484,11 @@ mod tests { assert!(caps_de.is_strictly_equal(&caps)); let caps = Caps::builder("foo/bar") - .field("int", &12) - .field("bool", &true) - .field("string", &"bla") - .field("fraction", &Fraction::new(1, 2)) - .field("array", &Array::new(&[&1, &2])) + .field("int", 12) + .field("bool", true) + .field("string", "bla") + .field("fraction", Fraction::new(1, 2)) + .field("array", Array::new(&[&1, &2])) .any_features() .build(); let caps_ser = ron::ser::to_string(&caps).unwrap(); diff --git a/gstreamer/src/clock_time.rs b/gstreamer/src/clock_time.rs index 42415155c..d9c084ce4 100644 --- a/gstreamer/src/clock_time.rs +++ b/gstreamer/src/clock_time.rs @@ -1,6 +1,7 @@ // Take a look at the license at the top of the repository in the LICENSE file. use glib::translate::*; +use glib::StaticType; use num_integer::div_rem; use std::io::{self, prelude::*}; use std::time::Duration; @@ -304,25 +305,32 @@ impl FromGlib for ClockTime { } } +impl glib::value::ValueType for ClockTime { + type Type = Self; +} + #[doc(hidden)] -impl<'a> glib::value::FromValueOptional<'a> for ClockTime { - unsafe fn from_value_optional(value: &'a glib::Value) -> Option { - ::from_value_optional(value) - .map(|x| ClockTime::from_glib(x)) +unsafe impl<'a> glib::value::FromValue<'a> for ClockTime { + type Checker = glib::value::GenericValueTypeChecker; + + unsafe fn from_value(value: &glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_uint64( + value.to_glib_none().0, + )) } } #[doc(hidden)] -impl<'a> glib::value::FromValue<'a> for ClockTime { - unsafe fn from_value(value: &'a glib::Value) -> Self { - ClockTime::from_glib(::from_value(value)) +impl glib::value::ToValue for ClockTime { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { glib::gobject_ffi::g_value_set_uint64(value.to_glib_none_mut().0, self.to_glib()) } + value } -} -#[doc(hidden)] -impl glib::value::SetValue for ClockTime { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - ::set_value(value, &this.to_glib()); + fn value_type(&self) -> glib::Type { + Self::static_type() } } diff --git a/gstreamer/src/date_time_serde.rs b/gstreamer/src/date_time_serde.rs index 5681e26f7..1fedde466 100644 --- a/gstreamer/src/date_time_serde.rs +++ b/gstreamer/src/date_time_serde.rs @@ -3,7 +3,7 @@ use std::convert::{TryFrom, TryInto}; use glib::translate::{FromGlib, ToGlib}; -use glib::value::{SetValue, SetValueOptional}; +use glib::value::{ToValue, ToValueOptional}; use glib::StaticType; use crate::DateTime; @@ -33,15 +33,20 @@ impl From for Date { } } -impl SetValue for Date { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::value::SetValue::set_value(value, &this.0); +impl ToValue for Date { + fn to_value(&self) -> glib::Value { + self.0.to_value() + } + + fn value_type(&self) -> glib::Type { + glib::Date::static_type() } } -impl SetValueOptional for Date { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::value::SetValueOptional::set_value_optional(value, this.map(|this| &this.0)); +impl ToValueOptional for Date { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + s.map(|s| &s.0).to_value() } } diff --git a/gstreamer/src/enums.rs b/gstreamer/src/enums.rs index f4667b4ba..fc6e5811a 100644 --- a/gstreamer/src/enums.rs +++ b/gstreamer/src/enums.rs @@ -11,8 +11,7 @@ use thiserror::Error; use glib::translate::*; use glib::value::FromValue; -use glib::value::FromValueOptional; -use glib::value::SetValue; +use glib::value::ToValue; use glib::value::Value; use glib::StaticType; use glib::Type; @@ -610,21 +609,30 @@ impl StaticType for MessageType { } } -impl<'a> FromValueOptional<'a> for MessageType { - unsafe fn from_value_optional(value: &Value) -> Option { - Some(FromValue::from_value(value)) +impl glib::value::ValueType for MessageType { + type Type = Self; +} + +unsafe impl<'a> FromValue<'a> for MessageType { + type Checker = glib::value::GenericValueTypeChecker; + + unsafe fn from_value(value: &glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0) as ffi::GstMessageType) } } -impl<'a> FromValue<'a> for MessageType { - unsafe fn from_value(value: &Value) -> Self { - from_glib(glib::gobject_ffi::g_value_get_flags(value.to_glib_none().0)) +impl ToValue for MessageType { + fn to_value(&self) -> Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.to_glib() as i32) + } + value } -} -impl SetValue for MessageType { - unsafe fn set_value(value: &mut Value, this: &Self) { - glib::gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib()) + fn value_type(&self) -> Type { + Self::static_type() } } diff --git a/gstreamer/src/event.rs b/gstreamer/src/event.rs index 08e0054fd..9d7a99add 100644 --- a/gstreamer/src/event.rs +++ b/gstreamer/src/event.rs @@ -1143,7 +1143,7 @@ impl<'a> CustomBothOob<'a> { struct EventBuilder<'a> { seqnum: Option, running_time_offset: Option, - other_fields: Vec<(&'a str, &'a dyn ToSendValue)>, + other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>, } impl<'a> EventBuilder<'a> { @@ -1169,7 +1169,7 @@ impl<'a> EventBuilder<'a> { } } - fn other_fields(self, other_fields: &[(&'a str, &'a dyn ToSendValue)]) -> Self { + fn other_fields(self, other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))]) -> Self { Self { other_fields: self .other_fields @@ -1201,7 +1201,10 @@ macro_rules! event_builder_generic_impl { } #[allow(clippy::needless_update)] - pub fn other_fields(self, other_fields: &[(&'a str, &'a dyn ToSendValue)]) -> Self { + pub fn other_fields( + self, + other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))], + ) -> Self { Self { builder: self.builder.other_fields(other_fields), ..self @@ -1980,6 +1983,6 @@ mod tests { } let structure = flush_start_evt.structure().unwrap(); - assert_eq!(structure.get_some("test"), Ok(42u32)); + assert_eq!(structure.get("test"), Ok(42u32)); } } diff --git a/gstreamer/src/iterator.rs b/gstreamer/src/iterator.rs index 807c19006..54310fda1 100644 --- a/gstreamer/src/iterator.rs +++ b/gstreamer/src/iterator.rs @@ -2,7 +2,7 @@ use glib::ffi::{gconstpointer, gpointer}; use glib::translate::*; -use glib::value::{FromValueOptional, ToValue}; +use glib::value::{FromValue, ToValue}; use glib::StaticType; use glib::Value; use std::ffi::CString; @@ -30,7 +30,7 @@ pub struct Iterator { impl Iterator where - for<'a> T: FromValueOptional<'a> + 'static, + for<'a> T: FromValue<'a> + 'static, { pub unsafe fn into_ptr(self) -> *mut ffi::GstIterator { let s = mem::ManuallyDrop::new(self); @@ -46,9 +46,9 @@ where #[allow(clippy::wildcard_in_or_patterns)] match res { - ffi::GST_ITERATOR_OK => match value.get::().expect("Iterator::next") { - Some(value) => Ok(Some(value)), - None => Err(IteratorError::Error), + ffi::GST_ITERATOR_OK => match value.get::() { + Ok(value) => Ok(Some(value)), + Err(_) => Err(IteratorError::Error), }, ffi::GST_ITERATOR_DONE => Ok(None), ffi::GST_ITERATOR_RESYNC => Err(IteratorError::Resync), @@ -66,6 +66,7 @@ where pub fn filter(self, func: F) -> Self where F: Fn(T) -> bool + Send + Sync + 'static, + T: StaticType, { unsafe { let func_box: Box bool + Send + Sync + 'static> = Box::new(func); @@ -100,7 +101,7 @@ where func_ptr, )); if res { - elem.get::().expect("Iterator::find") + Some(elem.get::().expect("Iterator::find")) } else { None } @@ -164,7 +165,7 @@ where impl Iterator where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static, { pub fn new>(imp: I) -> Self { assert_initialized_main_thread!(); @@ -195,7 +196,7 @@ where impl Iterator where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Clone + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Clone + Send + 'static, { pub fn from_vec(items: Vec) -> Self { skip_assert_initialized!(); @@ -206,7 +207,7 @@ where #[repr(C)] struct RsIterator> where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static, { iter: ffi::GstIterator, imp: I, @@ -215,7 +216,7 @@ where pub trait IteratorImpl: Clone + Send + 'static where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static, { fn next(&mut self) -> Option>; fn resync(&mut self); @@ -225,7 +226,7 @@ unsafe extern "C" fn rs_iterator_copy>( it: *const ffi::GstIterator, copy: *mut ffi::GstIterator, ) where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static, { let it = it as *const RsIterator; let copy = copy as *mut RsIterator; @@ -235,7 +236,7 @@ unsafe extern "C" fn rs_iterator_copy>( unsafe extern "C" fn rs_iterator_free>(it: *mut ffi::GstIterator) where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static, { let it = it as *mut RsIterator; ptr::drop_in_place(&mut (*it).imp); @@ -246,7 +247,7 @@ unsafe extern "C" fn rs_iterator_next>( result: *mut glib::gobject_ffi::GValue, ) -> ffi::GstIteratorResult where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static, { let it = it as *mut RsIterator; match (*it).imp.next() { @@ -265,7 +266,7 @@ where unsafe extern "C" fn rs_iterator_resync>(it: *mut ffi::GstIterator) where - for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, + for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static, { let it = it as *mut RsIterator; (*it).imp.resync(); @@ -279,7 +280,7 @@ struct VecIteratorImpl { impl VecIteratorImpl where - for<'a> T: StaticType + ToValue + FromValueOptional<'a> + Clone + Send + 'static, + for<'a> T: StaticType + ToValue + FromValue<'a> + Clone + Send + 'static, { fn new(items: Vec) -> Self { skip_assert_initialized!(); @@ -289,7 +290,7 @@ where impl IteratorImpl for VecIteratorImpl where - for<'a> T: StaticType + ToValue + FromValueOptional<'a> + Clone + Send + 'static, + for<'a> T: StaticType + ToValue + FromValue<'a> + Clone + Send + 'static, { fn next(&mut self) -> Option> { if self.pos < self.items.len() { @@ -311,7 +312,7 @@ unsafe impl Sync for Iterator {} unsafe extern "C" fn filter_trampoline(value: gconstpointer, func: gconstpointer) -> i32 where - for<'a> T: FromValueOptional<'a> + 'static, + for<'a> T: FromValue<'a> + 'static, { let value = value as *const glib::gobject_ffi::GValue; @@ -320,10 +321,7 @@ where let func = &*(func as *const &(dyn Fn(T) -> bool + Send + Sync + 'static)); let value = &*(value as *const glib::Value); - let value = value - .get::() - .expect("Iterator filter_trampoline") - .unwrap(); + let value = value.get::().expect("Iterator filter_trampoline"); if func(value) { 0 @@ -399,13 +397,13 @@ unsafe extern "C" fn find_trampoline bool>( func: gconstpointer, ) -> i32 where - for<'a> T: FromValueOptional<'a> + 'static, + for<'a> T: FromValue<'a> + 'static, { let value = value as *const glib::gobject_ffi::GValue; let func = func as *mut F; let value = &*(value as *const glib::Value); - let value = value.get::().expect("Iterator find_trampoline").unwrap(); + let value = value.get::().expect("Iterator find_trampoline"); if (*func)(value) { 0 @@ -418,14 +416,11 @@ unsafe extern "C" fn foreach_trampoline( value: *const glib::gobject_ffi::GValue, func: gpointer, ) where - for<'a> T: FromValueOptional<'a> + 'static, + for<'a> T: FromValue<'a> + 'static, { let func = func as *mut F; let value = &*(value as *const glib::Value); - let value = value - .get::() - .expect("Iterator foreach_trampoline") - .unwrap(); + let value = value.get::().expect("Iterator foreach_trampoline"); (*func)(value); } @@ -436,11 +431,11 @@ unsafe extern "C" fn fold_trampoline Result>( func: gpointer, ) -> glib::ffi::gboolean where - for<'a> T: FromValueOptional<'a> + 'static, + for<'a> T: FromValue<'a> + 'static, { let func = func as *mut F; let value = &*(value as *const glib::Value); - let value = value.get::().expect("Iterator fold_trampoline").unwrap(); + let value = value.get::().expect("Iterator fold_trampoline"); let accum = &mut *(glib::gobject_ffi::g_value_get_pointer(ret) as *mut Option); @@ -480,7 +475,7 @@ impl Drop for Iterator { impl iter::IntoIterator for Iterator where - for<'a> T: FromValueOptional<'a> + 'static, + for<'a> T: FromValue<'a> + 'static, { type Item = Result; type IntoIter = StdIterator; @@ -496,34 +491,49 @@ impl glib::types::StaticType for Iterator { } } -#[doc(hidden)] -impl<'a, T: StaticType> glib::value::FromValueOptional<'a> for Iterator { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::>::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstIterator) - } +impl glib::value::ValueType for Iterator { + type Type = Self; } -#[doc(hidden)] -impl glib::value::SetValue for Iterator { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstIterator>::to_glib_none(this).0 - as glib::ffi::gpointer, +unsafe impl<'a, T: StaticType + 'static> glib::value::FromValue<'a> for Iterator { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none( + glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstIterator ) } } -#[doc(hidden)] -impl glib::value::SetValueOptional for Iterator { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstIterator>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for Iterator { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl glib::value::ToValueOptional for Iterator { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } @@ -645,7 +655,7 @@ impl fmt::Debug for StdIterator { impl iter::Iterator for StdIterator where - for<'a> T: FromValueOptional<'a> + 'static, + for<'a> T: FromValue<'a> + 'static, { type Item = Result; diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index 685351fa4..c3b5c79a8 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -26,6 +26,7 @@ macro_rules! skip_assert_initialized { #[allow(clippy::too_many_arguments)] #[allow(clippy::match_same_arms)] #[allow(clippy::type_complexity)] +#[allow(unused_imports)] mod auto; pub use crate::auto::functions::*; pub use crate::auto::*; diff --git a/gstreamer/src/message.rs b/gstreamer/src/message.rs index 38fbe42e3..91320a7ab 100644 --- a/gstreamer/src/message.rs +++ b/gstreamer/src/message.rs @@ -1555,7 +1555,7 @@ struct MessageBuilder<'a> { src: Option, seqnum: Option, #[allow(unused)] - other_fields: Vec<(&'a str, &'a dyn ToSendValue)>, + other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>, } impl<'a> MessageBuilder<'a> { @@ -1583,7 +1583,7 @@ impl<'a> MessageBuilder<'a> { #[cfg(any(feature = "v1_14", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] - fn other_fields(self, other_fields: &[(&'a str, &'a dyn ToSendValue)]) -> Self { + fn other_fields(self, other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))]) -> Self { Self { other_fields: self .other_fields @@ -1617,7 +1617,10 @@ macro_rules! message_builder_generic_impl { #[cfg(any(feature = "v1_14", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] #[allow(clippy::needless_update)] - pub fn other_fields(self, other_fields: &[(&'a str, &'a dyn ToSendValue)]) -> Self { + pub fn other_fields( + self, + other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))], + ) -> Self { Self { builder: self.builder.other_fields(other_fields), ..self @@ -2117,7 +2120,7 @@ pub struct StreamStatusBuilder<'a> { builder: MessageBuilder<'a>, type_: crate::StreamStatusType, owner: &'a crate::Element, - status_object: Option<&'a dyn glib::ToSendValue>, + status_object: Option<&'a (dyn glib::ToSendValue + Sync)>, } impl<'a> StreamStatusBuilder<'a> { @@ -2131,7 +2134,7 @@ impl<'a> StreamStatusBuilder<'a> { } } - pub fn status_object(self, status_object: &'a dyn glib::ToSendValue) -> Self { + pub fn status_object(self, status_object: &'a (dyn glib::ToSendValue + Sync)) -> Self { Self { status_object: Some(status_object), ..self @@ -2614,7 +2617,7 @@ impl<'a> DeviceRemovedBuilder<'a> { pub struct PropertyNotifyBuilder<'a> { builder: MessageBuilder<'a>, property_name: &'a str, - value: Option<&'a dyn glib::ToSendValue>, + value: Option<&'a (dyn glib::ToSendValue + Sync)>, } #[cfg(any(feature = "v1_10", feature = "dox"))] @@ -2629,7 +2632,7 @@ impl<'a> PropertyNotifyBuilder<'a> { } } - pub fn value(self, value: &'a dyn glib::ToSendValue) -> Self { + pub fn value(self, value: &'a (dyn glib::ToSendValue + Sync)) -> Self { Self { value: Some(value), ..self diff --git a/gstreamer/src/miniobject.rs b/gstreamer/src/miniobject.rs index 6825a0f82..0696f02e9 100644 --- a/gstreamer/src/miniobject.rs +++ b/gstreamer/src/miniobject.rs @@ -424,41 +424,58 @@ macro_rules! mini_object_wrapper ( } } - impl<'a> $crate::glib::value::FromValueOptional<'a> - for $name - { - unsafe fn from_value_optional(v: &'a glib::Value) -> Option { - let ptr = $crate::glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(v).0); - $crate::glib::translate::from_glib_none(ptr as *const $ffi_name) + impl glib::value::ValueType for $name { + type Type = Self; + } + + unsafe impl<'a> $crate::glib::value::FromValue<'a> for $name { + type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a $crate::glib::Value) -> Self { + skip_assert_initialized!(); + $crate::glib::translate::from_glib_none( + $crate::glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(value).0) as *mut $ffi_name + ) } } - impl $crate::glib::value::SetValue for $name { - unsafe fn set_value(v: &mut glib::Value, s: &Self) { - $crate::glib::gobject_ffi::g_value_set_boxed($crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(v).0, s.as_ptr() as $crate::glib::ffi::gpointer); - } - } - - impl $crate::glib::value::SetValueOptional for $name { - unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) { - if let Some(s) = s { - $crate::glib::gobject_ffi::g_value_set_boxed($crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(v).0, s.as_ptr() as $crate::glib::ffi::gpointer); - } else { - $crate::glib::gobject_ffi::g_value_set_boxed($crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(v).0, std::ptr::null_mut()); + impl $crate::glib::value::ToValue for $name { + fn to_value(&self) -> $crate::glib::Value { + let mut value = $crate::glib::Value::for_value_type::<$name>(); + unsafe { + $crate::glib::gobject_ffi::g_value_set_boxed( + $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, + $crate::glib::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(self).0 as *mut _, + ) } + value + } + + fn value_type(&self) -> $crate::glib::Type { + ::static_type() } } - impl<'a> $crate::glib::value::FromValueOptional<'a> - for &'a $ref_name - { - unsafe fn from_value_optional(v: &'a glib::Value) -> Option { - let ptr = glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(v).0); - if ptr.is_null() { - None - } else { - Some(&*(ptr as *const $ref_name)) + impl $crate::glib::value::ToValueOptional for $name { + fn to_value_optional(s: Option<&Self>) -> $crate::glib::Value { + skip_assert_initialized!(); + let mut value = $crate::glib::Value::for_value_type::<$name>(); + unsafe { + $crate::glib::gobject_ffi::g_value_set_boxed( + $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, + $crate::glib::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(&s).0 as *mut _, + ) } + value + } + } + + unsafe impl<'a> $crate::glib::value::FromValue<'a> for &'a $ref_name { + type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a $crate::glib::Value) -> Self { + skip_assert_initialized!(); + &*($crate::glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(value).0) as *const $ref_name) } } diff --git a/gstreamer/src/object.rs b/gstreamer/src/object.rs index f11e0e7cf..cb2a928a3 100644 --- a/gstreamer/src/object.rs +++ b/gstreamer/src/object.rs @@ -57,13 +57,11 @@ impl> GstObjectExtManual for O { .unwrap_or_else(|err| { panic!("Object signal \"deep-notify\": values[0]: {}", err) }) - .expect("Object signal \"deep-notify\": values[0] not defined") .unsafe_cast() }; let prop_obj: crate::Object = values[1] .get() - .unwrap_or_else(|err| panic!("Object signal \"deep-notify\": values[1]: {}", err)) - .expect("Object signal \"deep-notify\": values[1] not defined"); + .unwrap_or_else(|err| panic!("Object signal \"deep-notify\": values[1]: {}", err)); let pspec = unsafe { let pspec = glib::gobject_ffi::g_value_get_param(values[2].to_glib_none().0); diff --git a/gstreamer/src/pad.rs b/gstreamer/src/pad.rs index 3320f38e0..5c759fd03 100644 --- a/gstreamer/src/pad.rs +++ b/gstreamer/src/pad.rs @@ -1663,7 +1663,7 @@ impl + IsA + glib::object::IsClass> PadBuilder { let gtype = templ .property("gtype") .unwrap() - .get_some::() + .get::() .unwrap(); if gtype == glib::Type::UNIT { diff --git a/gstreamer/src/segment.rs b/gstreamer/src/segment.rs index bb8d4ffa6..2c4761e68 100644 --- a/gstreamer/src/segment.rs +++ b/gstreamer/src/segment.rs @@ -6,6 +6,7 @@ use crate::GenericFormattedValue; use crate::SeekFlags; use crate::SeekType; use glib::translate::*; +use glib::StaticType; use std::fmt; use std::marker::PhantomData; use std::mem; @@ -558,37 +559,55 @@ impl glib::types::StaticType for FormattedSegment { } } -#[doc(hidden)] -impl<'a> glib::value::FromValueOptional<'a> for Segment { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstSegment) - } +impl glib::value::ValueType for Segment { + type Type = Self; } #[doc(hidden)] -impl glib::value::SetValue for FormattedSegment { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstSegment>::to_glib_none(this).0 - as glib::ffi::gpointer, +unsafe impl<'a> glib::value::FromValue<'a> for Segment { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none( + glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstSegment ) } } #[doc(hidden)] -impl glib::value::SetValueOptional for FormattedSegment { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstSegment>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for FormattedSegment { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } +#[doc(hidden)] +impl glib::value::ToValueOptional for FormattedSegment { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value + } +} +#[doc(hidden)] #[doc(hidden)] impl glib::translate::GlibPtrDefault for FormattedSegment { type GlibType = *mut ffi::GstSegment; diff --git a/gstreamer/src/static_caps.rs b/gstreamer/src/static_caps.rs index 9db889a10..e2e0101c1 100644 --- a/gstreamer/src/static_caps.rs +++ b/gstreamer/src/static_caps.rs @@ -3,6 +3,7 @@ use crate::Caps; use glib::translate::*; +use glib::StaticType; use std::ffi::CStr; use std::fmt; @@ -35,34 +36,52 @@ impl glib::types::StaticType for StaticCaps { } } -#[doc(hidden)] -impl<'a> glib::value::FromValueOptional<'a> for StaticCaps { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstStaticCaps) - } +impl glib::value::ValueType for StaticCaps { + type Type = Self; } #[doc(hidden)] -impl glib::value::SetValue for StaticCaps { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstStaticCaps>::to_glib_none(this).0 - as glib::ffi::gpointer, +unsafe impl<'a> glib::value::FromValue<'a> for StaticCaps { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none( + glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstStaticCaps ) } } #[doc(hidden)] -impl glib::value::SetValueOptional for StaticCaps { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstStaticCaps>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for StaticCaps { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +#[doc(hidden)] +impl glib::value::ToValueOptional for StaticCaps { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } diff --git a/gstreamer/src/static_pad_template.rs b/gstreamer/src/static_pad_template.rs index 58b5ef93c..603539ac1 100644 --- a/gstreamer/src/static_pad_template.rs +++ b/gstreamer/src/static_pad_template.rs @@ -4,6 +4,7 @@ use crate::Caps; use crate::PadTemplate; use glib::translate::*; +use glib::StaticType; use std::ffi::CStr; use std::fmt; @@ -65,34 +66,51 @@ impl glib::types::StaticType for StaticPadTemplate { } } +impl glib::value::ValueType for StaticPadTemplate { + type Type = Self; +} + #[doc(hidden)] -impl<'a> glib::value::FromValueOptional<'a> for StaticPadTemplate { - unsafe fn from_value_optional(value: &glib::Value) -> Option { - Option::::from_glib_none(glib::gobject_ffi::g_value_get_boxed( - value.to_glib_none().0, - ) as *mut ffi::GstStaticPadTemplate) +unsafe impl<'a> glib::value::FromValue<'a> for StaticPadTemplate { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) + as *mut ffi::GstStaticPadTemplate) } } #[doc(hidden)] -impl glib::value::SetValue for StaticPadTemplate { - unsafe fn set_value(value: &mut glib::Value, this: &Self) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstStaticPadTemplate>::to_glib_none(this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValue for StaticPadTemplate { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.to_glib_none().0 as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } #[doc(hidden)] -impl glib::value::SetValueOptional for StaticPadTemplate { - unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { - glib::gobject_ffi::g_value_set_boxed( - value.to_glib_none_mut().0, - glib::translate::ToGlibPtr::<*const ffi::GstStaticPadTemplate>::to_glib_none(&this).0 - as glib::ffi::gpointer, - ) +impl glib::value::ToValueOptional for StaticPadTemplate { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.to_glib_none().0 as *mut _, + ) + } + value } } diff --git a/gstreamer/src/structure.rs b/gstreamer/src/structure.rs index 1ba3539c3..8d0c24782 100644 --- a/gstreamer/src/structure.rs +++ b/gstreamer/src/structure.rs @@ -8,40 +8,56 @@ use std::ops::{Deref, DerefMut}; use std::ptr; use std::str; -use thiserror::Error; - use crate::Fraction; -use glib::ffi::gpointer; -use glib::translate::{ - from_glib, from_glib_full, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault, Stash, StashMut, - ToGlib, ToGlibPtr, ToGlibPtrMut, -}; -use glib::value::{FromValue, FromValueOptional, SendValue, ToSendValue}; +use glib::translate::*; +use glib::value::{FromValue, SendValue, ToSendValue}; +use glib::StaticType; -#[derive(Clone, Debug, Eq, PartialEq, Error)] -pub enum GetError<'name> { +#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)] +pub enum GetError { #[error("GetError: Structure field with name {name} not found")] - FieldNotFound { name: &'name str }, + FieldNotFound { name: &'static str }, #[error("GetError: Structure field with name {name} not retrieved")] ValueGetError { - name: &'name str, + name: &'static str, #[source] - value_get_error: glib::value::GetError, + type_mismatch_error: glib::value::ValueTypeMismatchOrNoneError, }, } -impl<'name> GetError<'name> { - fn new_field_not_found(name: &'name str) -> GetError { +impl GetError { + fn new_field_not_found(name: &'static str) -> Self { skip_assert_initialized!(); GetError::FieldNotFound { name } } - fn from_value_get_error(name: &'name str, value_get_error: glib::value::GetError) -> GetError { + fn from_value_get_error(name: &'static str, err: E) -> Self { + skip_assert_initialized!(); + E::from_value_error(name, err) + } +} + +pub trait GlibValueError: 'static { + fn from_value_error(name: &'static str, err: Self) -> GetError; +} + +impl GlibValueError for glib::value::ValueTypeMismatchError { + fn from_value_error(name: &'static str, err: Self) -> GetError { skip_assert_initialized!(); GetError::ValueGetError { name, - value_get_error, + type_mismatch_error: glib::value::ValueTypeMismatchOrNoneError::from(err), + } + } +} + +impl GlibValueError for glib::value::ValueTypeMismatchOrNoneError { + fn from_value_error(name: &'static str, err: Self) -> GetError { + skip_assert_initialized!(); + GetError::ValueGetError { + name, + type_mismatch_error: err, } } } @@ -65,7 +81,7 @@ impl Structure { } } - pub fn new(name: &str, values: &[(&str, &dyn ToSendValue)]) -> Structure { + pub fn new(name: &str, values: &[(&str, &(dyn ToSendValue + Sync))]) -> Structure { assert_initialized_main_thread!(); let mut structure = Structure::new_empty(name); @@ -283,28 +299,54 @@ impl FromGlibPtrFull<*mut ffi::GstStructure> for Structure { } } -impl<'a> glib::value::FromValueOptional<'a> for Structure { - unsafe fn from_value_optional(v: &'a glib::Value) -> Option { - <&'a StructureRef as glib::value::FromValueOptional<'a>>::from_value_optional(v) - .map(ToOwned::to_owned) - } +impl glib::value::ValueType for Structure { + type Type = Self; } -impl glib::value::SetValue for Structure { - unsafe fn set_value(v: &mut glib::Value, s: &Self) { - ::set_value(v, s.as_ref()) - } -} +unsafe impl<'a> glib::value::FromValue<'a> for Structure { + type Checker = glib::value::GenericValueTypeOrNoneChecker; -impl glib::value::SetValueOptional for Structure { - unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) { - ::set_value_optional( - v, - s.map(|s| s.as_ref()), + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib_none( + glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstStructure ) } } +impl glib::value::ToValue for Structure { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + glib::translate::ToGlibPtr::<*const ffi::GstStructure>::to_glib_none(self).0 + as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl glib::value::ToValueOptional for Structure { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + glib::translate::ToGlibPtr::<*const ffi::GstStructure>::to_glib_none(&s).0 + as *mut _, + ) + } + value + } +} + impl GlibPtrDefault for Structure { type GlibType = *mut ffi::GstStructure; } @@ -336,54 +378,63 @@ impl StructureRef { self as *const Self as *mut ffi::GstStructure } - pub fn get<'structure, 'name, T: FromValueOptional<'structure>>( - &'structure self, - name: &'name str, - ) -> Result, GetError<'name>> { - self.value(name)? + pub fn get<'a, T: FromValue<'a>>(&'a self, name: &str) -> Result + where + <>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, + { + let name = glib::Quark::from_string(name); + self.get_by_quark(name) + } + + pub fn get_optional<'a, T: FromValue<'a>>(&'a self, name: &str) -> Result, GetError> + where + <>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, + { + let name = glib::Quark::from_string(name); + self.get_optional_by_quark(name) + } + + pub fn value(&self, name: &str) -> Result<&SendValue, GetError> { + let name = glib::Quark::from_string(name); + self.value_by_quark(name) + } + + pub fn get_by_quark<'a, T: FromValue<'a>>(&'a self, name: glib::Quark) -> Result + where + <>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, + { + self.value_by_quark(name)? .get() - .map_err(|err| GetError::from_value_get_error(name, err)) + .map_err(|err| GetError::from_value_get_error(name.to_string(), err)) } - pub fn get_optional<'structure, 'name, T: FromValueOptional<'structure>>( - &'structure self, - name: &'name str, - ) -> Result, GetError<'name>> { - let value = self.value(name); - if let Ok(value) = value { - value - .get() - .map_err(|err| GetError::from_value_get_error(name, err)) - } else { - Ok(None) - } + pub fn get_optional_by_quark<'a, T: FromValue<'a>>( + &'a self, + name: glib::Quark, + ) -> Result, GetError> + where + <>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, + { + self.value_by_quark(name) + .ok() + .map(|v| v.get()) + .transpose() + .map_err(|err| GetError::from_value_get_error(name.to_string(), err)) } - pub fn get_some<'structure, 'name, T: FromValue<'structure>>( - &'structure self, - name: &'name str, - ) -> Result> { - self.value(name)? - .get_some() - .map_err(|err| GetError::from_value_get_error(name, err)) - } - - pub fn value<'structure, 'name>( - &'structure self, - name: &'name str, - ) -> Result<&SendValue, GetError<'name>> { + pub fn value_by_quark(&self, name: glib::Quark) -> Result<&SendValue, GetError> { unsafe { - let value = ffi::gst_structure_get_value(&self.0, name.to_glib_none().0); + let value = ffi::gst_structure_id_get_value(&self.0, name.to_glib()); if value.is_null() { - return Err(GetError::new_field_not_found(name)); + return Err(GetError::new_field_not_found(name.to_string())); } Ok(&*(value as *const SendValue)) } } - pub fn set(&mut self, name: &str, value: &T) { + pub fn set(&mut self, name: &str, value: T) { let value = value.to_send_value(); self.set_value(name, value); } @@ -395,6 +446,18 @@ impl StructureRef { } } + pub fn set_by_quark(&mut self, name: glib::Quark, value: T) { + let value = value.to_send_value(); + self.set_value_by_quark(name, value); + } + + pub fn set_value_by_quark(&mut self, name: glib::Quark, value: SendValue) { + unsafe { + let mut value = value.into_raw(); + ffi::gst_structure_id_take_value(&mut self.0, name.to_glib(), &mut value); + } + } + pub fn name<'a>(&self) -> &'a str { unsafe { CStr::from_ptr(ffi::gst_structure_get_name(&self.0)) @@ -403,6 +466,10 @@ impl StructureRef { } } + pub fn name_quark(&self) -> glib::Quark { + unsafe { from_glib(ffi::gst_structure_get_name_id(&self.0)) } + } + pub fn set_name(&mut self, name: &str) { unsafe { ffi::gst_structure_set_name(&mut self.0, name.to_glib_none().0) } } @@ -426,6 +493,20 @@ impl StructureRef { } } + pub fn has_field_by_quark(&self, field: glib::Quark) -> bool { + unsafe { from_glib(ffi::gst_structure_id_has_field(&self.0, field.to_glib())) } + } + + pub fn has_field_with_type_by_quark(&self, field: glib::Quark, type_: glib::Type) -> bool { + unsafe { + from_glib(ffi::gst_structure_id_has_field_typed( + &self.0, + field.to_glib(), + type_.to_glib(), + )) + } + } + pub fn remove_field(&mut self, field: &str) { unsafe { ffi::gst_structure_remove_field(&mut self.0, field.to_glib_none().0); @@ -578,32 +659,43 @@ impl glib::types::StaticType for StructureRef { } } -impl<'a> glib::value::FromValueOptional<'a> for &'a StructureRef { - unsafe fn from_value_optional(v: &'a glib::Value) -> Option { - let ptr = glib::gobject_ffi::g_value_get_boxed(v.to_glib_none().0); - if ptr.is_null() { - None - } else { - Some(StructureRef::from_glib_borrow( - ptr as *const ffi::GstStructure, - )) - } +unsafe impl<'a> glib::value::FromValue<'a> for &'a StructureRef { + type Checker = glib::value::GenericValueTypeOrNoneChecker; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + &*(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const StructureRef) } } -impl glib::value::SetValue for StructureRef { - unsafe fn set_value(v: &mut glib::Value, s: &Self) { - glib::gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer); +impl glib::value::ToValue for StructureRef { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + self.as_ptr() as *mut _, + ) + } + value + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } -impl glib::value::SetValueOptional for StructureRef { - unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) { - if let Some(s) = s { - glib::gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.as_ptr() as gpointer); - } else { - glib::gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ptr::null_mut()); +impl glib::value::ToValueOptional for StructureRef { + fn to_value_optional(s: Option<&Self>) -> glib::Value { + skip_assert_initialized!(); + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + s.map(|s| s.as_ptr()).unwrap_or(ptr::null()) as *mut _, + ) } + value } } @@ -728,7 +820,7 @@ impl Builder { } } - pub fn field(mut self, name: &str, value: &V) -> Self { + pub fn field(mut self, name: &str, value: V) -> Self { self.s.set(name, value); self } @@ -756,9 +848,9 @@ mod tests { s.set("f2", &String::from("bcd")); s.set("f3", &123i32); - assert_eq!(s.get::<&str>("f1"), Ok(Some("abc"))); - assert_eq!(s.get::<&str>("f2"), Ok(Some("bcd"))); - assert_eq!(s.get_some::("f3"), Ok(123i32)); + assert_eq!(s.get::<&str>("f1"), Ok("abc")); + assert_eq!(s.get::>("f2"), Ok(Some("bcd"))); + assert_eq!(s.get::("f3"), Ok(123i32)); assert_eq!(s.get_optional::<&str>("f1"), Ok(Some("abc"))); assert_eq!(s.get_optional::<&str>("f4"), Ok(None)); assert_eq!(s.get_optional::("f3"), Ok(Some(123i32))); @@ -768,35 +860,32 @@ mod tests { s.get::("f2"), Err(GetError::from_value_get_error( "f2", - value::GetError::new_type_mismatch(Type::STRING, Type::I32), + value::ValueTypeMismatchError::new(Type::STRING, Type::I32), )) ); assert_eq!( - s.get_some::("f3"), + s.get::("f3"), Err(GetError::from_value_get_error( "f3", - value::GetError::new_type_mismatch(Type::I32, Type::BOOL), + value::ValueTypeMismatchError::new(Type::I32, Type::BOOL), )) ); assert_eq!( s.get::<&str>("f4"), Err(GetError::new_field_not_found("f4")) ); - assert_eq!( - s.get_some::("f4"), - Err(GetError::new_field_not_found("f4")) - ); + assert_eq!(s.get::("f4"), Err(GetError::new_field_not_found("f4"))); assert_eq!(s.fields().collect::>(), vec!["f1", "f2", "f3"]); let v = s.iter().map(|(f, v)| (f, v.clone())).collect::>(); assert_eq!(v.len(), 3); assert_eq!(v[0].0, "f1"); - assert_eq!(v[0].1.get::<&str>(), Ok(Some("abc"))); + assert_eq!(v[0].1.get::<&str>(), Ok("abc")); assert_eq!(v[1].0, "f2"); - assert_eq!(v[1].1.get::<&str>(), Ok(Some("bcd"))); + assert_eq!(v[1].1.get::<&str>(), Ok("bcd")); assert_eq!(v[2].0, "f3"); - assert_eq!(v[2].1.get_some::(), Ok(123i32)); + assert_eq!(v[2].1.get::(), Ok(123i32)); let s2 = Structure::new("test", &[("f1", &"abc"), ("f2", &"bcd"), ("f3", &123i32)]); assert_eq!(s, s2); @@ -813,9 +902,9 @@ mod tests { .build(); assert_eq!(s.name(), "test"); - assert_eq!(s.get::<&str>("f1"), Ok(Some("abc"))); - assert_eq!(s.get::<&str>("f2"), Ok(Some("bcd"))); - assert_eq!(s.get_some::("f3"), Ok(123i32)); + assert_eq!(s.get::<&str>("f1"), Ok("abc")); + assert_eq!(s.get::<&str>("f2"), Ok("bcd")); + assert_eq!(s.get::("f3"), Ok(123i32)); } #[test] @@ -825,20 +914,22 @@ mod tests { let a = "Test, f1=(string)abc, f2=(uint)123;"; let s = Structure::from_str(&a).unwrap(); - assert_eq!(s.get::<&str>("f1"), Ok(Some("abc"))); - assert_eq!(s.get_some::("f2"), Ok(123)); + assert_eq!(s.get::<&str>("f1"), Ok("abc")); + assert_eq!(s.get::("f2"), Ok(123)); assert_eq!(a, s.to_string()); } #[test] fn test_from_value_optional() { + use glib::ToValue; + crate::init().unwrap(); - let a = glib::value::Value::from(None::<&Structure>); - assert!(a.get::().unwrap().is_none()); - let b = glib::value::Value::from(&Structure::from_str(&"foo").unwrap()); - assert!(b.get::().unwrap().is_some()); + let a = None::<&Structure>.to_value(); + assert!(a.get::>().unwrap().is_none()); + let b = Structure::from_str(&"foo").unwrap().to_value(); + assert!(b.get::>().unwrap().is_some()); } #[test] @@ -854,7 +945,7 @@ mod tests { let s2 = Structure::from_iter(s.name(), s.iter().filter(|(f, _)| *f == "f1")); assert_eq!(s2.name(), "test"); - assert_eq!(s2.get::<&str>("f1"), Ok(Some("abc"))); + assert_eq!(s2.get::<&str>("f1"), Ok("abc")); assert!(s2.get::<&str>("f2").is_err()); assert!(s2.get::<&str>("f3").is_err()); } diff --git a/gstreamer/src/tag_setter.rs b/gstreamer/src/tag_setter.rs index 17337502c..c221fd4c3 100644 --- a/gstreamer/src/tag_setter.rs +++ b/gstreamer/src/tag_setter.rs @@ -5,19 +5,14 @@ use crate::TagMergeMode; use crate::TagSetter; use glib::object::IsA; use glib::translate::*; -use glib::value::ToSendValue; +use glib::ToSendValue; pub trait TagSetterExtManual: 'static { - fn add<'a, T: Tag<'a>>(&self, value: T::TagType, mode: TagMergeMode) - where - T::TagType: ToSendValue; + fn add<'a, T: Tag<'a>>(&self, value: &T::TagType, mode: TagMergeMode); } impl> TagSetterExtManual for O { - fn add<'a, T: Tag<'a>>(&self, value: T::TagType, mode: TagMergeMode) - where - T::TagType: ToSendValue, - { + fn add<'a, T: Tag<'a>>(&self, value: &T::TagType, mode: TagMergeMode) { unsafe { let v = value.to_send_value(); diff --git a/gstreamer/src/tags.rs b/gstreamer/src/tags.rs index 78bf7ac61..0ac1e82ed 100644 --- a/gstreamer/src/tags.rs +++ b/gstreamer/src/tags.rs @@ -10,7 +10,7 @@ use once_cell::sync::Lazy; use glib::translate::{ from_glib, from_glib_full, FromGlibPtrFull, ToGlib, ToGlibPtr, ToGlibPtrMut, }; -use glib::value::{FromValue, FromValueOptional, SendValue, SetValue, ToSendValue, Value}; +use glib::value::{FromValue, SendValue, ToSendValue, Value}; use glib::StaticType; use crate::Sample; @@ -19,7 +19,7 @@ use crate::TagMergeMode; use crate::TagScope; pub trait Tag<'a> { - type TagType: FromValueOptional<'a> + SetValue + Send; + type TagType: StaticType + FromValue<'a> + ToSendValue + Send + Sync; fn tag_name<'b>() -> &'b str; } @@ -28,6 +28,7 @@ macro_rules! impl_tag( pub enum $name {} impl<'a> Tag<'a> for $name { type TagType = $t; + fn tag_name<'b>() -> &'b str { *$rust_tag } @@ -357,39 +358,27 @@ impl Default for TagList { pub struct TagValue(SendValue, PhantomData); impl TagValue { - pub fn get<'a>(&'a self) -> Option + pub fn get<'a>(&'a self) -> T where - T: FromValueOptional<'a>, + T: StaticType + FromValue<'a>, { self.0.get().expect("Invalid tag type") } - - pub fn get_some<'a>(&'a self) -> T - where - T: FromValue<'a>, - { - self.0.get_some().expect("Invalid tag type") - } } impl TagListRef { - pub fn add<'a, T: Tag<'a>>(&mut self, value: &T::TagType, mode: TagMergeMode) - where - T::TagType: ToSendValue, - { + pub fn add<'a, T: Tag<'a>>(&mut self, value: &T::TagType, mode: TagMergeMode) { // result can be safely ignored here as `value`'s type is tied to `T::tag_name()` - let _res = self.add_generic(T::tag_name(), value, mode); + let v = ::to_send_value(value); + let _res = self.add_value(T::tag_name(), &v, mode); } - pub fn add_generic( + pub fn add_generic( &mut self, tag_name: &str, - value: &T, + value: T, mode: TagMergeMode, - ) -> Result<(), TagError> - where - T: ToSendValue, - { + ) -> Result<(), TagError> { let v = value.to_send_value(); self.add_value(tag_name, &v, mode) } @@ -969,15 +958,12 @@ mod tests { tags.add::(&(crate::SECOND * 120), TagMergeMode::Append); } - assert_eq!(tags.get::().unwrap().get(), Some("some title")); + assert_eq!(tags.get::<Title>().unwrap().get(), "some title"); + assert_eq!(tags.get::<Duration>().unwrap().get(), crate::SECOND * 120); + assert_eq!(tags.index::<Title>(0).unwrap().get(), "some title"); assert_eq!( - tags.get::<Duration>().unwrap().get_some(), - (crate::SECOND * 120) - ); - assert_eq!(tags.index::<Title>(0).unwrap().get(), Some("some title")); - assert_eq!( - tags.index::<Duration>(0).unwrap().get_some(), - (crate::SECOND * 120) + tags.index::<Duration>(0).unwrap().get(), + crate::SECOND * 120 ); } @@ -1003,22 +989,22 @@ mod tests { { let tags = tags.get_mut().unwrap(); assert!(tags - .add_generic(&TAG_TITLE, &"some title", TagMergeMode::Append) + .add_generic(&TAG_TITLE, "some title", TagMergeMode::Append) .is_ok()); assert!(tags - .add_generic(&TAG_TITLE, &"second title", TagMergeMode::Append) + .add_generic(&TAG_TITLE, "second title", TagMergeMode::Append) .is_ok()); assert!(tags - .add_generic(&TAG_DURATION, &(crate::SECOND * 120), TagMergeMode::Append) + .add_generic(&TAG_DURATION, crate::SECOND * 120, TagMergeMode::Append) .is_ok()); assert!(tags - .add_generic(&TAG_TITLE, &"third title", TagMergeMode::Append) + .add_generic(&TAG_TITLE, "third title", TagMergeMode::Append) .is_ok()); assert_eq!( tags.add_generic( &TAG_IMAGE, - &"`&[str] instead of `Sample`", + "`&[str] instead of `Sample`", TagMergeMode::Append ), Err(TagError::TypeMismatch), @@ -1035,7 +1021,7 @@ mod tests { ); assert_eq!( tags.index_generic(&TAG_DURATION, 0).unwrap().get(), - Ok(Some(crate::SECOND * 120)) + Ok(crate::SECOND * 120) ); assert_eq!( tags.index_generic(&TAG_TITLE, 2).unwrap().get(), @@ -1081,7 +1067,7 @@ mod tests { let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap(); assert_eq!(tag_name, *TAG_DURATION); let first_duration = tag_iter.next().unwrap(); - assert_eq!(first_duration.get_some(), Ok(crate::SECOND * 120)); + assert_eq!(first_duration.get(), Ok(crate::SECOND * 120)); assert!(tag_iter.next().is_none()); // Iter @@ -1097,7 +1083,7 @@ mod tests { let (tag_name, tag_value) = tag_list_iter.next().unwrap(); assert_eq!(tag_name, *TAG_DURATION); - assert_eq!(tag_value.get_some(), Ok(crate::SECOND * 120)); + assert_eq!(tag_value.get(), Ok(crate::SECOND * 120)); assert!(tag_iter.next().is_none()); } @@ -1148,7 +1134,7 @@ mod tests { tags.add::<MyCustomTag>(&"first one", TagMergeMode::Append); } - assert_eq!(tags.get::<MyCustomTag>().unwrap().get(), Some("first one")); + assert_eq!(tags.get::<MyCustomTag>().unwrap().get(), "first one"); { let tags = tags.get_mut().unwrap(); @@ -1157,7 +1143,7 @@ mod tests { assert_eq!( tags.get::<MyCustomTag>().unwrap().get(), - Some("first one, second one") + "first one, second one" ); } diff --git a/gstreamer/src/tags_serde.rs b/gstreamer/src/tags_serde.rs index 1bd25e2aa..e86412a84 100644 --- a/gstreamer/src/tags_serde.rs +++ b/gstreamer/src/tags_serde.rs @@ -21,13 +21,14 @@ use crate::Sample; use crate::TagMergeMode; use crate::TagScope; -macro_rules! ser_some_tag ( +macro_rules! ser_tag ( ($value:ident, $seq:ident, $t:ty) => ( ser_some_value!($value, $t, |_, value| { $seq.serialize_element(&value) }) ); ); + macro_rules! ser_opt_tag ( ($value:ident, $seq:ident, $t:ty) => ( ser_opt_value!($value, $t, |_, value| { @@ -57,24 +58,22 @@ impl<'a> Serialize for TagValuesSer<'a> { let mut seq = serializer.serialize_seq(tag_iter.size_hint().1)?; for value in tag_iter.deref_mut() { match value.type_() { - glib::Type::F64 => ser_some_tag!(value, seq, f64), + glib::Type::F64 => ser_tag!(value, seq, f64), glib::Type::STRING => { // See above comment about `Tag`s with `String` values - ser_opt_value!(value, String, |_, value: Option<String>| { - seq.serialize_element(&value.expect("String tag ser")) + ser_some_value!(value, String, |_, value: String| { + seq.serialize_element(&value) }) } - glib::Type::U32 => ser_some_tag!(value, seq, u32), - glib::Type::U64 => ser_some_tag!(value, seq, u64), + glib::Type::U32 => ser_tag!(value, seq, u32), + glib::Type::U64 => ser_tag!(value, seq, u64), type_id => { if *DATE_OTHER_TYPE_ID == type_id { // See above comment about `Tag`s with `Date` values - ser_opt_value!(value, Date, |_, value: Option<Date>| { + ser_some_value!(value, Date, |_, value: Date| { // Need to wrap the `glib::Date` in new type `date_time_serde::Date` first // See comment in `date_time_serde.rs` - seq.serialize_element(&date_time_serde::Date::from( - value.expect("Date tag ser"), - )) + seq.serialize_element(&date_time_serde::Date::from(value)) }) } else if *DATE_TIME_OTHER_TYPE_ID == type_id { ser_opt_tag!(value, seq, DateTime) @@ -147,7 +146,7 @@ impl Serialize for TagList { } } -macro_rules! de_some_tag( +macro_rules! de_tag( ($tag_name:expr, $seq:expr, $t:ty) => ( de_some_send_value!("Tag", $tag_name, $seq, $t) ); @@ -176,13 +175,13 @@ impl<'de, 'a> Visitor<'de> for TagValuesVisitor<'a> { loop { let tag_value = match tag_type { - glib::Type::F64 => de_some_tag!(self.0, seq, f64), + glib::Type::F64 => de_tag!(self.0, seq, f64), glib::Type::STRING => { // See comment above `TagValuesSer` definition about `Tag`s with `String` values - de_some_tag!(self.0, seq, String) + de_tag!(self.0, seq, String) } - glib::Type::U32 => de_some_tag!(self.0, seq, u32), - glib::Type::U64 => de_some_tag!(self.0, seq, u64), + glib::Type::U32 => de_tag!(self.0, seq, u32), + glib::Type::U64 => de_tag!(self.0, seq, u64), type_id => { if *DATE_OTHER_TYPE_ID == type_id { // See comment above `TagValuesSer` definition about `Tag`s with `Date` values @@ -464,23 +463,23 @@ mod tests { let tags: TagList = ron::de::from_str(tag_list_ron).unwrap(); assert_eq!(tags.scope(), TagScope::Global); - assert_eq!(tags.index::<Title>(0).unwrap().get(), Some("a title")); - assert_eq!(tags.index::<Title>(1).unwrap().get(), Some("another title")); + assert_eq!(tags.index::<Title>(0).unwrap().get(), "a title"); + assert_eq!(tags.index::<Title>(1).unwrap().get(), "another title"); assert_eq!( - tags.index::<Duration>(0).unwrap().get_some(), + tags.index::<Duration>(0).unwrap().get(), crate::SECOND * 120 ); - assert_eq!(tags.index::<Bitrate>(0).unwrap().get_some(), 96_000); - assert!((tags.index::<TrackGain>(0).unwrap().get_some() - 1f64).abs() < std::f64::EPSILON); + assert_eq!(tags.index::<Bitrate>(0).unwrap().get(), 96_000); + assert!((tags.index::<TrackGain>(0).unwrap().get() - 1f64).abs() < std::f64::EPSILON); assert_eq!( - tags.index::<Date>(0).unwrap().get().unwrap(), + tags.index::<Date>(0).unwrap().get(), glib::Date::new_dmy(28, glib::DateMonth::May, 2018).unwrap() ); assert_eq!( - tags.index::<DateTime>(0).unwrap().get().unwrap(), + tags.index::<DateTime>(0).unwrap().get(), crate::DateTime::new_ymd(2018, 5, 28).unwrap() ); - let sample = tags.index::<Image>(0).unwrap().get().unwrap(); + let sample = tags.index::<Image>(0).unwrap().get(); let buffer = sample.buffer().unwrap(); { let data = buffer.map_readable().unwrap(); @@ -504,19 +503,19 @@ mod tests { let tags: TagList = serde_json::from_str(tag_json).unwrap(); assert_eq!(tags.scope(), TagScope::Global); - assert_eq!(tags.index::<Title>(0).unwrap().get(), Some("a title")); - assert_eq!(tags.index::<Title>(1).unwrap().get(), Some("another title")); - assert_eq!(tags.index::<Bitrate>(0).unwrap().get_some(), 96_000); - assert!((tags.index::<TrackGain>(0).unwrap().get_some() - 1f64).abs() < std::f64::EPSILON); + assert_eq!(tags.index::<Title>(0).unwrap().get(), "a title"); + assert_eq!(tags.index::<Title>(1).unwrap().get(), "another title"); + assert_eq!(tags.index::<Bitrate>(0).unwrap().get(), 96_000); + assert!((tags.index::<TrackGain>(0).unwrap().get() - 1f64).abs() < std::f64::EPSILON); assert_eq!( - tags.index::<Date>(0).unwrap().get().unwrap(), + tags.index::<Date>(0).unwrap().get(), glib::Date::new_dmy(28, glib::DateMonth::May, 2018).unwrap() ); assert_eq!( - tags.index::<DateTime>(0).unwrap().get().unwrap(), + tags.index::<DateTime>(0).unwrap().get(), crate::DateTime::new_ymd(2018, 5, 28).unwrap() ); - let sample = tags.index::<Image>(0).unwrap().get().unwrap(); + let sample = tags.index::<Image>(0).unwrap().get(); let buffer = sample.buffer().unwrap(); { let data = buffer.map_readable().unwrap(); @@ -572,16 +571,16 @@ mod tests { tags.index::<Title>(1).unwrap().get(), ); assert_eq!( - tags_de.index::<Duration>(0).unwrap().get_some(), - tags.index::<Duration>(0).unwrap().get_some(), + tags_de.index::<Duration>(0).unwrap().get(), + tags.index::<Duration>(0).unwrap().get(), ); assert_eq!( - tags_de.index::<Bitrate>(0).unwrap().get_some(), - tags.index::<Bitrate>(0).unwrap().get_some(), + tags_de.index::<Bitrate>(0).unwrap().get(), + tags.index::<Bitrate>(0).unwrap().get(), ); assert!( - (tags_de.index::<TrackGain>(0).unwrap().get_some() - - tags.index::<TrackGain>(0).unwrap().get_some()) + (tags_de.index::<TrackGain>(0).unwrap().get() + - tags.index::<TrackGain>(0).unwrap().get()) .abs() < std::f64::EPSILON ); @@ -590,10 +589,10 @@ mod tests { tags.index::<Date>(0).unwrap().get(), ); assert_eq!( - tags.index::<DateTime>(0).unwrap().get().unwrap(), + tags.index::<DateTime>(0).unwrap().get(), crate::DateTime::new_ymd(2018, 5, 28).unwrap() ); - let sample = tags.index::<Image>(0).unwrap().get().unwrap(); + let sample = tags.index::<Image>(0).unwrap().get(); let buffer = sample.buffer().unwrap(); { let data = buffer.map_readable().unwrap(); diff --git a/gstreamer/src/toc_serde.rs b/gstreamer/src/toc_serde.rs index 4d752bd38..e6d38b3f1 100644 --- a/gstreamer/src/toc_serde.rs +++ b/gstreamer/src/toc_serde.rs @@ -387,7 +387,7 @@ mod tests { assert_eq!("chapter1.1", chapter1_1.uid()); assert_eq!(Some((0, 4)), chapter1_1.start_stop_times()); let tags = chapter1_1.tags().unwrap(); - assert_eq!(Some("chapter 1.1"), tags.index::<Title>(0).unwrap().get()); + assert_eq!("chapter 1.1", tags.index::<Title>(0).unwrap().get()); assert_eq!(0, chapter1_1.sub_entries().len()); let chapter1_2 = &chap1_sub_entries[1]; @@ -395,14 +395,14 @@ mod tests { assert_eq!("chapter1.2", chapter1_2.uid()); assert_eq!(Some((4, 10)), chapter1_2.start_stop_times()); let tags = chapter1_2.tags().unwrap(); - assert_eq!(Some("chapter 1.2"), tags.index::<Title>(0).unwrap().get()); + assert_eq!("chapter 1.2", tags.index::<Title>(0).unwrap().get()); assert_eq!(0, chapter1_2.sub_entries().len()); let chapter2 = &sub_entries[1]; assert_eq!(TocEntryType::Chapter, chapter2.entry_type()); assert_eq!("chapter2", chapter2.uid()); let tags = chapter2.tags().unwrap(); - assert_eq!(Some("chapter 2"), tags.index::<Title>(0).unwrap().get()); + assert_eq!("chapter 2", tags.index::<Title>(0).unwrap().get()); assert_eq!(Some((10, 15)), chapter2.start_stop_times()); assert_eq!(0, chapter2.sub_entries().len()); } diff --git a/gstreamer/src/value.rs b/gstreamer/src/value.rs index dcf5902c1..7e900cfc1 100644 --- a/gstreamer/src/value.rs +++ b/gstreamer/src/value.rs @@ -8,7 +8,8 @@ use std::ops; use std::slice; use glib::translate::{from_glib, FromGlibPtrFull, ToGlibPtr, ToGlibPtrMut, Uninitialized}; -use glib::value::{FromValue, FromValueOptional, SetValue, ToSendValue, Value}; +use glib::value::ToSendValue; +use glib::StaticType; #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)] pub struct Fraction(pub Rational32); @@ -243,24 +244,33 @@ impl glib::types::StaticType for Fraction { } } -impl<'a> FromValue<'a> for Fraction { - unsafe fn from_value(v: &'a Value) -> Self { - let n = ffi::gst_value_get_fraction_numerator(v.to_glib_none().0); - let d = ffi::gst_value_get_fraction_denominator(v.to_glib_none().0); +impl glib::value::ValueType for Fraction { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for Fraction { + type Checker = glib::value::GenericValueTypeChecker<Self>; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + let n = ffi::gst_value_get_fraction_numerator(value.to_glib_none().0); + let d = ffi::gst_value_get_fraction_denominator(value.to_glib_none().0); Fraction::new(n, d) } } -impl<'a> FromValueOptional<'a> for Fraction { - unsafe fn from_value_optional(v: &'a Value) -> Option<Self> { - Some(Fraction::from_value(v)) +impl glib::value::ToValue for Fraction { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<Fraction>(); + unsafe { + ffi::gst_value_set_fraction(value.to_glib_none_mut().0, *self.numer(), *self.denom()); + } + value } -} -impl SetValue for Fraction { - unsafe fn set_value(v: &mut Value, f: &Self) { - ffi::gst_value_set_fraction(v.to_glib_none_mut().0, *f.numer(), *f.denom()); + fn value_type(&self) -> glib::Type { + Self::static_type() } } @@ -352,25 +362,39 @@ impl glib::types::StaticType for IntRange<i32> { } } -impl<'a> FromValue<'a> for IntRange<i32> { - unsafe fn from_value(v: &'a Value) -> Self { - let min = ffi::gst_value_get_int_range_min(v.to_glib_none().0); - let max = ffi::gst_value_get_int_range_max(v.to_glib_none().0); - let step = ffi::gst_value_get_int_range_step(v.to_glib_none().0); +impl glib::value::ValueType for IntRange<i32> { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for IntRange<i32> { + type Checker = glib::value::GenericValueTypeChecker<Self>; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + let min = ffi::gst_value_get_int_range_min(value.to_glib_none().0); + let max = ffi::gst_value_get_int_range_max(value.to_glib_none().0); + let step = ffi::gst_value_get_int_range_step(value.to_glib_none().0); Self::with_step(min, max, step) } } -impl<'a> FromValueOptional<'a> for IntRange<i32> { - unsafe fn from_value_optional(v: &'a Value) -> Option<Self> { - Some(Self::from_value(v)) +impl glib::value::ToValue for IntRange<i32> { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<IntRange<i32>>(); + unsafe { + ffi::gst_value_set_int_range_step( + value.to_glib_none_mut().0, + self.min(), + self.max(), + self.step(), + ); + } + value } -} -impl SetValue for IntRange<i32> { - unsafe fn set_value(v: &mut Value, r: &Self) { - ffi::gst_value_set_int_range_step(v.to_glib_none_mut().0, r.min(), r.max(), r.step()); + fn value_type(&self) -> glib::Type { + Self::static_type() } } @@ -380,25 +404,39 @@ impl glib::types::StaticType for IntRange<i64> { } } -impl<'a> FromValue<'a> for IntRange<i64> { - unsafe fn from_value(v: &'a Value) -> Self { - let min = ffi::gst_value_get_int64_range_min(v.to_glib_none().0); - let max = ffi::gst_value_get_int64_range_max(v.to_glib_none().0); - let step = ffi::gst_value_get_int64_range_step(v.to_glib_none().0); +impl glib::value::ValueType for IntRange<i64> { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for IntRange<i64> { + type Checker = glib::value::GenericValueTypeChecker<Self>; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + let min = ffi::gst_value_get_int64_range_min(value.to_glib_none().0); + let max = ffi::gst_value_get_int64_range_max(value.to_glib_none().0); + let step = ffi::gst_value_get_int64_range_step(value.to_glib_none().0); Self::with_step(min, max, step) } } -impl<'a> FromValueOptional<'a> for IntRange<i64> { - unsafe fn from_value_optional(v: &'a Value) -> Option<Self> { - Some(Self::from_value(v)) +impl glib::value::ToValue for IntRange<i64> { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<IntRange<i64>>(); + unsafe { + ffi::gst_value_set_int64_range_step( + value.to_glib_none_mut().0, + self.min(), + self.max(), + self.step(), + ); + } + value } -} -impl SetValue for IntRange<i64> { - unsafe fn set_value(v: &mut Value, r: &Self) { - ffi::gst_value_set_int64_range_step(v.to_glib_none_mut().0, r.min(), r.max(), r.step()); + fn value_type(&self) -> glib::Type { + Self::static_type() } } @@ -444,10 +482,17 @@ impl glib::types::StaticType for FractionRange { } } -impl<'a> FromValue<'a> for FractionRange { - unsafe fn from_value(v: &'a Value) -> Self { - let min = ffi::gst_value_get_fraction_range_min(v.to_glib_none().0); - let max = ffi::gst_value_get_fraction_range_max(v.to_glib_none().0); +impl glib::value::ValueType for FractionRange { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for FractionRange { + type Checker = glib::value::GenericValueTypeChecker<Self>; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + let min = ffi::gst_value_get_fraction_range_min(value.to_glib_none().0); + let max = ffi::gst_value_get_fraction_range_max(value.to_glib_none().0); let min_n = ffi::gst_value_get_fraction_numerator(min); let min_d = ffi::gst_value_get_fraction_denominator(min); @@ -458,21 +503,23 @@ impl<'a> FromValue<'a> for FractionRange { } } -impl<'a> FromValueOptional<'a> for FractionRange { - unsafe fn from_value_optional(v: &'a Value) -> Option<Self> { - Some(Self::from_value(v)) +impl glib::value::ToValue for FractionRange { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<FractionRange>(); + unsafe { + ffi::gst_value_set_fraction_range_full( + value.to_glib_none_mut().0, + *self.min().numer(), + *self.min().denom(), + *self.max().numer(), + *self.max().denom(), + ); + } + value } -} -impl SetValue for FractionRange { - unsafe fn set_value(v: &mut Value, r: &Self) { - ffi::gst_value_set_fraction_range_full( - v.to_glib_none_mut().0, - *r.min().numer(), - *r.min().denom(), - *r.max().numer(), - *r.max().denom(), - ); + fn value_type(&self) -> glib::Type { + Self::static_type() } } @@ -546,22 +593,31 @@ impl glib::types::StaticType for Bitmask { } } -impl<'a> FromValue<'a> for Bitmask { - unsafe fn from_value(v: &'a Value) -> Self { - let v = ffi::gst_value_get_bitmask(v.to_glib_none().0); +impl glib::value::ValueType for Bitmask { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for Bitmask { + type Checker = glib::value::GenericValueTypeChecker<Self>; + + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + let v = ffi::gst_value_get_bitmask(value.to_glib_none().0); Self::new(v) } } -impl<'a> FromValueOptional<'a> for Bitmask { - unsafe fn from_value_optional(v: &'a Value) -> Option<Self> { - Some(Self::from_value(v)) +impl glib::value::ToValue for Bitmask { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<Bitmask>(); + unsafe { + ffi::gst_value_set_bitmask(value.to_glib_none_mut().0, self.0); + } + value } -} -impl SetValue for Bitmask { - unsafe fn set_value(v: &mut Value, r: &Self) { - ffi::gst_value_set_bitmask(v.to_glib_none_mut().0, r.0); + fn value_type(&self) -> glib::Type { + Self::static_type() } } @@ -569,9 +625,10 @@ impl SetValue for Bitmask { pub struct Array<'a>(Cow<'a, [glib::SendValue]>); unsafe impl<'a> Send for Array<'a> {} +unsafe impl<'a> Sync for Array<'a> {} impl<'a> Array<'a> { - pub fn new(values: &[&dyn ToSendValue]) -> Self { + pub fn new(values: &[&(dyn ToSendValue + Sync)]) -> Self { assert_initialized_main_thread!(); Array(values.iter().map(|v| v.to_send_value()).collect()) @@ -598,8 +655,8 @@ impl<'a> Array<'a> { } } -impl<'a> From<&'a [&'a dyn ToSendValue]> for Array<'a> { - fn from(values: &'a [&'a dyn ToSendValue]) -> Self { +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) @@ -614,9 +671,16 @@ impl<'a> From<&'a [glib::SendValue]> for Array<'a> { } } -impl<'a> FromValue<'a> for Array<'a> { - unsafe fn from_value(v: &'a Value) -> Self { - let arr = (*v.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray; +impl<'a> glib::value::ValueType for Array<'static> { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for Array<'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() { Array(Cow::Borrowed(&[])) } else { @@ -629,17 +693,19 @@ impl<'a> FromValue<'a> for Array<'a> { } } -impl<'a> FromValueOptional<'a> for Array<'a> { - unsafe fn from_value_optional(v: &'a Value) -> Option<Self> { - Some(Array::from_value(v)) - } -} - -impl<'a> SetValue for Array<'a> { - unsafe fn set_value(v: &mut Value, a: &Self) { - for value in a.as_slice() { - ffi::gst_value_array_append_value(v.to_glib_none_mut().0, value.to_glib_none().0); +impl<'a> glib::value::ToValue for Array<'a> { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<Array<'static>>(); + 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 + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } @@ -653,9 +719,10 @@ impl<'a> glib::types::StaticType for Array<'a> { pub struct List<'a>(Cow<'a, [glib::SendValue]>); unsafe impl<'a> Send for List<'a> {} +unsafe impl<'a> Sync for List<'a> {} impl<'a> List<'a> { - pub fn new(values: &[&dyn ToSendValue]) -> Self { + pub fn new(values: &[&(dyn ToSendValue + Sync)]) -> Self { assert_initialized_main_thread!(); List(values.iter().map(|v| v.to_send_value()).collect()) @@ -682,8 +749,8 @@ impl<'a> List<'a> { } } -impl<'a> From<&'a [&'a dyn ToSendValue]> for List<'a> { - fn from(values: &'a [&'a dyn ToSendValue]) -> Self { +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) @@ -698,9 +765,16 @@ impl<'a> From<&'a [glib::SendValue]> for List<'a> { } } -impl<'a> FromValue<'a> for List<'a> { - unsafe fn from_value(v: &'a Value) -> Self { - let arr = (*v.to_glib_none().0).data[0].v_pointer as *const glib::ffi::GArray; +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>; + + 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(&[])) } else { @@ -713,17 +787,19 @@ impl<'a> FromValue<'a> for List<'a> { } } -impl<'a> FromValueOptional<'a> for List<'a> { - unsafe fn from_value_optional(v: &'a Value) -> Option<Self> { - Some(List::from_value(v)) - } -} - -impl<'a> SetValue for List<'a> { - unsafe fn set_value(v: &mut Value, a: &Self) { - for value in a.as_slice() { - ffi::gst_value_list_append_value(v.to_glib_none_mut().0, value.to_glib_none().0); +impl<'a> glib::value::ToValue for List<'a> { + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::<List<'static>>(); + 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 + } + + fn value_type(&self) -> glib::Type { + Self::static_type() } } diff --git a/gstreamer/src/value_serde.rs b/gstreamer/src/value_serde.rs index ed0e2c60b..c3d6dc03b 100644 --- a/gstreamer/src/value_serde.rs +++ b/gstreamer/src/value_serde.rs @@ -52,7 +52,7 @@ impl<'de> Deserialize<'de> for Fraction { macro_rules! ser_some_value ( ($value:expr, $t:ty, $ser_closure:expr) => ( { - let value = $value.get_some::<$t>().expect("ser_some_value macro"); + let value = $value.get::<$t>().expect("ser_some_value macro"); $ser_closure(stringify!($t), value) } ); @@ -60,7 +60,7 @@ macro_rules! ser_some_value ( macro_rules! ser_opt_value ( ($value:expr, $t:ty, $ser_closure:expr) => ( { - let value = $value.get::<$t>().expect("ser_opt_value macro"); + let value = $value.get::<Option<$t>>().expect("ser_opt_value macro"); $ser_closure(stringify!($t), value) } ); @@ -523,54 +523,60 @@ mod tests { let slice = array.as_slice(); assert_eq!(6, slice.len()); - let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap(); + 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]").unwrap(); + 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]").unwrap() + slice[2].get::<String>().expect("slice[2]") ); - assert!(slice[3].get::<String>().expect("slice[3]").is_none()); + assert!(slice[3] + .get::<Option<String>>() + .expect("slice[3]") + .is_none()); assert_eq!( Date::new_dmy(19, DateMonth::August, 2019).unwrap(), - slice[4].get::<Date>().expect("slice[4]").unwrap() + slice[4].get::<Date>().expect("slice[4]") ); - assert!(slice[5].get::<Date>().expect("slice[5]").is_none()); + assert!(slice[5].get::<Option<Date>>().expect("slice[5]").is_none()); let array_json = r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"],["String",null],["Date",{"YMD":[2019,8,19]}],["Date",null]]"#; let array: Array = serde_json::from_str(array_json).unwrap(); let slice = array.as_slice(); assert_eq!(6, slice.len()); - let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap(); + 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]").unwrap(); + 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]").unwrap() + slice[2].get::<String>().expect("slice[2]") ); - assert!(slice[3].get::<String>().expect("slice[3]").is_none()); + assert!(slice[3] + .get::<Option<String>>() + .expect("slice[3]") + .is_none()); assert_eq!( Date::new_dmy(19, DateMonth::August, 2019).unwrap(), - slice[4].get::<Date>().expect("slice[4]").unwrap() + slice[4].get::<Date>().expect("slice[4]") ); - assert!(slice[5].get::<Date>().expect("slice[5]").is_none()); + assert!(slice[5].get::<Option<Date>>().expect("slice[5]").is_none()); // List let list_ron = r#"[ @@ -584,23 +590,29 @@ mod tests { let slice = list.as_slice(); assert_eq!(5, slice.len()); - let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap(); + 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]").unwrap() + slice[1].get::<String>().expect("slice[1]") ); - assert!(slice[2].get::<String>().expect("slice[2]").is_none()); + assert!(slice[2] + .get::<Option<String>>() + .expect("slice[2]") + .is_none()); assert_eq!( DateTime::new(2f32, 2019, 8, 19, 13, 34, 42f64).unwrap(), - slice[3].get::<DateTime>().expect("slice[3]").unwrap() + slice[3].get::<DateTime>().expect("slice[3]") ); - assert!(slice[4].get::<DateTime>().expect("slice[4]").is_none()); + assert!(slice[4] + .get::<Option<DateTime>>() + .expect("slice[4]") + .is_none()); } #[test] @@ -630,29 +642,32 @@ mod tests { let slice = array.as_slice(); assert_eq!(slice_de.len(), slice.len()); - let fraction_de = slice_de[0].get::<Fraction>().expect("slice_de[0]").unwrap(); - let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap(); + let fraction_de = slice_de[0].get::<Fraction>().expect("slice_de[0]"); + let fraction = slice[0].get::<Fraction>().expect("slice[0]"); assert_eq!(fraction_de.0.numer(), fraction.0.numer()); assert_eq!(fraction_de.0.denom(), fraction.0.denom()); - let fraction_de = slice_de[1].get::<Fraction>().expect("slice_de[1]").unwrap(); - let fraction = slice[1].get::<Fraction>().expect("slice[1]").unwrap(); + let fraction_de = slice_de[1].get::<Fraction>().expect("slice_de[1]"); + let fraction = slice[1].get::<Fraction>().expect("slice[1]"); assert_eq!(fraction_de.0.numer(), fraction.0.numer()); assert_eq!(fraction.0.denom(), fraction.0.denom()); assert_eq!( - slice_de[2].get::<String>().expect("slice_de[2]").unwrap(), - slice[2].get::<String>().expect("slice[2]").unwrap() + slice_de[2].get::<String>().expect("slice_de[2]"), + slice[2].get::<String>().expect("slice[2]") ); - assert!(slice[3].get::<String>().expect("slice[3]").is_none()); + assert!(slice[3] + .get::<Option<String>>() + .expect("slice[3]") + .is_none()); assert_eq!( - slice_de[4].get::<Date>().expect("slice_de[4]").unwrap(), - slice[4].get::<Date>().expect("slice[4]").unwrap() + slice_de[4].get::<Date>().expect("slice_de[4]"), + slice[4].get::<Date>().expect("slice[4]") ); - assert!(slice[5].get::<Date>().expect("slice[5]").is_none()); + assert!(slice[5].get::<Option<Date>>().expect("slice[5]").is_none()); // List let value_12 = Fraction::new(1, 2); @@ -675,23 +690,29 @@ mod tests { let slice = list.as_slice(); assert_eq!(slice_de.len(), slice.len()); - let fraction_de = slice_de[0].get::<Fraction>().expect("slice_de[0]").unwrap(); - let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap(); + let fraction_de = slice_de[0].get::<Fraction>().expect("slice_de[0]"); + let fraction = slice[0].get::<Fraction>().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::<String>().expect("slice_de[1]").unwrap(), - slice[1].get::<String>().expect("slice[1]").unwrap() + slice_de[1].get::<String>().expect("slice_de[1]"), + slice[1].get::<String>().expect("slice[1]") ); - assert!(slice[2].get::<String>().expect("slice[2]").is_none()); + assert!(slice[2] + .get::<Option<String>>() + .expect("slice[2]") + .is_none()); assert_eq!( - slice_de[3].get::<DateTime>().expect("slice_de[3]").unwrap(), - slice[3].get::<DateTime>().expect("slice[3]").unwrap() + slice_de[3].get::<DateTime>().expect("slice_de[3]"), + slice[3].get::<DateTime>().expect("slice[3]") ); - assert!(slice[4].get::<DateTime>().expect("slice[4]").is_none()); + assert!(slice[4] + .get::<Option<DateTime>>() + .expect("slice[4]") + .is_none()); } } diff --git a/tutorials/src/bin/basic-tutorial-13.rs b/tutorials/src/bin/basic-tutorial-13.rs index b559b2bcc..15fff4032 100644 --- a/tutorials/src/bin/basic-tutorial-13.rs +++ b/tutorials/src/bin/basic-tutorial-13.rs @@ -56,7 +56,11 @@ fn send_seek_event(pipeline: &Element, rate: f64) -> bool { }; // If we have not done so, obtain the sink through which we will send the seek events - if let Ok(Some(video_sink)) = pipeline.property("video-sink").unwrap().get::<Element>() { + if let Ok(Some(video_sink)) = pipeline + .property("video-sink") + .unwrap() + .get::<Option<Element>>() + { println!("Current rate: {}\r", rate); // Send the event video_sink.send_event(seek_event) @@ -171,8 +175,10 @@ USAGE: Choose one of the following options, then press enter: } } Command::NextFrame => { - if let Ok(Some(video_sink)) = - pipeline.property("video-sink").unwrap().get::<Element>() + if let Ok(Some(video_sink)) = pipeline + .property("video-sink") + .unwrap() + .get::<Option<Element>>() { // Send the event let step = Step::new(gst::format::Buffers(Some(1)), rate.abs(), true, false); diff --git a/tutorials/src/bin/basic-tutorial-5.rs b/tutorials/src/bin/basic-tutorial-5.rs index 22a2c70c9..b29b810a0 100644 --- a/tutorials/src/bin/basic-tutorial-5.rs +++ b/tutorials/src/bin/basic-tutorial-5.rs @@ -41,46 +41,28 @@ mod tutorial5 { let propname: &str = &format!("n-{}", stype); let signame: &str = &format!("get-{}-tags", stype); - match playbin.property(propname).unwrap().get() { - Ok(Some(x)) => { - for i in 0..x { - let tags = playbin.emit_by_name(signame, &[&i]).unwrap().unwrap(); + let x = playbin.property(propname).unwrap().get::<i32>().unwrap(); + for i in 0..x { + let tags = playbin.emit_by_name(signame, &[&i]).unwrap().unwrap(); - if let Ok(Some(tags)) = tags.get::<gst::TagList>() { - textbuf.insert_at_cursor(&format!("{} stream {}:\n ", stype, i)); + if let Ok(Some(tags)) = tags.get::<Option<gst::TagList>>() { + textbuf.insert_at_cursor(&format!("{} stream {}:\n ", stype, i)); - if let Some(codec) = tags.get::<gst::tags::VideoCodec>() { - textbuf.insert_at_cursor(&format!( - " codec: {} \n", - codec.get().unwrap() - )); - } - - if let Some(codec) = tags.get::<gst::tags::AudioCodec>() { - textbuf.insert_at_cursor(&format!( - " codec: {} \n", - codec.get().unwrap() - )); - } - - if let Some(lang) = tags.get::<gst::tags::LanguageCode>() { - textbuf.insert_at_cursor(&format!( - " language: {} \n", - lang.get().unwrap() - )); - } - - if let Some(bitrate) = tags.get::<gst::tags::Bitrate>() { - textbuf.insert_at_cursor(&format!( - " bitrate: {} \n", - bitrate.get().unwrap() - )); - } - } + if let Some(codec) = tags.get::<gst::tags::VideoCodec>() { + textbuf.insert_at_cursor(&format!(" codec: {} \n", codec.get())); + } + + if let Some(codec) = tags.get::<gst::tags::AudioCodec>() { + textbuf.insert_at_cursor(&format!(" codec: {} \n", codec.get())); + } + + if let Some(lang) = tags.get::<gst::tags::LanguageCode>() { + textbuf.insert_at_cursor(&format!(" language: {} \n", lang.get())); + } + + if let Some(bitrate) = tags.get::<gst::tags::Bitrate>() { + textbuf.insert_at_cursor(&format!(" bitrate: {} \n", bitrate.get())); } - } - _ => { - eprintln!("Could not get {}!", propname); } } } @@ -329,8 +311,7 @@ mod tutorial5 { .connect("video-tags-changed", false, |args| { let pipeline = args[0] .get::<gst::Element>() - .expect("playbin \"video-tags-changed\" args[0]") - .unwrap(); + .expect("playbin \"video-tags-changed\" args[0]"); post_app_message(&pipeline); None }) @@ -340,8 +321,7 @@ mod tutorial5 { .connect("audio-tags-changed", false, |args| { let pipeline = args[0] .get::<gst::Element>() - .expect("playbin \"audio-tags-changed\" args[0]") - .unwrap(); + .expect("playbin \"audio-tags-changed\" args[0]"); post_app_message(&pipeline); None }) @@ -351,8 +331,7 @@ mod tutorial5 { .connect("text-tags-changed", false, move |args| { let pipeline = args[0] .get::<gst::Element>() - .expect("playbin \"text-tags-changed\" args[0]") - .unwrap(); + .expect("playbin \"text-tags-changed\" args[0]"); post_app_message(&pipeline); None }) diff --git a/tutorials/src/bin/basic-tutorial-9.rs b/tutorials/src/bin/basic-tutorial-9.rs index 20340d7ed..50b85c4e3 100644 --- a/tutorials/src/bin/basic-tutorial-9.rs +++ b/tutorials/src/bin/basic-tutorial-9.rs @@ -11,7 +11,7 @@ use std::env; mod tutorials_common; fn send_value_as_str(v: &glib::SendValue) -> Option<String> { - if let Ok(Some(s)) = v.get::<&str>() { + if let Ok(s) = v.get::<&str>() { Some(s.to_string()) } else if let Ok(serialized) = v.serialize() { Some(serialized.into()) diff --git a/tutorials/src/bin/playback-tutorial-4.rs b/tutorials/src/bin/playback-tutorial-4.rs index e54413d2d..073a94d36 100644 --- a/tutorials/src/bin/playback-tutorial-4.rs +++ b/tutorials/src/bin/playback-tutorial-4.rs @@ -100,18 +100,14 @@ fn tutorial_main() -> Result<(), Error> { .expect("Failed to add bus watch"); pipeline.connect("deep-notify::temp-location", false, |args| { - let download_buffer = args[1] - .get::<gst::Object>() - .unwrap() - .expect("download buffer"); + let download_buffer = args[1].get::<gst::Object>().unwrap(); println!( "Temporary file: {:?}", download_buffer .property("temp-location") .unwrap() - .get::<String>() + .get::<Option<String>>() .unwrap() - .as_deref() ); // Uncomment this line to keep the temporary file after the program exists. // download_buffer.set_property("temp-remove", &false).ok();