Update for Value trait refactoring

This commit is contained in:
Sebastian Dröge 2021-04-20 10:19:02 +03:00
parent 0eb5845934
commit eda1d3d4a7
54 changed files with 1254 additions and 871 deletions

View file

@ -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::<bool>("send_eos").unwrap();
let send_eos = s.get::<bool>("send_eos").unwrap();
Some(ExampleCustomEvent { send_eos })
}
_ => None, // Not a custom event

View file

@ -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 {

View file

@ -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 {

View file

@ -37,7 +37,7 @@ fn create_ui(app: &gtk::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::<gtk::Widget>().unwrap().unwrap())
(glsinkbin, widget.get::<gtk::Widget>().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: &gtk::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::<gtk::Widget>().unwrap().unwrap())
(sink, widget.get::<gtk::Widget>().unwrap())
};
pipeline.add_many(&[&src, &sink]).unwrap();

View file

@ -139,8 +139,8 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
let drawer = drawer.lock().unwrap();
// Get the signal's arguments
let _overlay = args[0].get::<gst::Element>().unwrap().unwrap();
let sample = args[1].get::<gst::Sample>().unwrap().unwrap();
let _overlay = args[0].get::<gst::Element>().unwrap();
let sample = args[1].get::<gst::Sample>().unwrap();
let buffer = sample.buffer().unwrap();
let timestamp = buffer.pts();
@ -276,8 +276,8 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
// stream that dynamically changes resolution when enough bandwith is available.
overlay
.connect("caps-changed", false, move |args| {
let _overlay = args[0].get::<gst::Element>().unwrap().unwrap();
let caps = args[1].get::<gst::Caps>().unwrap().unwrap();
let _overlay = args[0].get::<gst::Element>().unwrap();
let caps = args[1].get::<gst::Caps>().unwrap();
let mut drawer = drawer.lock().unwrap();
drawer.info = Some(gst_video::VideoInfo::from_caps(&caps).unwrap());

View file

@ -133,12 +133,12 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
let drawer = drawer.lock().unwrap();
// Get the signal's arguments
let _overlay = args[0].get::<gst::Element>().unwrap().unwrap();
let _overlay = args[0].get::<gst::Element>().unwrap();
// This is the cairo context. This is the root of all of cairo's
// drawing functionality.
let cr = args[1].get::<cairo::Context>().unwrap().unwrap();
let timestamp = args[2].get_some::<gst::ClockTime>().unwrap();
let _duration = args[3].get_some::<gst::ClockTime>().unwrap();
let cr = args[1].get::<cairo::Context>().unwrap();
let timestamp = args[2].get::<gst::ClockTime>().unwrap();
let _duration = args[3].get::<gst::ClockTime>().unwrap();
let info = drawer.info.as_ref().unwrap();
let layout = drawer.layout.borrow();
@ -207,8 +207,8 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
// stream that dynamically changes resolution when enough bandwith is available.
overlay
.connect("caps-changed", false, move |args| {
let _overlay = args[0].get::<gst::Element>().unwrap().unwrap();
let caps = args[1].get::<gst::Caps>().unwrap().unwrap();
let _overlay = args[0].get::<gst::Element>().unwrap();
let caps = args[1].get::<gst::Caps>().unwrap();
let mut drawer = drawer.lock().unwrap();
drawer.info = Some(gst_video::VideoInfo::from_caps(&caps).unwrap());

View file

@ -57,12 +57,11 @@ fn example_main() {
// mark the beginning of a new track, or a new DJ.
let playbin = values[0]
.get::<glib::Object>()
.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::<i32>()
.get::<i32>()
.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::<gst::TagList>().expect("tags").unwrap();
let tags = tags.get::<gst::TagList>().expect("tags");
if let Some(artist) = tags.get::<gst::tags::Artist>() {
println!(" Artist: {}", artist.get().unwrap());
println!(" Artist: {}", artist.get());
}
if let Some(title) = tags.get::<gst::tags::Title>() {
println!(" Title: {}", title.get().unwrap());
println!(" Title: {}", title.get());
}
if let Some(album) = tags.get::<gst::tags::Album>() {
println!(" Album: {}", album.get().unwrap());
println!(" Album: {}", album.get());
}
None

View file

@ -87,8 +87,7 @@ fn make_fec_decoder(rtpbin: &gst::Element, sess_id: u32) -> Result<gst::Element,
.unwrap()
.unwrap()
.get::<glib::Object>()
.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::<gst::Element>()
.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::<u32>()
.get::<u32>()
.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::<gst::Element>()
.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::<u32>()
.get::<u32>()
.expect("rtpbin \"request-fec-decoder\" signal values[1]");
match make_fec_decoder(&rtpbin, sess_id) {

View file

@ -109,8 +109,7 @@ fn example_main() -> Result<(), Error> {
rtpbin.connect("request-fec-encoder", false, move |values| {
let rtpbin = values[0]
.get::<gst::Element>()
.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()),

View file

@ -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::<gst::Caps>()
.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 {

View file

@ -683,7 +683,7 @@ pub(crate) fn main_loop(app: App) -> Result<(), Error> {
gst_gl_context = glupload
.property("context")
.unwrap()
.get::<gst_gl::GLContext>()
.get::<Option<gst_gl::GLContext>>()
.unwrap();
}

View file

@ -150,15 +150,12 @@ impl AudioConverterConfig {
.as_slice()
.iter()
.map(|val| {
let array = val
.get::<gst::Array>()
.expect("Wrong type")
.unwrap_or_else(|| gst::Array::from_owned(Vec::new()));
let array = val.get::<gst::Array>().expect("Wrong type");
array
.as_slice()
.iter()
.map(|val| val.get_some::<f32>().expect("Wrong type"))
.map(|val| val.get::<f32>().expect("Wrong type"))
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()

View file

@ -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<Self> {
Option::<AudioFormatInfo>::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<Self>;
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::<AudioFormatInfo>();
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::<AudioFormatInfo>();
unsafe {
glib::gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0,
s.to_glib_none().0 as *mut _,
)
}
value
}
}

View file

@ -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<Self> {
Option::<AudioInfo>::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<Self>;
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::<AudioInfo>();
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::<AudioInfo>();
unsafe {
glib::gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0,
s.to_glib_none().0 as *mut _,
)
}
value
}
}

View file

@ -135,7 +135,6 @@ impl<O: IsA<Aggregator>> AggregatorExtManual for O {
value
.get()
.expect("AggregatorExtManual::min_upstream_latency")
.unwrap()
}
}

View file

@ -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::*;

View file

@ -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::*;

View file

@ -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;

View file

@ -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<F: Fn(&Self) + Send + Sync + 'static>(

View file

@ -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::*;

View file

@ -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();

View file

@ -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<Self> {
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<Self>;
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::<SDPMessage>();
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::<SDPMessage>();
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
}
}

View file

@ -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<gst::Seqnum>,
running_time_offset: Option<i64>,
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<gst::Seqnum>,
running_time_offset: Option<i64>,
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<gst::Seqnum>,
running_time_offset: Option<i64>,
other_fields: Vec<(&'a str, &'a dyn ToSendValue)>,
other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>,
in_still: bool,
}

View file

@ -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<Self> {
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<Self>;
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::<VideoColorRange>();
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<Self> {
Option::<VideoInfo>::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<Self>;
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::<VideoInfo>();
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::<VideoInfo>();
unsafe {
glib::gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0,
s.to_glib_none().0 as *mut _,
)
}
value
}
}

View file

@ -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<Self> {
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<Self>;
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
}
}
};

View file

@ -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<Self> {
Option::<VideoTimeCodeInterval>::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<Self>;
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::<VideoTimeCodeInterval>();
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::<VideoTimeCodeInterval>();
unsafe {
glib::gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0,
s.to_glib_none().0 as *mut _,
)
}
value
}
}

View file

@ -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::*;

View file

@ -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<NoFeature> {
}
impl<T> Builder<T> {
pub fn field<'b, V: ToSendValue>(mut self, name: &'b str, value: &'b V) -> Self {
pub fn field<V: ToSendValue + Sync>(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(),

View file

@ -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<ffi::GstCapsFeatures>);
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<Self> {
<&'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<Self>;
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) {
<CapsFeaturesRef as glib::value::SetValue>::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::<CapsFeatures>();
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>) {
<CapsFeaturesRef as glib::value::SetValueOptional>::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::<CapsFeatures>();
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<Self> {
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<Self>;
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::<CapsFeatures>();
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::<CapsFeatures>();
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::<CapsFeatures>().unwrap().is_none());
let a = None::<CapsFeatures>.to_value();
assert!(a.get::<Option<CapsFeatures>>().unwrap().is_none());
let b = glib::value::Value::from(&CapsFeatures::new_empty());
assert!(b.get::<CapsFeatures>().unwrap().is_some());
assert!(b.get::<Option<CapsFeatures>>().unwrap().is_some());
}
}

View file

@ -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();

View file

@ -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<ffi::GstClockTime> 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<Self> {
<u64 as glib::value::FromValueOptional>::from_value_optional(value)
.map(|x| ClockTime::from_glib(x))
unsafe impl<'a> glib::value::FromValue<'a> for ClockTime {
type Checker = glib::value::GenericValueTypeChecker<Self>;
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(<u64 as glib::value::FromValue>::from_value(value))
impl glib::value::ToValue for ClockTime {
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<ClockTime>();
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) {
<u64 as glib::value::SetValue>::set_value(value, &this.to_glib());
fn value_type(&self) -> glib::Type {
Self::static_type()
}
}

View file

@ -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<glib::Date> 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()
}
}

View file

@ -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<Self> {
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<Self>;
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::<MessageType>();
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()
}
}

