forked from mirrors/gstreamer-rs
Manual update for new Value::get
signature
This commit is contained in:
parent
5d012945df
commit
514a05accd
13 changed files with 247 additions and 78 deletions
|
@ -60,10 +60,15 @@ fn example_main() {
|
||||||
// The metadata of any of the contained audio streams changed
|
// The metadata of any of the contained audio streams changed
|
||||||
// In the case of a live-stream from an internet radio, this could for example
|
// In the case of a live-stream from an internet radio, this could for example
|
||||||
// mark the beginning of a new track, or a new DJ.
|
// mark the beginning of a new track, or a new DJ.
|
||||||
let playbin = values[0].get::<glib::Object>().unwrap();
|
let playbin = values[0]
|
||||||
|
.get::<glib::Object>()
|
||||||
|
.expect("playbin \"audio-tags-changed\" signal values[1]")
|
||||||
|
.unwrap();
|
||||||
// This gets the index of the stream that changed. This is neccessary, since
|
// This gets the index of the stream that changed. This is neccessary, since
|
||||||
// there could e.g. be multiple audio streams (english, spanish, ...).
|
// there could e.g. be multiple audio streams (english, spanish, ...).
|
||||||
let idx = values[1].get::<i32>().unwrap();
|
let idx = values[1]
|
||||||
|
.get_some::<i32>()
|
||||||
|
.expect("playbin \"audio-tags-changed\" signal values[1]");
|
||||||
|
|
||||||
println!("audio tags of audio stream {} changed:", idx);
|
println!("audio tags of audio stream {} changed:", idx);
|
||||||
|
|
||||||
|
@ -81,7 +86,7 @@ fn example_main() {
|
||||||
.emit("get-audio-tags", &[&idx.to_value()])
|
.emit("get-audio-tags", &[&idx.to_value()])
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let tags = tags.get::<gst::TagList>().unwrap();
|
let tags = tags.get::<gst::TagList>().expect("tags").unwrap();
|
||||||
|
|
||||||
if let Some(artist) = tags.get::<gst::tags::Artist>() {
|
if let Some(artist) = tags.get::<gst::tags::Artist>() {
|
||||||
println!(" Artist: {}", artist.get().unwrap());
|
println!(" Artist: {}", artist.get().unwrap());
|
||||||
|
|
|
@ -151,7 +151,10 @@ fn example_main() -> Result<(), Error> {
|
||||||
src.link(&netsim)?;
|
src.link(&netsim)?;
|
||||||
|
|
||||||
rtpbin.connect("new-storage", false, |values| {
|
rtpbin.connect("new-storage", false, |values| {
|
||||||
let storage = values[1].get::<gst::Element>().expect("Invalid argument");
|
let storage = values[1]
|
||||||
|
.get::<gst::Element>()
|
||||||
|
.expect("rtpbin \"new-storage\" signal values[1]")
|
||||||
|
.expect("rtpbin \"new-storage\" signal values[1]: no `Element`");
|
||||||
storage
|
storage
|
||||||
.set_property("size-time", &250_000_000u64.to_value())
|
.set_property("size-time", &250_000_000u64.to_value())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -160,7 +163,9 @@ fn example_main() -> Result<(), Error> {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
rtpbin.connect("request-pt-map", false, |values| {
|
rtpbin.connect("request-pt-map", false, |values| {
|
||||||
let pt = values[2].get::<u32>().expect("Invalid argument");
|
let pt = values[2]
|
||||||
|
.get_some::<u32>()
|
||||||
|
.expect("rtpbin \"new-storage\" signal values[2]");
|
||||||
match pt {
|
match pt {
|
||||||
100 => Some(
|
100 => Some(
|
||||||
gst::Caps::new_simple(
|
gst::Caps::new_simple(
|
||||||
|
@ -189,8 +194,13 @@ fn example_main() -> Result<(), Error> {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
rtpbin.connect("request-fec-decoder", false, |values| {
|
rtpbin.connect("request-fec-decoder", false, |values| {
|
||||||
let rtpbin = values[0].get::<gst::Element>().expect("Invalid argument");
|
let rtpbin = values[0]
|
||||||
let sess_id = values[1].get::<u32>().expect("Invalid argument");
|
.get::<gst::Element>()
|
||||||
|
.expect("rtpbin \"request-fec-decoder\" signal values[0]")
|
||||||
|
.expect("rtpbin \"request-fec-decoder\" signal values[0]: no `Element`");
|
||||||
|
let sess_id = values[1]
|
||||||
|
.get_some::<u32>()
|
||||||
|
.expect("rtpbin \"request-fec-decoder\" signal values[1]");
|
||||||
|
|
||||||
match make_fec_decoder(&rtpbin, sess_id) {
|
match make_fec_decoder(&rtpbin, sess_id) {
|
||||||
Ok(elem) => Some(elem.to_value()),
|
Ok(elem) => Some(elem.to_value()),
|
||||||
|
|
|
@ -119,7 +119,10 @@ fn example_main() -> Result<(), Error> {
|
||||||
pay.link(&q2)?;
|
pay.link(&q2)?;
|
||||||
|
|
||||||
rtpbin.connect("request-fec-encoder", false, move |values| {
|
rtpbin.connect("request-fec-encoder", false, move |values| {
|
||||||
let rtpbin = values[0].get::<gst::Element>().expect("Invalid argument");
|
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`");
|
||||||
|
|
||||||
match make_fec_encoder(fec_percentage) {
|
match make_fec_encoder(fec_percentage) {
|
||||||
Ok(elem) => Some(elem.to_value()),
|
Ok(elem) => Some(elem.to_value()),
|
||||||
|
|
|
@ -110,7 +110,8 @@ fn example_main() -> Result<(), Error> {
|
||||||
// much more corner-cases. This is just for the sake of being an example.
|
// much more corner-cases. This is just for the sake of being an example.
|
||||||
let caps = values[2]
|
let caps = values[2]
|
||||||
.get::<gst::Caps>()
|
.get::<gst::Caps>()
|
||||||
.expect("Failed to automatically detect type");
|
.expect("typefinder \"have-type\" signal values[2]")
|
||||||
|
.expect("typefinder \"have-type\" signal values[2]: no `caps`");
|
||||||
let format_name = caps
|
let format_name = caps
|
||||||
.get_structure(0)
|
.get_structure(0)
|
||||||
.expect("Failed to get format name")
|
.expect("Failed to get format name")
|
||||||
|
|
|
@ -57,7 +57,10 @@ impl<O: IsA<Aggregator>> AggregatorExtManual for O {
|
||||||
b"min-upstream-latency\0".as_ptr() as *const _,
|
b"min-upstream-latency\0".as_ptr() as *const _,
|
||||||
value.to_glib_none_mut().0,
|
value.to_glib_none_mut().0,
|
||||||
);
|
);
|
||||||
value.get().unwrap()
|
value
|
||||||
|
.get()
|
||||||
|
.expect("AggregatorExtManual::get_property_min_upstream_latency")
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,10 @@ impl Discoverer {
|
||||||
value.to_glib_none_mut().0,
|
value.to_glib_none_mut().0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
value.get().unwrap()
|
value
|
||||||
|
.get()
|
||||||
|
.expect("Discoverer::get_property_timeout")
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect_property_timeout_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
pub fn connect_property_timeout_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||||
|
|
|
@ -66,7 +66,7 @@ where
|
||||||
let res =
|
let res =
|
||||||
gst_sys::gst_iterator_next(self.to_glib_none_mut().0, value.to_glib_none_mut().0);
|
gst_sys::gst_iterator_next(self.to_glib_none_mut().0, value.to_glib_none_mut().0);
|
||||||
match res {
|
match res {
|
||||||
gst_sys::GST_ITERATOR_OK => match value.get::<T>() {
|
gst_sys::GST_ITERATOR_OK => match value.get::<T>().expect("Iterator::next") {
|
||||||
Some(value) => Ok(Some(value)),
|
Some(value) => Ok(Some(value)),
|
||||||
None => Err(IteratorError::Error),
|
None => Err(IteratorError::Error),
|
||||||
},
|
},
|
||||||
|
@ -123,7 +123,7 @@ where
|
||||||
func_ptr,
|
func_ptr,
|
||||||
));
|
));
|
||||||
if res {
|
if res {
|
||||||
Some(elem.get::<T>().unwrap())
|
elem.get::<T>().expect("Iterator::find")
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,10 @@ where
|
||||||
let func: &&(dyn Fn(T) -> bool + Send + Sync + 'static) = mem::transmute(func);
|
let func: &&(dyn Fn(T) -> bool + Send + Sync + 'static) = mem::transmute(func);
|
||||||
|
|
||||||
let value = &*(value as *const glib::Value);
|
let value = &*(value as *const glib::Value);
|
||||||
let value = value.get::<T>().unwrap();
|
let value = value
|
||||||
|
.get::<T>()
|
||||||
|
.expect("Iterator filter_trampoline")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if func(value) {
|
if func(value) {
|
||||||
0
|
0
|
||||||
|
@ -408,7 +411,7 @@ where
|
||||||
|
|
||||||
let func = func as *mut F;
|
let func = func as *mut F;
|
||||||
let value = &*(value as *const glib::Value);
|
let value = &*(value as *const glib::Value);
|
||||||
let value = value.get::<T>().unwrap();
|
let value = value.get::<T>().expect("Iterator find_trampoline").unwrap();
|
||||||
|
|
||||||
if (*func)(value) {
|
if (*func)(value) {
|
||||||
0
|
0
|
||||||
|
@ -425,7 +428,10 @@ unsafe extern "C" fn foreach_trampoline<T, F: FnMut(T)>(
|
||||||
{
|
{
|
||||||
let func = func as *mut F;
|
let func = func as *mut F;
|
||||||
let value = &*(value as *const glib::Value);
|
let value = &*(value as *const glib::Value);
|
||||||
let value = value.get::<T>().unwrap();
|
let value = value
|
||||||
|
.get::<T>()
|
||||||
|
.expect("Iterator foreach_trampoline")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
(*func)(value);
|
(*func)(value);
|
||||||
}
|
}
|
||||||
|
@ -440,7 +446,7 @@ where
|
||||||
{
|
{
|
||||||
let func = func as *mut F;
|
let func = func as *mut F;
|
||||||
let value = &*(value as *const glib::Value);
|
let value = &*(value as *const glib::Value);
|
||||||
let value = value.get::<T>().unwrap();
|
let value = value.get::<T>().expect("Iterator fold_trampoline").unwrap();
|
||||||
|
|
||||||
let accum = &mut *(gobject_sys::g_value_get_pointer(ret) as *mut Option<U>);
|
let accum = &mut *(gobject_sys::g_value_get_pointer(ret) as *mut Option<U>);
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,22 @@ impl<O: IsA<::Object>> GstObjectExtManual for O {
|
||||||
unsafe { from_glib_borrow(self.as_ptr() as *mut gobject_sys::GObject) };
|
unsafe { from_glib_borrow(self.as_ptr() as *mut gobject_sys::GObject) };
|
||||||
|
|
||||||
obj.connect(signal_name.as_str(), false, move |values| {
|
obj.connect(signal_name.as_str(), false, move |values| {
|
||||||
let obj: O = unsafe { values[0].get::<::Object>().unwrap().unsafe_cast() };
|
// It would be nice to display the actual signal name in the panic messages below,
|
||||||
let prop_obj: ::Object = values[1].get().unwrap();
|
// but that would require to copy `signal_name` so as to move it into the closure
|
||||||
|
// which seems too much for the messages of development errors
|
||||||
|
let obj: O = unsafe {
|
||||||
|
values[0]
|
||||||
|
.get::<::Object>()
|
||||||
|
.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: ::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");
|
||||||
|
|
||||||
let pspec = unsafe {
|
let pspec = unsafe {
|
||||||
let pspec = gobject_sys::g_value_get_param(values[2].to_glib_none().0);
|
let pspec = gobject_sys::g_value_get_param(values[2].to_glib_none().0);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::borrow::{Borrow, BorrowMut, ToOwned};
|
use std::borrow::{Borrow, BorrowMut, ToOwned};
|
||||||
|
use std::error;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -22,11 +23,62 @@ use glib::translate::{
|
||||||
from_glib, from_glib_full, from_glib_none, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault,
|
from_glib, from_glib_full, from_glib_none, FromGlibPtrFull, FromGlibPtrNone, GlibPtrDefault,
|
||||||
Stash, StashMut, ToGlib, ToGlibPtr, ToGlibPtrMut,
|
Stash, StashMut, ToGlib, ToGlibPtr, ToGlibPtrMut,
|
||||||
};
|
};
|
||||||
use glib::value::{FromValueOptional, SendValue, ToSendValue};
|
use glib::value::{FromValue, FromValueOptional, SendValue, ToSendValue};
|
||||||
use glib_sys::gpointer;
|
use glib_sys::gpointer;
|
||||||
use gobject_sys;
|
use gobject_sys;
|
||||||
use gst_sys;
|
use gst_sys;
|
||||||
|
|
||||||
|
/// An error returned from the [`get`](struct.StructureRef.html#method.get)
|
||||||
|
/// or [`get_some`](struct.StructureRef.html#method.get_some) functions
|
||||||
|
/// on a [`StructureRef`](struct.StructureRef.html)
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum GetError<'name> {
|
||||||
|
FieldNotFound {
|
||||||
|
name: &'name str,
|
||||||
|
},
|
||||||
|
ValueGetError {
|
||||||
|
name: &'name str,
|
||||||
|
value_get_error: glib::value::GetError,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'name> GetError<'name> {
|
||||||
|
fn new_field_not_found(name: &'name str) -> GetError {
|
||||||
|
GetError::FieldNotFound { name }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_value_get_error(name: &'name str, value_get_error: glib::value::GetError) -> GetError {
|
||||||
|
GetError::ValueGetError {
|
||||||
|
name,
|
||||||
|
value_get_error,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'name> fmt::Display for GetError<'name> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
GetError::FieldNotFound { name } => {
|
||||||
|
write!(f, "GetError: Structure field with name {} not found", name)
|
||||||
|
}
|
||||||
|
GetError::ValueGetError {
|
||||||
|
name,
|
||||||
|
value_get_error,
|
||||||
|
} => write!(
|
||||||
|
f,
|
||||||
|
"GetError: Structure field with name {} value: {}",
|
||||||
|
name, value_get_error,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'name> error::Error for GetError<'name> {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
"GetError: Structure field value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Structure(ptr::NonNull<StructureRef>, PhantomData<StructureRef>);
|
pub struct Structure(ptr::NonNull<StructureRef>, PhantomData<StructureRef>);
|
||||||
unsafe impl Send for Structure {}
|
unsafe impl Send for Structure {}
|
||||||
unsafe impl Sync for Structure {}
|
unsafe impl Sync for Structure {}
|
||||||
|
@ -326,19 +378,36 @@ impl StructureRef {
|
||||||
unsafe { from_glib_full(gst_sys::gst_structure_to_string(&self.0)) }
|
unsafe { from_glib_full(gst_sys::gst_structure_to_string(&self.0)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<'a, T: FromValueOptional<'a>>(&'a self, name: &str) -> Option<T> {
|
pub fn get<'structure, 'name, T: FromValueOptional<'structure>>(
|
||||||
self.get_value(name).and_then(|v| v.get())
|
&'structure self,
|
||||||
|
name: &'name str,
|
||||||
|
) -> Result<Option<T>, GetError<'name>> {
|
||||||
|
self.get_value(name)?
|
||||||
|
.get()
|
||||||
|
.map_err(|err| GetError::from_value_get_error(name, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_value<'a>(&'a self, name: &str) -> Option<&SendValue> {
|
pub fn get_some<'structure, 'name, T: FromValue<'structure>>(
|
||||||
|
&'structure self,
|
||||||
|
name: &'name str,
|
||||||
|
) -> Result<T, GetError<'name>> {
|
||||||
|
self.get_value(name)?
|
||||||
|
.get_some()
|
||||||
|
.map_err(|err| GetError::from_value_get_error(name, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_value<'structure, 'name>(
|
||||||
|
&'structure self,
|
||||||
|
name: &'name str,
|
||||||
|
) -> Result<&SendValue, GetError<'name>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let value = gst_sys::gst_structure_get_value(&self.0, name.to_glib_none().0);
|
let value = gst_sys::gst_structure_get_value(&self.0, name.to_glib_none().0);
|
||||||
|
|
||||||
if value.is_null() {
|
if value.is_null() {
|
||||||
return None;
|
return Err(GetError::new_field_not_found(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(&*(value as *const SendValue))
|
Ok(&*(value as *const SendValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,20 +748,52 @@ mod tests {
|
||||||
s.set("f2", &String::from("bcd"));
|
s.set("f2", &String::from("bcd"));
|
||||||
s.set("f3", &123i32);
|
s.set("f3", &123i32);
|
||||||
|
|
||||||
assert_eq!(s.get::<&str>("f1").unwrap(), "abc");
|
assert_eq!(s.get::<&str>("f1"), Ok(Some("abc")));
|
||||||
assert_eq!(s.get::<&str>("f2").unwrap(), "bcd");
|
assert_eq!(s.get::<&str>("f2"), Ok(Some("bcd")));
|
||||||
assert_eq!(s.get::<i32>("f3").unwrap(), 123i32);
|
assert_eq!(s.get_some::<i32>("f3"), Ok(123i32));
|
||||||
|
|
||||||
|
// FIXME: use a proper `assert_eq!`, but that requires
|
||||||
|
// `glib::value::GetError fields to be public
|
||||||
|
// See https://github.com/gtk-rs/glib/issues/515
|
||||||
|
match s.get::<i32>("f2") {
|
||||||
|
Err(GetError::ValueGetError { name, .. }) if name == "f2" => (),
|
||||||
|
res => panic!(
|
||||||
|
"Expected GetError::ValueGetError{{ \"f2\", .. }} found {:?}",
|
||||||
|
res
|
||||||
|
),
|
||||||
|
}
|
||||||
|
match s.get_some::<bool>("f3") {
|
||||||
|
Err(GetError::ValueGetError { name, .. }) if name == "f3" => (),
|
||||||
|
res => panic!(
|
||||||
|
"Expected GetError::ValueGetError{{ \"f3\", .. }} found {:?}",
|
||||||
|
res
|
||||||
|
),
|
||||||
|
}
|
||||||
|
match s.get::<&str>("f4") {
|
||||||
|
Err(GetError::FieldNotFound { name }) if name == "f4" => (),
|
||||||
|
res => panic!(
|
||||||
|
"Expected GetError::FieldNotFound{{ \"f4\" }} found {:?}",
|
||||||
|
res
|
||||||
|
),
|
||||||
|
}
|
||||||
|
match s.get_some::<i32>("f4") {
|
||||||
|
Err(GetError::FieldNotFound { name }) if name == "f4" => (),
|
||||||
|
res => panic!(
|
||||||
|
"Expected GetError::FieldNotFound{{ \"f4\" }} found {:?}",
|
||||||
|
res
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(s.fields().collect::<Vec<_>>(), vec!["f1", "f2", "f3"]);
|
assert_eq!(s.fields().collect::<Vec<_>>(), vec!["f1", "f2", "f3"]);
|
||||||
|
|
||||||
let v = s.iter().map(|(f, v)| (f, v.clone())).collect::<Vec<_>>();
|
let v = s.iter().map(|(f, v)| (f, v.clone())).collect::<Vec<_>>();
|
||||||
assert_eq!(v.len(), 3);
|
assert_eq!(v.len(), 3);
|
||||||
assert_eq!(v[0].0, "f1");
|
assert_eq!(v[0].0, "f1");
|
||||||
assert_eq!(v[0].1.get::<&str>().unwrap(), "abc");
|
assert_eq!(v[0].1.get::<&str>(), Ok(Some("abc")));
|
||||||
assert_eq!(v[1].0, "f2");
|
assert_eq!(v[1].0, "f2");
|
||||||
assert_eq!(v[1].1.get::<&str>().unwrap(), "bcd");
|
assert_eq!(v[1].1.get::<&str>(), Ok(Some("bcd")));
|
||||||
assert_eq!(v[2].0, "f3");
|
assert_eq!(v[2].0, "f3");
|
||||||
assert_eq!(v[2].1.get::<i32>().unwrap(), 123i32);
|
assert_eq!(v[2].1.get_some::<i32>(), Ok(123i32));
|
||||||
|
|
||||||
let s2 = Structure::new("test", &[("f1", &"abc"), ("f2", &"bcd"), ("f3", &123i32)]);
|
let s2 = Structure::new("test", &[("f1", &"abc"), ("f2", &"bcd"), ("f3", &123i32)]);
|
||||||
assert_eq!(s, s2);
|
assert_eq!(s, s2);
|
||||||
|
@ -709,9 +810,9 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assert_eq!(s.get_name(), "test");
|
assert_eq!(s.get_name(), "test");
|
||||||
assert_eq!(s.get::<&str>("f1").unwrap(), "abc");
|
assert_eq!(s.get::<&str>("f1"), Ok(Some("abc")));
|
||||||
assert_eq!(s.get::<&str>("f2").unwrap(), "bcd");
|
assert_eq!(s.get::<&str>("f2"), Ok(Some("bcd")));
|
||||||
assert_eq!(s.get::<i32>("f3").unwrap(), 123i32);
|
assert_eq!(s.get_some::<i32>("f3"), Ok(123i32));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -721,8 +822,8 @@ mod tests {
|
||||||
let a = "Test, f1=(string)abc, f2=(uint)123;";
|
let a = "Test, f1=(string)abc, f2=(uint)123;";
|
||||||
|
|
||||||
let s = Structure::from_string(&a).unwrap();
|
let s = Structure::from_string(&a).unwrap();
|
||||||
assert_eq!(s.get::<&str>("f1").unwrap(), "abc");
|
assert_eq!(s.get::<&str>("f1"), Ok(Some("abc")));
|
||||||
assert_eq!(s.get::<u32>("f2").unwrap(), 123);
|
assert_eq!(s.get_some::<u32>("f2"), Ok(123));
|
||||||
|
|
||||||
assert_eq!(a, s.to_string());
|
assert_eq!(a, s.to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,8 +406,11 @@ impl TagListRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<'a, T: Tag<'a>>(&self) -> Option<TypedValue<T::TagType>> {
|
pub fn get<'a, T: Tag<'a>>(&self) -> Option<TypedValue<T::TagType>> {
|
||||||
self.get_generic(T::tag_name())
|
self.get_generic(T::tag_name()).map(|value| {
|
||||||
.and_then(|value| value.downcast().ok())
|
value.downcast().unwrap_or_else(|_| {
|
||||||
|
panic!("TagListRef::get type mismatch for tag {}", T::tag_name())
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_generic(&self, tag_name: &str) -> Option<SendValue> {
|
pub fn get_generic(&self, tag_name: &str) -> Option<SendValue> {
|
||||||
|
@ -966,24 +969,24 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tags.get_index_generic(&TAG_TITLE, 0).unwrap().get(),
|
tags.get_index_generic(&TAG_TITLE, 0).unwrap().get(),
|
||||||
Some("some title")
|
Ok(Some("some title"))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tags.get_index_generic(&TAG_TITLE, 1).unwrap().get(),
|
tags.get_index_generic(&TAG_TITLE, 1).unwrap().get(),
|
||||||
Some("second title")
|
Ok(Some("second title"))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tags.get_index_generic(&TAG_DURATION, 0).unwrap().get(),
|
tags.get_index_generic(&TAG_DURATION, 0).unwrap().get(),
|
||||||
Some(::SECOND * 120)
|
Ok(Some(::SECOND * 120))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tags.get_index_generic(&TAG_TITLE, 2).unwrap().get(),
|
tags.get_index_generic(&TAG_TITLE, 2).unwrap().get(),
|
||||||
Some("third title")
|
Ok(Some("third title"))
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tags.get_generic(&TAG_TITLE).unwrap().get(),
|
tags.get_generic(&TAG_TITLE).unwrap().get(),
|
||||||
Some("some title, second title, third title"),
|
Ok(Some("some title, second title, third title"))
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(tags.n_tags(), 2);
|
assert_eq!(tags.n_tags(), 2);
|
||||||
|
@ -996,11 +999,11 @@ mod tests {
|
||||||
let mut title_iter = tags.iter_tag_generic(&TAG_TITLE);
|
let mut title_iter = tags.iter_tag_generic(&TAG_TITLE);
|
||||||
assert_eq!(title_iter.size_hint(), (3, Some(3)));
|
assert_eq!(title_iter.size_hint(), (3, Some(3)));
|
||||||
let first_title = title_iter.next().unwrap();
|
let first_title = title_iter.next().unwrap();
|
||||||
assert_eq!(first_title.get(), Some("some title"));
|
assert_eq!(first_title.get(), Ok(Some("some title")));
|
||||||
let second_title = title_iter.next().unwrap();
|
let second_title = title_iter.next().unwrap();
|
||||||
assert_eq!(second_title.get(), Some("second title"));
|
assert_eq!(second_title.get(), Ok(Some("second title")));
|
||||||
let third_title = title_iter.next().unwrap();
|
let third_title = title_iter.next().unwrap();
|
||||||
assert_eq!(third_title.get(), Some("third title"));
|
assert_eq!(third_title.get(), Ok(Some("third title")));
|
||||||
assert!(title_iter.next().is_none());
|
assert!(title_iter.next().is_none());
|
||||||
|
|
||||||
// GenericIter
|
// GenericIter
|
||||||
|
@ -1010,17 +1013,17 @@ mod tests {
|
||||||
let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap();
|
let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap();
|
||||||
assert_eq!(tag_name, *TAG_TITLE);
|
assert_eq!(tag_name, *TAG_TITLE);
|
||||||
let first_title = tag_iter.next().unwrap();
|
let first_title = tag_iter.next().unwrap();
|
||||||
assert_eq!(first_title.get(), Some("some title"));
|
assert_eq!(first_title.get(), Ok(Some("some title")));
|
||||||
let second_title = tag_iter.next().unwrap();
|
let second_title = tag_iter.next().unwrap();
|
||||||
assert_eq!(second_title.get(), Some("second title"));
|
assert_eq!(second_title.get(), Ok(Some("second title")));
|
||||||
let third_title = tag_iter.next().unwrap();
|
let third_title = tag_iter.next().unwrap();
|
||||||
assert_eq!(third_title.get(), Some("third title"));
|
assert_eq!(third_title.get(), Ok(Some("third title")));
|
||||||
assert!(tag_iter.next().is_none());
|
assert!(tag_iter.next().is_none());
|
||||||
|
|
||||||
let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap();
|
let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap();
|
||||||
assert_eq!(tag_name, *TAG_DURATION);
|
assert_eq!(tag_name, *TAG_DURATION);
|
||||||
let first_duration = tag_iter.next().unwrap();
|
let first_duration = tag_iter.next().unwrap();
|
||||||
assert_eq!(first_duration.get(), Some(::SECOND * 120));
|
assert_eq!(first_duration.get_some(), Ok(::SECOND * 120));
|
||||||
assert!(tag_iter.next().is_none());
|
assert!(tag_iter.next().is_none());
|
||||||
|
|
||||||
// Iter
|
// Iter
|
||||||
|
@ -1031,12 +1034,12 @@ mod tests {
|
||||||
assert_eq!(tag_name, *TAG_TITLE);
|
assert_eq!(tag_name, *TAG_TITLE);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tag_value.get(),
|
tag_value.get(),
|
||||||
Some("some title, second title, third title")
|
Ok(Some("some title, second title, third title"))
|
||||||
);
|
);
|
||||||
|
|
||||||
let (tag_name, tag_value) = tag_list_iter.next().unwrap();
|
let (tag_name, tag_value) = tag_list_iter.next().unwrap();
|
||||||
assert_eq!(tag_name, *TAG_DURATION);
|
assert_eq!(tag_name, *TAG_DURATION);
|
||||||
assert_eq!(tag_value.get(), Some(::SECOND * 120));
|
assert_eq!(tag_value.get_some(), Ok(::SECOND * 120));
|
||||||
assert!(tag_iter.next().is_none());
|
assert!(tag_iter.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,9 @@ impl<'de> Deserialize<'de> for Fraction {
|
||||||
macro_rules! ser_value (
|
macro_rules! ser_value (
|
||||||
($value:expr, $t:ty, $ser_closure:expr) => (
|
($value:expr, $t:ty, $ser_closure:expr) => (
|
||||||
{
|
{
|
||||||
let value = $value.get::<$t>().unwrap();
|
// FIXME: This should serialize to an `Option` when the `Type` allows it
|
||||||
|
// See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/issues/215
|
||||||
|
let value = $value.get::<$t>().expect("Value serialization macro").unwrap();
|
||||||
$ser_closure(stringify!($t), value)
|
$ser_closure(stringify!($t), value)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -493,30 +495,36 @@ mod tests {
|
||||||
let slice = array.as_slice();
|
let slice = array.as_slice();
|
||||||
assert_eq!(3, slice.len());
|
assert_eq!(3, slice.len());
|
||||||
|
|
||||||
let fraction = slice[0].get::<Fraction>().unwrap();
|
let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap();
|
||||||
assert_eq!(fraction.0.numer(), &1);
|
assert_eq!(fraction.0.numer(), &1);
|
||||||
assert_eq!(fraction.0.denom(), &3);
|
assert_eq!(fraction.0.denom(), &3);
|
||||||
|
|
||||||
let fraction = slice[1].get::<Fraction>().unwrap();
|
let fraction = slice[1].get::<Fraction>().expect("slice[1]").unwrap();
|
||||||
assert_eq!(fraction.0.numer(), &1);
|
assert_eq!(fraction.0.numer(), &1);
|
||||||
assert_eq!(fraction.0.denom(), &2);
|
assert_eq!(fraction.0.denom(), &2);
|
||||||
|
|
||||||
assert_eq!("test str".to_owned(), slice[2].get::<String>().unwrap());
|
assert_eq!(
|
||||||
|
"test str".to_owned(),
|
||||||
|
slice[2].get::<String>().expect("slice[2]").unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
let array_json = r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"]]"#;
|
let array_json = r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"]]"#;
|
||||||
let array: Array = serde_json::from_str(array_json).unwrap();
|
let array: Array = serde_json::from_str(array_json).unwrap();
|
||||||
let slice = array.as_slice();
|
let slice = array.as_slice();
|
||||||
assert_eq!(3, slice.len());
|
assert_eq!(3, slice.len());
|
||||||
|
|
||||||
let fraction = slice[0].get::<Fraction>().unwrap();
|
let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap();
|
||||||
assert_eq!(fraction.0.numer(), &1);
|
assert_eq!(fraction.0.numer(), &1);
|
||||||
assert_eq!(fraction.0.denom(), &3);
|
assert_eq!(fraction.0.denom(), &3);
|
||||||
|
|
||||||
let fraction = slice[1].get::<Fraction>().unwrap();
|
let fraction = slice[1].get::<Fraction>().expect("slice[1]").unwrap();
|
||||||
assert_eq!(fraction.0.numer(), &1);
|
assert_eq!(fraction.0.numer(), &1);
|
||||||
assert_eq!(fraction.0.denom(), &2);
|
assert_eq!(fraction.0.denom(), &2);
|
||||||
|
|
||||||
assert_eq!("test str".to_owned(), slice[2].get::<String>().unwrap());
|
assert_eq!(
|
||||||
|
"test str".to_owned(),
|
||||||
|
slice[2].get::<String>().expect("slice[2]").unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
// List
|
// List
|
||||||
let list_ron = r#"[
|
let list_ron = r#"[
|
||||||
|
@ -527,11 +535,14 @@ mod tests {
|
||||||
let slice = list.as_slice();
|
let slice = list.as_slice();
|
||||||
assert_eq!(2, slice.len());
|
assert_eq!(2, slice.len());
|
||||||
|
|
||||||
let fraction = slice[0].get::<Fraction>().unwrap();
|
let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap();
|
||||||
assert_eq!(fraction.0.numer(), &1);
|
assert_eq!(fraction.0.numer(), &1);
|
||||||
assert_eq!(fraction.0.denom(), &2);
|
assert_eq!(fraction.0.denom(), &2);
|
||||||
|
|
||||||
assert_eq!("test str".to_owned(), slice[1].get::<String>().unwrap());
|
assert_eq!(
|
||||||
|
"test str".to_owned(),
|
||||||
|
slice[1].get::<String>().expect("slice[1]").unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ser_de")]
|
#[cfg(feature = "ser_de")]
|
||||||
|
@ -556,19 +567,19 @@ mod tests {
|
||||||
let slice = array.as_slice();
|
let slice = array.as_slice();
|
||||||
assert_eq!(slice_de.len(), slice.len());
|
assert_eq!(slice_de.len(), slice.len());
|
||||||
|
|
||||||
let fraction_de = slice_de[0].get::<Fraction>().unwrap();
|
let fraction_de = slice_de[0].get::<Fraction>().expect("slice_de[0]").unwrap();
|
||||||
let fraction = slice[0].get::<Fraction>().unwrap();
|
let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap();
|
||||||
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
||||||
assert_eq!(fraction_de.0.denom(), fraction.0.denom());
|
assert_eq!(fraction_de.0.denom(), fraction.0.denom());
|
||||||
|
|
||||||
let fraction_de = slice_de[1].get::<Fraction>().unwrap();
|
let fraction_de = slice_de[1].get::<Fraction>().expect("slice_de[1]").unwrap();
|
||||||
let fraction = slice[1].get::<Fraction>().unwrap();
|
let fraction = slice[1].get::<Fraction>().expect("slice[1]").unwrap();
|
||||||
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
||||||
assert_eq!(fraction.0.denom(), fraction.0.denom());
|
assert_eq!(fraction.0.denom(), fraction.0.denom());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
slice_de[2].get::<String>().unwrap(),
|
slice_de[2].get::<String>().expect("slice_de[2]").unwrap(),
|
||||||
slice[2].get::<String>().unwrap()
|
slice[2].get::<String>().expect("slice[2]").unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
// List
|
// List
|
||||||
|
@ -584,14 +595,14 @@ mod tests {
|
||||||
let slice = list.as_slice();
|
let slice = list.as_slice();
|
||||||
assert_eq!(slice_de.len(), slice.len());
|
assert_eq!(slice_de.len(), slice.len());
|
||||||
|
|
||||||
let fraction_de = slice_de[0].get::<Fraction>().unwrap();
|
let fraction_de = slice_de[0].get::<Fraction>().expect("slice_de[0]").unwrap();
|
||||||
let fraction = slice[0].get::<Fraction>().unwrap();
|
let fraction = slice[0].get::<Fraction>().expect("slice[0]").unwrap();
|
||||||
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
assert_eq!(fraction_de.0.numer(), fraction.0.numer());
|
||||||
assert_eq!(fraction_de.0.denom(), fraction.0.denom());
|
assert_eq!(fraction_de.0.denom(), fraction.0.denom());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
slice_de[1].get::<String>().unwrap(),
|
slice_de[1].get::<String>().expect("slice_de[1]").unwrap(),
|
||||||
slice[1].get::<String>().unwrap()
|
slice[1].get::<String>().expect("slice[1]").unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,11 +50,11 @@ mod tutorial5 {
|
||||||
let signame: &str = &format!("get-{}-tags", stype);
|
let signame: &str = &format!("get-{}-tags", stype);
|
||||||
|
|
||||||
match playbin.get_property(propname).unwrap().get() {
|
match playbin.get_property(propname).unwrap().get() {
|
||||||
Some(x) => {
|
Ok(Some(x)) => {
|
||||||
for i in 0..x {
|
for i in 0..x {
|
||||||
let tags = playbin.emit(signame, &[&i]).unwrap().unwrap();
|
let tags = playbin.emit(signame, &[&i]).unwrap().unwrap();
|
||||||
|
|
||||||
if let Some(tags) = tags.get::<gst::TagList>() {
|
if let Ok(Some(tags)) = tags.get::<gst::TagList>() {
|
||||||
textbuf.insert_at_cursor(&format!("{} stream {}:\n ", stype, i));
|
textbuf.insert_at_cursor(&format!("{} stream {}:\n ", stype, i));
|
||||||
|
|
||||||
if let Some(codec) = tags.get::<gst::tags::VideoCodec>() {
|
if let Some(codec) = tags.get::<gst::tags::VideoCodec>() {
|
||||||
|
@ -87,7 +87,7 @@ mod tutorial5 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
_ => {
|
||||||
eprintln!("Could not get {}!", propname);
|
eprintln!("Could not get {}!", propname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,10 @@ mod tutorial5 {
|
||||||
|
|
||||||
playbin
|
playbin
|
||||||
.connect("video-tags-changed", false, |args| {
|
.connect("video-tags-changed", false, |args| {
|
||||||
let pipeline = args[0].get::<gst::Element>().unwrap();
|
let pipeline = args[0]
|
||||||
|
.get::<gst::Element>()
|
||||||
|
.expect("playbin \"video-tags-changed\" args[0]")
|
||||||
|
.unwrap();
|
||||||
post_app_message(&pipeline);
|
post_app_message(&pipeline);
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
|
@ -353,7 +356,10 @@ mod tutorial5 {
|
||||||
|
|
||||||
playbin
|
playbin
|
||||||
.connect("audio-tags-changed", false, |args| {
|
.connect("audio-tags-changed", false, |args| {
|
||||||
let pipeline = args[0].get::<gst::Element>().unwrap();
|
let pipeline = args[0]
|
||||||
|
.get::<gst::Element>()
|
||||||
|
.expect("playbin \"audio-tags-changed\" args[0]")
|
||||||
|
.unwrap();
|
||||||
post_app_message(&pipeline);
|
post_app_message(&pipeline);
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
|
@ -361,7 +367,10 @@ mod tutorial5 {
|
||||||
|
|
||||||
playbin
|
playbin
|
||||||
.connect("text-tags-changed", false, move |args| {
|
.connect("text-tags-changed", false, move |args| {
|
||||||
let pipeline = args[0].get::<gst::Element>().unwrap();
|
let pipeline = args[0]
|
||||||
|
.get::<gst::Element>()
|
||||||
|
.expect("playbin \"text-tags-changed\" args[0]")
|
||||||
|
.unwrap();
|
||||||
post_app_message(&pipeline);
|
post_app_message(&pipeline);
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::env;
|
||||||
mod tutorials_common;
|
mod tutorials_common;
|
||||||
|
|
||||||
fn send_value_as_str(v: &glib::SendValue) -> Option<String> {
|
fn send_value_as_str(v: &glib::SendValue) -> Option<String> {
|
||||||
if let Some(s) = v.get::<&str>() {
|
if let Ok(Some(s)) = v.get::<&str>() {
|
||||||
Some(s.to_string())
|
Some(s.to_string())
|
||||||
} else if let Some(serialized) = v.serialize() {
|
} else if let Some(serialized) = v.serialize() {
|
||||||
Some(serialized)
|
Some(serialized)
|
||||||
|
|
Loading…
Reference in a new issue