gstreamer: use thiserror crate

Make code simpler and fix deprecated warning when building on nightly as
Error::description is being deprecated.
This commit is contained in:
Guillaume Desmottes 2020-01-10 17:03:03 +05:30
parent e151ee75f8
commit 01c4d08501
6 changed files with 46 additions and 183 deletions

View file

@ -29,6 +29,7 @@ serde_bytes = { version = "0.11", optional = true }
serde_derive = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true }
paste = { version = "0.1" } paste = { version = "0.1" }
pretty-hex = "0.1" pretty-hex = "0.1"
thiserror = "1"
[build-dependencies] [build-dependencies]
rustdoc-stripper = { version = "0.1", optional = true } rustdoc-stripper = { version = "0.1", optional = true }

View file

@ -6,9 +6,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::error::Error;
use std::fmt;
use std::{cmp, ops}; use std::{cmp, ops};
use thiserror::Error;
use ClockReturn; use ClockReturn;
use FlowReturn; use FlowReturn;
use PadLinkReturn; use PadLinkReturn;
@ -59,28 +58,17 @@ impl From<StateChangeSuccess> for StateChangeReturn {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)]
#[must_use] #[must_use]
#[error("Element failed to change its state")]
pub struct StateChangeError; pub struct StateChangeError;
impl fmt::Display for StateChangeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "State-change error")
}
}
impl From<StateChangeError> for StateChangeReturn { impl From<StateChangeError> for StateChangeReturn {
fn from(value: StateChangeError) -> Self { fn from(value: StateChangeError) -> Self {
StateChangeReturn::from_error(value) StateChangeReturn::from_error(value)
} }
} }
impl Error for StateChangeError {
fn description(&self) -> &str {
"Element failed to change its state"
}
}
impl From<Result<StateChangeSuccess, StateChangeError>> for StateChangeReturn { impl From<Result<StateChangeSuccess, StateChangeError>> for StateChangeReturn {
fn from(res: Result<StateChangeSuccess, StateChangeError>) -> Self { fn from(res: Result<StateChangeSuccess, StateChangeError>) -> Self {
match res { match res {
@ -155,52 +143,35 @@ impl From<FlowSuccess> for FlowReturn {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)]
#[must_use] #[must_use]
pub enum FlowError { pub enum FlowError {
#[error("Pad is not linked")]
NotLinked, NotLinked,
#[error("Pad is flushing")]
Flushing, Flushing,
#[error("Pad is EOS")]
Eos, Eos,
#[error("Pad is not negotiated")]
NotNegotiated, NotNegotiated,
#[error("Some (fatal) error occurred. Element generating this error should post an error message with more details")]
Error, Error,
#[error("This operation is not supported")]
NotSupported, NotSupported,
#[error("Elements can use values starting from this (and lower) to define custom error codes")]
CustomError, CustomError,
#[error("Pre-defined custom error code")]
CustomError1, CustomError1,
#[error("Pre-defined custom error code")]
CustomError2, CustomError2,
} }
impl fmt::Display for FlowError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Flow error: {}", self.description())
}
}
impl From<FlowError> for FlowReturn { impl From<FlowError> for FlowReturn {
fn from(value: FlowError) -> Self { fn from(value: FlowError) -> Self {
FlowReturn::from_error(value) 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<Result<FlowSuccess, FlowError>> for FlowReturn { impl From<Result<FlowSuccess, FlowError>> for FlowReturn {
fn from(res: Result<FlowSuccess, FlowError>) -> Self { fn from(res: Result<FlowSuccess, FlowError>) -> Self {
match res { match res {
@ -249,42 +220,29 @@ impl From<PadLinkSuccess> for PadLinkReturn {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)]
#[must_use] #[must_use]
pub enum PadLinkError { pub enum PadLinkError {
#[error("Pads have no common grandparent")]
WrongHierarchy, WrongHierarchy,
#[error("Pad was already linked")]
WasLinked, WasLinked,
#[error("Pads have wrong direction")]
WrongDirection, WrongDirection,
#[error("Pads do not have common format")]
Noformat, Noformat,
#[error("Pads cannot cooperate in scheduling")]
Nosched, Nosched,
#[error("Refused for some other reason")]
Refused, 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<PadLinkError> for PadLinkReturn { impl From<PadLinkError> for PadLinkReturn {
fn from(value: PadLinkError) -> Self { fn from(value: PadLinkError) -> Self {
PadLinkReturn::from_error(value) 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<Result<PadLinkSuccess, PadLinkError>> for PadLinkReturn { impl From<Result<PadLinkSuccess, PadLinkError>> for PadLinkReturn {
fn from(res: Result<PadLinkSuccess, PadLinkError>) -> Self { fn from(res: Result<PadLinkSuccess, PadLinkError>) -> Self {
match res { match res {
@ -340,42 +298,29 @@ impl From<ClockSuccess> for ClockReturn {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)]
#[must_use] #[must_use]
pub enum ClockError { pub enum ClockError {
#[error("The operation was scheduled too late")]
Early, Early,
#[error("The clockID was unscheduled")]
Unscheduled, Unscheduled,
#[error("The ClockID is busy")]
Busy, Busy,
#[error("A bad time was provided to a function")]
Badtime, Badtime,
#[error("An error occurred")]
Error, Error,
#[error("Operation is not supported")]
Unsupported, Unsupported,
} }
impl fmt::Display for ClockError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Clock error: {}", self.description())
}
}
impl From<ClockError> for ClockReturn { impl From<ClockError> for ClockReturn {
fn from(value: ClockError) -> Self { fn from(value: ClockError) -> Self {
ClockReturn::from_error(value) 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<Result<ClockSuccess, ClockError>> for ClockReturn { impl From<Result<ClockSuccess, ClockError>> for ClockReturn {
fn from(res: Result<ClockSuccess, ClockError>) -> Self { fn from(res: Result<ClockSuccess, ClockError>) -> Self {
match res { match res {
@ -489,26 +434,13 @@ impl ops::SubAssign<u32> for ::Rank {
} }
} }
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)]
#[must_use] #[must_use]
pub enum TagError { pub enum TagError {
#[error("The value type doesn't match with the specified Tag")]
TypeMismatch, 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 // This cannot be done automatically because in GStreamer it's exposed as a bitflag but works as an
// enum instead // enum instead
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]

View file

@ -6,8 +6,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::error::Error; use thiserror::Error;
use std::fmt;
use glib; use glib;
use glib::IsA; 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 struct ErrorMessage {
pub(crate) error_domain: glib::Quark, pub(crate) error_domain: glib::Quark,
pub(crate) error_code: i32, 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_export]
macro_rules! gst_loggable_error( macro_rules! gst_loggable_error(
// Plain strings // 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 { pub struct LoggableError {
category: ::DebugCategory, category: ::DebugCategory,
bool_error: glib::BoolError, bool_error: glib::BoolError,
@ -179,25 +164,6 @@ impl From<glib::BoolError> 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -15,7 +15,6 @@ use glib_sys;
use glib_sys::{gconstpointer, gpointer}; use glib_sys::{gconstpointer, gpointer};
use gobject_sys; use gobject_sys;
use gst_sys; use gst_sys;
use std::error::Error;
use std::ffi::CString; use std::ffi::CString;
use std::fmt; use std::fmt;
use std::iter; use std::iter;
@ -23,31 +22,16 @@ use std::marker::PhantomData;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use std::sync::Arc; 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 { pub enum IteratorError {
#[error("Resync")]
Resync, Resync,
#[error("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 // Implemented manually so that we can use generics for the item
pub struct Iterator<T> { pub struct Iterator<T> {
iter: ptr::NonNull<gst_sys::GstIterator>, iter: ptr::NonNull<gst_sys::GstIterator>,

View file

@ -15,6 +15,7 @@ extern crate cfg_if;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
extern crate libc; extern crate libc;
extern crate thiserror;
// Re-exported for the subclass gst_plugin_define! macro // Re-exported for the subclass gst_plugin_define! macro
#[doc(hidden)] #[doc(hidden)]

View file

@ -6,9 +6,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::error::Error; use thiserror::Error;
use std::fmt::Error as FmtError;
use std::fmt::{Display, Formatter};
use ErrorMessage; use ErrorMessage;
use FlowReturn; 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 { pub enum FlowError {
#[error("Flushing")]
Flushing, Flushing,
#[error("Eos")]
Eos, Eos,
#[error("Not Negotiated")]
NotNegotiated(ErrorMessage), NotNegotiated(ErrorMessage),
#[error("Error")]
Error(ErrorMessage), 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",
}
}
}