View file

@ -1143,7 +1143,7 @@ impl<'a> CustomBothOob<'a> {
struct EventBuilder<'a> {
seqnum: Option<Seqnum>,
running_time_offset: Option<i64>,
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));
}
}

View file

@ -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<T> {
impl<T> Iterator<T>
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::<T>().expect("Iterator::next") {
Some(value) => Ok(Some(value)),
None => Err(IteratorError::Error),
ffi::GST_ITERATOR_OK => match value.get::<T>() {
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<F>(self, func: F) -> Self
where
F: Fn(T) -> bool + Send + Sync + 'static,
T: StaticType,
{
unsafe {
let func_box: Box<dyn Fn(T) -> bool + Send + Sync + 'static> = Box::new(func);
@ -100,7 +101,7 @@ where
func_ptr,
));
if res {
elem.get::<T>().expect("Iterator::find")
Some(elem.get::<T>().expect("Iterator::find"))
} else {
None
}
@ -164,7 +165,7 @@ where
impl<T> Iterator<T>
where
for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static,
for<'a> T: FromValue<'a> + StaticType + ToValue + Send + 'static,
{
pub fn new<I: IteratorImpl<T>>(imp: I) -> Self {
assert_initialized_main_thread!();
@ -195,7 +196,7 @@ where
impl<T> Iterator<T>
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<T>) -> Self {
skip_assert_initialized!();
@ -206,7 +207,7 @@ where
#[repr(C)]
struct RsIterator<T, I: IteratorImpl<T>>
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<T>: 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<Result<T, IteratorError>>;
fn resync(&mut self);
@ -225,7 +226,7 @@ unsafe extern "C" fn rs_iterator_copy<T, I: IteratorImpl<T>>(
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<T, I>;
let copy = copy as *mut RsIterator<T, I>;
@ -235,7 +236,7 @@ unsafe extern "C" fn rs_iterator_copy<T, I: IteratorImpl<T>>(
unsafe extern "C" fn rs_iterator_free<T, I: IteratorImpl<T>>(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<T, I>;
ptr::drop_in_place(&mut (*it).imp);
@ -246,7 +247,7 @@ unsafe extern "C" fn rs_iterator_next<T, I: IteratorImpl<T>>(
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<T, I>;
match (*it).imp.next() {
@ -265,7 +266,7 @@ where
unsafe extern "C" fn rs_iterator_resync<T, I: IteratorImpl<T>>(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<T, I>;
(*it).imp.resync();
@ -279,7 +280,7 @@ struct VecIteratorImpl<T> {
impl<T> VecIteratorImpl<T>
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<T>) -> Self {
skip_assert_initialized!();
@ -289,7 +290,7 @@ where
impl<T> IteratorImpl<T> for VecIteratorImpl<T>
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<Result<T, IteratorError>> {
if self.pos < self.items.len() {
@ -311,7 +312,7 @@ unsafe impl<T> Sync for Iterator<T> {}
unsafe extern "C" fn filter_trampoline<T>(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::<T>()
.expect("Iterator filter_trampoline")
.unwrap();
let value = value.get::<T>().expect("Iterator filter_trampoline");
if func(value) {
0
@ -399,13 +397,13 @@ unsafe extern "C" fn find_trampoline<T, F: FnMut(T) -> 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::<T>().expect("Iterator find_trampoline").unwrap();
let value = value.get::<T>().expect("Iterator find_trampoline");
if (*func)(value) {
0
@ -418,14 +416,11 @@ unsafe extern "C" fn foreach_trampoline<T, F: FnMut(T)>(
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::<T>()
.expect("Iterator foreach_trampoline")
.unwrap();
let value = value.get::<T>().expect("Iterator foreach_trampoline");
(*func)(value);
}
@ -436,11 +431,11 @@ unsafe extern "C" fn fold_trampoline<T, U, F: FnMut(U, T) -> Result<U, U>>(
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::<T>().expect("Iterator fold_trampoline").unwrap();
let value = value.get::<T>().expect("Iterator fold_trampoline");
let accum = &mut *(glib::gobject_ffi::g_value_get_pointer(ret) as *mut Option<U>);
@ -480,7 +475,7 @@ impl<T> Drop for Iterator<T> {
impl<T> iter::IntoIterator for Iterator<T>
where
for<'a> T: FromValueOptional<'a> + 'static,
for<'a> T: FromValue<'a> + 'static,
{
type Item = Result<T, IteratorError>;
type IntoIter = StdIterator<T>;
@ -496,34 +491,49 @@ impl<T> glib::types::StaticType for Iterator<T> {
}
}
#[doc(hidden)]
impl<'a, T: StaticType> glib::value::FromValueOptional<'a> for Iterator<T> {
unsafe fn from_value_optional(value: &glib::Value) -> Option<Self> {
Option::<Iterator<T>>::from_glib_none(glib::gobject_ffi::g_value_get_boxed(
value.to_glib_none().0,
) as *mut ffi::GstIterator)
}
impl<T: StaticType + 'static> glib::value::ValueType for Iterator<T> {
type Type = Self;
}
#[doc(hidden)]
impl<T: 'static> glib::value::SetValue for Iterator<T> {
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<T> {
type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
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<T: 'static> glib::value::SetValueOptional for Iterator<T> {
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<T: StaticType + 'static> glib::value::ToValue for Iterator<T> {
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Self>();
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<T: StaticType + 'static> glib::value::ToValueOptional for Iterator<T> {
fn to_value_optional(s: Option<&Self>) -> glib::Value {
skip_assert_initialized!();
let mut value = glib::Value::for_value_type::<Self>();
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<T> fmt::Debug for StdIterator<T> {
impl<T> iter::Iterator for StdIterator<T>
where
for<'a> T: FromValueOptional<'a> + 'static,
for<'a> T: FromValue<'a> + 'static,
{
type Item = Result<T, IteratorError>;

View file

@ -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::*;

View file

@ -1555,7 +1555,7 @@ struct MessageBuilder<'a> {
src: Option<Object>,
seqnum: Option<Seqnum>,
#[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

View file

@ -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<Self> {
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<Self>;
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 {
<Self as $crate::glib::StaticType>::static_type()
}
}
impl<'a> $crate::glib::value::FromValueOptional<'a>
for &'a $ref_name
{
unsafe fn from_value_optional(v: &'a glib::Value) -> Option<Self> {
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<Self>;
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)
}
}

View file

@ -57,13 +57,11 @@ impl<O: IsA<crate::Object>> 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);

View file

@ -1663,7 +1663,7 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
let gtype = templ
.property("gtype")
.unwrap()
.get_some::<glib::Type>()
.get::<glib::Type>()
.unwrap();
if gtype == glib::Type::UNIT {

View file

@ -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<T: FormattedValue> glib::types::StaticType for FormattedSegment<T> {
}
}
#[doc(hidden)]
impl<'a> glib::value::FromValueOptional<'a> for Segment {
unsafe fn from_value_optional(value: &glib::Value) -> Option<Self> {
Option::<Segment>::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<T: FormattedValue> glib::value::SetValue for FormattedSegment<T> {
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<Self>;
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<T: FormattedValue> glib::value::SetValueOptional for FormattedSegment<T> {
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<T: FormattedValue> glib::value::ToValue for FormattedSegment<T> {
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Segment>();
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<T: FormattedValue> glib::value::ToValueOptional for FormattedSegment<T> {
fn to_value_optional(s: Option<&Self>) -> glib::Value {
skip_assert_initialized!();
let mut value = glib::Value::for_value_type::<Segment>();
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<T: FormattedValue> glib::translate::GlibPtrDefault for FormattedSegment<T> {
type GlibType = *mut ffi::GstSegment;

View file

@ -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<Self> {
Option::<StaticCaps>::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<Self>;
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::<StaticCaps>();
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::<StaticCaps>();
unsafe {
glib::gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0,
s.to_glib_none().0 as *mut _,
)
}
value
}
}

View file

@ -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<Self> {
Option::<StaticPadTemplate>::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<Self>;
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::<StaticPadTemplate>();
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::<StaticPadTemplate>();
unsafe {
glib::gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0,
s.to_glib_none().0 as *mut _,
)
}
value
}
}

View file

@ -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<E: GlibValueError>(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<Self> {
<&'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) {
<StructureRef as glib::value::SetValue>::set_value(v, s.as_ref())
}
}
unsafe impl<'a> glib::value::FromValue<'a> for Structure {
type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
impl glib::value::SetValueOptional for Structure {
unsafe fn set_value_optional(v: &mut glib::Value, s: Option<&Self>) {
<StructureRef as glib::value::SetValueOptional>::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::<Structure>();
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::<Structure>();
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<Option<T>, GetError<'name>> {
self.value(name)?
pub fn get<'a, T: FromValue<'a>>(&'a self, name: &str) -> Result<T, GetError>
where
<<T as FromValue<'a>>::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<Option<T>, GetError>
where
<<T as FromValue<'a>>::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<T, GetError>
where
<<T as FromValue<'a>>::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<Option<T>, 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<Option<T>, GetError>
where
<<T as FromValue<'a>>::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<T, GetError<'name>> {
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<T: ToSendValue>(&mut self, name: &str, value: &T) {
pub fn set<T: ToSendValue + Sync>(&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<T: ToSendValue + Sync>(&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<Self> {
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<Self>;
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::<Structure>();
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::<Structure>();
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<V: ToSendValue>(mut self, name: &str, value: &V) -> Self {
pub fn field<V: ToSendValue + Sync>(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::<i32>("f3"), Ok(123i32));
assert_eq!(s.get::<&str>("f1"), Ok("abc"));
assert_eq!(s.get::<Option<&str>>("f2"), Ok(Some("bcd")));
assert_eq!(s.get::<i32>("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::<i32>("f3"), Ok(Some(123i32)));
@ -768,35 +860,32 @@ mod tests {
s.get::<i32>("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::<bool>("f3"),
s.get::<bool>("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::<i32>("f4"),
Err(GetError::new_field_not_found("f4"))
);
assert_eq!(s.get::<i32>("f4"), Err(GetError::new_field_not_found("f4")));
assert_eq!(s.fields().collect::<Vec<_>>(), vec!["f1", "f2", "f3"]);
let v = s.iter().map(|(f, v)| (f, v.clone())).collect::<Vec<_>>();
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::<i32>(), Ok(123i32));
assert_eq!(v[2].1.get::<i32>(), 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::<i32>("f3"), Ok(123i32));
assert_eq!(s.get::<&str>("f1"), Ok("abc"));
assert_eq!(s.get::<&str>("f2"), Ok("bcd"));
assert_eq!(s.get::<i32>("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::<u32>("f2"), Ok(123));
assert_eq!(s.get::<&str>("f1"), Ok("abc"));
assert_eq!(s.get::<u32>("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::<Structure>().unwrap().is_none());
let b = glib::value::Value::from(&Structure::from_str(&"foo").unwrap());
assert!(b.get::<Structure>().unwrap().is_some());
let a = None::<&Structure>.to_value();
assert!(a.get::<Option<Structure>>().unwrap().is_none());
let b = Structure::from_str(&"foo").unwrap().to_value();
assert!(b.get::<Option<Structure>>().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());
}

View file

@ -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<O: IsA<TagSetter>> 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();

View file

@ -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<T>(SendValue, PhantomData<T>);
impl<T> TagValue<T> {
pub fn get<'a>(&'a self) -> Option<T>
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 = <T::TagType as ToSendValue>::to_send_value(value);
let _res = self.add_value(T::tag_name(), &v, mode);
}
pub fn add_generic<T>(
pub fn add_generic<T: ToSendValue + Sync>(
&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::<Duration>(&(crate::SECOND * 120), TagMergeMode::Append);
}
assert_eq!(tags.get::<Title>().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"
);
}

View file

@ -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();

View file

@ -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());
}

View file

@ -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()
}
}

View file

@ -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());
}
}

View file

@ -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);

View file

@ -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
})

View file

@ -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())

View file

@ -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();