gst_plugin/
error.rs

1// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::error::Error;
10use std::fmt::Error as FmtError;
11use std::fmt::{Display, Formatter};
12
13use gst;
14
15#[macro_export]
16macro_rules! panic_to_error(
17    ($element:expr, $panicked:expr, $ret:expr, $code:block) => {{
18        use std::panic::{self, AssertUnwindSafe};
19        use std::sync::atomic::Ordering;
20
21        if $panicked.load(Ordering::Relaxed) {
22            $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked"]));
23            $ret
24        } else {
25            let result = panic::catch_unwind(AssertUnwindSafe(|| $code));
26
27            match result {
28                Ok(result) => result,
29                Err(err) => {
30                    $panicked.store(true, Ordering::Relaxed);
31                    if let Some(cause) = err.downcast_ref::<&str>() {
32                        $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked: {}", cause]));
33                    } else if let Some(cause) = err.downcast_ref::<String>() {
34                        $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked: {}", cause]));
35                    } else {
36                        $element.post_error_message(&gst_error_msg!(gst::LibraryError::Failed, ["Panicked"]));
37                    }
38                    $ret
39                }
40            }
41        }
42    }};
43);
44
45#[derive(Clone, Debug, PartialEq, Eq)]
46pub enum FlowError {
47    Flushing,
48    Eos,
49    NotNegotiated(gst::ErrorMessage),
50    Error(gst::ErrorMessage),
51}
52
53impl From<FlowError> for gst::FlowReturn {
54    fn from(err: FlowError) -> Self {
55        gst::FlowReturn::from(&err)
56    }
57}
58
59impl<'a> From<&'a FlowError> for gst::FlowReturn {
60    fn from(err: &FlowError) -> gst::FlowReturn {
61        match *err {
62            FlowError::Flushing => gst::FlowReturn::Flushing,
63            FlowError::Eos => gst::FlowReturn::Eos,
64            FlowError::NotNegotiated(..) => gst::FlowReturn::NotNegotiated,
65            FlowError::Error(..) => gst::FlowReturn::Error,
66        }
67    }
68}
69
70impl Display for FlowError {
71    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
72        match *self {
73            FlowError::Flushing | FlowError::Eos => f.write_str(self.description()),
74            FlowError::NotNegotiated(ref m) => {
75                f.write_fmt(format_args!("{}: {}", self.description(), m))
76            }
77            FlowError::Error(ref m) => f.write_fmt(format_args!("{}: {}", self.description(), m)),
78        }
79    }
80}
81
82impl Error for FlowError {
83    fn description(&self) -> &str {
84        match *self {
85            FlowError::Flushing => "Flushing",
86            FlowError::Eos => "Eos",
87            FlowError::NotNegotiated(..) => "Not Negotiated",
88            FlowError::Error(..) => "Error",
89        }
90    }
91}