From 9066cf063445530dd16e1adeec46aa9cc9715c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 20 Dec 2017 19:52:57 +0200 Subject: [PATCH] Add ErrorMessage type This can be used to propagate an element error via a Result until the place where it can be actually posted on an element. --- gstreamer/src/element.rs | 28 ++++++++++ gstreamer/src/error.rs | 109 +++++++++++++++++++++++++++++++++++++++ gstreamer/src/lib.rs | 4 ++ 3 files changed, 141 insertions(+) create mode 100644 gstreamer/src/error.rs diff --git a/gstreamer/src/element.rs b/gstreamer/src/element.rs index fb6cfe6c4..893c07474 100644 --- a/gstreamer/src/element.rs +++ b/gstreamer/src/element.rs @@ -116,6 +116,8 @@ pub trait ElementExtManual { structure: ::Structure, ); + fn post_error_message(&self, msg: &::ErrorMessage); + fn iterate_pads(&self) -> ::Iterator; fn iterate_sink_pads(&self) -> ::Iterator; fn iterate_src_pads(&self) -> ::Iterator; @@ -295,6 +297,32 @@ impl> ElementExtManual for O { } } + fn post_error_message(&self, msg: &::ErrorMessage) { + let ::ErrorMessage { + error_domain, + error_code, + ref message, + ref debug, + filename, + function, + line, + } = *msg; + + unsafe { + ffi::gst_element_message_full( + self.to_glib_none().0, + ffi::GST_MESSAGE_ERROR, + error_domain, + error_code, + message.to_glib_full(), + debug.to_glib_full(), + filename.to_glib_none().0, + function.to_glib_none().0, + line as i32, + ); + } + } + fn iterate_pads(&self) -> ::Iterator { unsafe { from_glib_full(ffi::gst_element_iterate_pads(self.to_glib_none().0)) } } diff --git a/gstreamer/src/error.rs b/gstreamer/src/error.rs new file mode 100644 index 000000000..1841954a7 --- /dev/null +++ b/gstreamer/src/error.rs @@ -0,0 +1,109 @@ +// Copyright (C) 2016-2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::error::Error; +use std::fmt; + +use glib_ffi; + +#[macro_export] +macro_rules! gst_error_msg( +// Plain strings + ($err:expr, ($msg:expr), [$dbg:expr]) => { + $crate::ErrorMessage::new(&$err, Some($msg), + Some($dbg), + file!(), module_path!(), line!()) + }; + ($err:expr, ($msg:expr)) => { + $crate::ErrorMessage::new(&$err, Some($msg), + None, + file!(), module_path!(), line!()) + }; + ($err:expr, [$dbg:expr]) => { + $crate::ErrorMessage::new(&$err, None, + Some($dbg), + file!(), module_path!(), line!()) + }; + +// Format strings + ($err:expr, ($($msg:tt)*), [$($dbg:tt)*]) => { { + $crate::ErrorMessage::new(&$err, Some(format!($($msg)*).as_ref()), + Some(format!($($dbg)*).as_ref()), + file!(), module_path!(), line!()) + }}; + ($err:expr, ($($msg:tt)*)) => { { + $crate::ErrorMessage::new(&$err, Some(format!($($msg)*).as_ref()), + None, + file!(), module_path!(), line!()) + }}; + + ($err:expr, [$($dbg:tt)*]) => { { + $crate::ErrorMessage::new(&$err, None, + Some(format!($($dbg)*).as_ref()), + file!(), module_path!(), line!()) + }}; +); + +#[derive(Debug, PartialEq, Eq)] +pub struct ErrorMessage { + pub(crate) error_domain: glib_ffi::GQuark, + pub(crate) error_code: i32, + pub(crate) message: Option, + pub(crate) debug: Option, + pub(crate) filename: &'static str, + pub(crate) function: &'static str, + pub(crate) line: u32, +} + +impl ErrorMessage { + pub fn new< + 'a, + 'b, + T: ::MessageErrorDomain, + U: Into>, + V: Into>, + >( + error: &T, + message: U, + debug: V, + filename: &'static str, + function: &'static str, + line: u32, + ) -> ErrorMessage { + let domain = T::domain(); + let code = error.code(); + let message = message.into(); + let debug = debug.into(); + + ErrorMessage { + error_domain: domain, + error_code: code, + message: message.map(String::from), + debug: debug.map(String::from), + filename: filename, + function: function, + line: line, + } + } +} + +impl fmt::Display for ErrorMessage { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!( + f, + "Error {:?} ({:?}) at {}:{}", + self.message, self.debug, self.filename, self.line + ) + } +} + +impl Error for ErrorMessage { + fn description(&self) -> &str { + "ErrorMessage" + } +} diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index 5d937e176..a75d9a0b8 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -63,6 +63,10 @@ pub use auto::functions::*; mod log; pub use log::*; +#[macro_use] +mod error; +pub use error::*; + pub mod miniobject; pub use miniobject::{GstRc, MiniObject}; pub mod message;