diff --git a/gstreamer/Cargo.toml b/gstreamer/Cargo.toml index 4e41906d9..c52bf2d15 100644 --- a/gstreamer/Cargo.toml +++ b/gstreamer/Cargo.toml @@ -29,6 +29,7 @@ serde_bytes = { version = "0.11", optional = true } serde_derive = { version = "1.0", optional = true } paste = { version = "0.1" } pretty-hex = "0.1" +thiserror = "1" [build-dependencies] rustdoc-stripper = { version = "0.1", optional = true } diff --git a/gstreamer/src/enums.rs b/gstreamer/src/enums.rs index cd9705272..8eb0d3e31 100644 --- a/gstreamer/src/enums.rs +++ b/gstreamer/src/enums.rs @@ -6,9 +6,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::error::Error; -use std::fmt; use std::{cmp, ops}; +use thiserror::Error; use ClockReturn; use FlowReturn; use PadLinkReturn; @@ -59,28 +58,17 @@ impl From for StateChangeReturn { } } -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)] #[must_use] +#[error("Element failed to change its state")] pub struct StateChangeError; -impl fmt::Display for StateChangeError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "State-change error") - } -} - impl From for StateChangeReturn { fn from(value: StateChangeError) -> Self { StateChangeReturn::from_error(value) } } -impl Error for StateChangeError { - fn description(&self) -> &str { - "Element failed to change its state" - } -} - impl From> for StateChangeReturn { fn from(res: Result) -> Self { match res { @@ -155,52 +143,35 @@ impl From for FlowReturn { } } -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)] #[must_use] pub enum FlowError { + #[error("Pad is not linked")] NotLinked, + #[error("Pad is flushing")] Flushing, + #[error("Pad is EOS")] Eos, + #[error("Pad is not negotiated")] NotNegotiated, + #[error("Some (fatal) error occurred. Element generating this error should post an error message with more details")] Error, + #[error("This operation is not supported")] NotSupported, + #[error("Elements can use values starting from this (and lower) to define custom error codes")] CustomError, + #[error("Pre-defined custom error code")] CustomError1, + #[error("Pre-defined custom error code")] CustomError2, } -impl fmt::Display for FlowError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Flow error: {}", self.description()) - } -} - impl From for FlowReturn { fn from(value: FlowError) -> Self { FlowReturn::from_error(value) } } -impl Error for FlowError { - fn description(&self) -> &str { - match *self { - FlowError::NotLinked => "Pad is not linked", - FlowError::Flushing => "Pad is flushing", - FlowError::Eos => "Pad is EOS", - FlowError::NotNegotiated => "Pad is not negotiated", - FlowError::Error => { - "Some (fatal) error occurred. Element generating this error should post an error message with more details" - } - FlowError::NotSupported => "This operation is not supported", - FlowError::CustomError => { - "Elements can use values starting from this (and lower) to define custom error codes" - } - FlowError::CustomError1 => "Pre-defined custom error code", - FlowError::CustomError2 => "Pre-defined custom error code", - } - } -} - impl From> for FlowReturn { fn from(res: Result) -> Self { match res { @@ -249,42 +220,29 @@ impl From for PadLinkReturn { } } -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)] #[must_use] pub enum PadLinkError { + #[error("Pads have no common grandparent")] WrongHierarchy, + #[error("Pad was already linked")] WasLinked, + #[error("Pads have wrong direction")] WrongDirection, + #[error("Pads do not have common format")] Noformat, + #[error("Pads cannot cooperate in scheduling")] Nosched, + #[error("Refused for some other reason")] Refused, } -impl fmt::Display for PadLinkError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Pad failed to link: {}", self.description()) - } -} - impl From for PadLinkReturn { fn from(value: PadLinkError) -> Self { PadLinkReturn::from_error(value) } } -impl Error for PadLinkError { - fn description(&self) -> &str { - match *self { - PadLinkError::WrongHierarchy => "Pads have no common grandparent", - PadLinkError::WasLinked => "Pad was already linked", - PadLinkError::WrongDirection => "Pads have wrong direction", - PadLinkError::Noformat => "Pads do not have common format", - PadLinkError::Nosched => "Pads cannot cooperate in scheduling", - PadLinkError::Refused => "Refused for some other reason", - } - } -} - impl From> for PadLinkReturn { fn from(res: Result) -> Self { match res { @@ -340,42 +298,29 @@ impl From for ClockReturn { } } -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)] #[must_use] pub enum ClockError { + #[error("The operation was scheduled too late")] Early, + #[error("The clockID was unscheduled")] Unscheduled, + #[error("The ClockID is busy")] Busy, + #[error("A bad time was provided to a function")] Badtime, + #[error("An error occurred")] Error, + #[error("Operation is not supported")] Unsupported, } -impl fmt::Display for ClockError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Clock error: {}", self.description()) - } -} - impl From for ClockReturn { fn from(value: ClockError) -> Self { ClockReturn::from_error(value) } } -impl Error for ClockError { - fn description(&self) -> &str { - match *self { - ClockError::Early => "The operation was scheduled too late", - ClockError::Unscheduled => "The clockID was unscheduled", - ClockError::Busy => "The ClockID is busy", - ClockError::Badtime => "A bad time was provided to a function", - ClockError::Error => "An error occurred", - ClockError::Unsupported => "Operation is not supported", - } - } -} - impl From> for ClockReturn { fn from(res: Result) -> Self { match res { @@ -489,26 +434,13 @@ impl ops::SubAssign for ::Rank { } } -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)] #[must_use] pub enum TagError { + #[error("The value type doesn't match with the specified Tag")] TypeMismatch, } -impl fmt::Display for TagError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Tag error: {}", self.description()) - } -} - -impl Error for TagError { - fn description(&self) -> &str { - match *self { - TagError::TypeMismatch => "The value type doesn't match with the specified Tag", - } - } -} - // This cannot be done automatically because in GStreamer it's exposed as a bitflag but works as an // enum instead #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] diff --git a/gstreamer/src/error.rs b/gstreamer/src/error.rs index ebde9eec0..d27115fdf 100644 --- a/gstreamer/src/error.rs +++ b/gstreamer/src/error.rs @@ -6,8 +6,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::error::Error; -use std::fmt; +use thiserror::Error; use glib; use glib::IsA; @@ -50,7 +49,8 @@ macro_rules! gst_error_msg( }}; ); -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[error("Error {:?} ({:?}) at {}:{}", .message, .debug, .filename, .line)] pub struct ErrorMessage { pub(crate) error_domain: glib::Quark, pub(crate) error_code: i32, @@ -85,22 +85,6 @@ impl ErrorMessage { } } -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" - } -} - #[macro_export] macro_rules! gst_loggable_error( // Plain strings @@ -129,7 +113,8 @@ macro_rules! gst_result_from_gboolean( }}; ); -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Error)] +#[error("Error {:?}: {:?} at {}:{}", .category.get_name(), .bool_error.message, .bool_error.filename, .bool_error.line)] pub struct LoggableError { category: ::DebugCategory, bool_error: glib::BoolError, @@ -179,25 +164,6 @@ impl From for LoggableError { } } -impl fmt::Display for LoggableError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!( - f, - "Error {:?}: {:?} at {}:{}", - self.category.get_name(), - self.bool_error.message, - self.bool_error.filename, - self.bool_error.line - ) - } -} - -impl Error for LoggableError { - fn description(&self) -> &str { - self.bool_error.message.as_ref() - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/gstreamer/src/iterator.rs b/gstreamer/src/iterator.rs index a4bbad28d..51ca4048e 100644 --- a/gstreamer/src/iterator.rs +++ b/gstreamer/src/iterator.rs @@ -15,7 +15,6 @@ use glib_sys; use glib_sys::{gconstpointer, gpointer}; use gobject_sys; use gst_sys; -use std::error::Error; use std::ffi::CString; use std::fmt; use std::iter; @@ -23,31 +22,16 @@ use std::marker::PhantomData; use std::mem; use std::ptr; use std::sync::Arc; +use thiserror::Error; -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)] pub enum IteratorError { + #[error("Resync")] Resync, + #[error("Error")] Error, } -impl fmt::Display for IteratorError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - IteratorError::Resync => write!(f, "Resync"), - IteratorError::Error => write!(f, "Error"), - } - } -} - -impl Error for IteratorError { - fn description(&self) -> &str { - match *self { - IteratorError::Resync => "Resync", - IteratorError::Error => "Error", - } - } -} - // Implemented manually so that we can use generics for the item pub struct Iterator { iter: ptr::NonNull, diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index 6028cbe8a..35ab61a49 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -15,6 +15,7 @@ extern crate cfg_if; #[macro_use] extern crate lazy_static; extern crate libc; +extern crate thiserror; // Re-exported for the subclass gst_plugin_define! macro #[doc(hidden)] diff --git a/gstreamer/src/subclass/error.rs b/gstreamer/src/subclass/error.rs index 19b991677..1653b8be8 100644 --- a/gstreamer/src/subclass/error.rs +++ b/gstreamer/src/subclass/error.rs @@ -6,9 +6,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::error::Error; -use std::fmt::Error as FmtError; -use std::fmt::{Display, Formatter}; +use thiserror::Error; use ErrorMessage; use FlowReturn; @@ -47,11 +45,15 @@ macro_rules! gst_panic_to_error( }}; ); -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Error)] pub enum FlowError { + #[error("Flushing")] Flushing, + #[error("Eos")] Eos, + #[error("Not Negotiated")] NotNegotiated(ErrorMessage), + #[error("Error")] Error(ErrorMessage), } @@ -71,26 +73,3 @@ impl<'a> From<&'a FlowError> for FlowReturn { } } } - -impl Display for FlowError { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - match *self { - FlowError::Flushing | FlowError::Eos => f.write_str(self.description()), - FlowError::NotNegotiated(ref m) => { - f.write_fmt(format_args!("{}: {}", self.description(), m)) - } - FlowError::Error(ref m) => f.write_fmt(format_args!("{}: {}", self.description(), m)), - } - } -} - -impl Error for FlowError { - fn description(&self) -> &str { - match *self { - FlowError::Flushing => "Flushing", - FlowError::Eos => "Eos", - FlowError::NotNegotiated(..) => "Not Negotiated", - FlowError::Error(..) => "Error", - } - } -}