Use new GLib boxed-type definition feature for carrying Rust types over GStreamer error messages

This commit is contained in:
Sebastian Dröge 2018-11-28 08:57:17 +02:00
parent 2255637e02
commit ab626adc4a
3 changed files with 37 additions and 14 deletions

View file

@ -4,7 +4,7 @@ version = "0.12.0"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
[dependencies]
glib = { git = "https://github.com/gtk-rs/glib" }
glib = { git = "https://github.com/gtk-rs/glib", features = ["subclassing"] }
gstreamer = { path = "../gstreamer" }
gstreamer-app = { path = "../gstreamer-app" }
gstreamer-audio = { path = "../gstreamer-audio" }

View file

@ -2,6 +2,7 @@
extern crate gstreamer as gst;
use gst::prelude::*;
#[macro_use]
extern crate glib;
use std::env;
@ -35,6 +36,20 @@ struct ErrorMessage {
cause: glib::Error,
}
#[cfg(feature = "v1_10")]
#[derive(Clone, Debug)]
struct ErrorValue(Arc<Mutex<Option<Error>>>);
#[cfg(feature = "v1_10")]
impl glib::subclass::boxed::BoxedType for ErrorValue {
const NAME: &'static str = "ErrorValue";
glib_boxed_get_type!();
}
#[cfg(feature = "v1_10")]
glib_boxed_derive_traits!(ErrorValue);
fn example_main() -> Result<(), Error> {
gst::init()?;
@ -139,7 +154,7 @@ fn example_main() -> Result<(), Error> {
("Failed to insert sink"),
details: gst::Structure::builder("error-details")
.field("error",
&glib::AnySendValue::new(Arc::new(Mutex::new(Some(err)))))
&ErrorValue(Arc::new(Mutex::new(Some(err)))))
.build()
);
@ -171,12 +186,8 @@ fn example_main() -> Result<(), Error> {
{
match err.get_details() {
Some(details) if details.get_name() == "error-details" => details
.get::<&glib::AnySendValue>("error")
.cloned()
.and_then(|v| {
v.downcast_ref::<Arc<Mutex<Option<Error>>>>()
.and_then(|v| v.lock().unwrap().take())
})
.get::<&ErrorValue>("error")
.and_then(|v| v.0.lock().unwrap().take())
.map(Result::Err)
.expect("error-details message without actual error"),
_ => Err(ErrorMessage {

View file

@ -5,6 +5,7 @@ use gst::prelude::*;
extern crate gstreamer_pbutils as gst_pbutils;
use gst_pbutils::prelude::*;
#[macro_use]
extern crate glib;
use std::env;
@ -38,6 +39,20 @@ struct ErrorMessage {
cause: glib::Error,
}
#[cfg(feature = "v1_10")]
#[derive(Clone, Debug)]
struct ErrorValue(Arc<Mutex<Option<Error>>>);
#[cfg(feature = "v1_10")]
impl glib::subclass::boxed::BoxedType for ErrorValue {
const NAME: &'static str = "ErrorValue";
glib_boxed_get_type!();
}
#[cfg(feature = "v1_10")]
glib_boxed_derive_traits!(ErrorValue);
fn configure_encodebin(encodebin: &gst::Element) -> Result<(), Error> {
let audio_profile = gst_pbutils::EncodingAudioProfileBuilder::new()
.format(&gst::Caps::new_simple("audio/x-vorbis", &[]))
@ -197,7 +212,7 @@ fn example_main() -> Result<(), Error> {
("Failed to insert sink"),
details: gst::Structure::builder("error-details")
.field("error",
&glib::AnySendValue::new(Arc::new(Mutex::new(Some(err)))))
&ErrorValue(Arc::new(Mutex::new(Some(err)))))
.build()
);
@ -229,12 +244,9 @@ fn example_main() -> Result<(), Error> {
{
match err.get_details() {
Some(details) if details.get_name() == "error-details" => details
.get::<&glib::AnySendValue>("error")
.get::<&ErrorValue>("error")
.cloned()
.and_then(|v| {
v.downcast_ref::<Arc<Mutex<Option<Error>>>>()
.and_then(|v| v.lock().unwrap().take())
})
.and_then(|v| v.0.lock().unwrap().take())
.map(Result::Err)
.expect("error-details message without actual error"),
_ => Err(ErrorMessage {