1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use thiserror::Error;
4
5use crate::{prelude::ElementExt, ErrorMessage, FlowReturn};
6
7#[doc(hidden)]
8#[inline(never)]
9pub fn post_panic_error_message(
10 element: &crate::Element,
11 src: &crate::Object,
12 panic: Option<Box<dyn std::any::Any + Send + 'static>>,
13) {
14 let cause: Option<&str> = panic.as_ref().and_then(|err: &Box| {
15 errOption<&str>.downcast_ref::<&str>()
16 .copied()
17 .or_else(|| err.downcast_ref::<String>().map(|s: &String| s.as_str()))
18 });
19
20 let msg: Message = if let Some(cause: &str) = cause {
21 crateErrorBuilder<'_>::message::Error::builder(error:crate::LibraryError::Failed, &format!("Panicked: {cause}"))
22 .src(src)
23 .build()
24 } else {
25 crateErrorBuilder<'_>::message::Error::builder(error:crate::LibraryError::Failed, message:"Panicked")
26 .src(src)
27 .build()
28 };
29
30 let _ = element.post_message(msg);
31}
32
33#[macro_export]
34macro_rules! panic_to_error(
35 ($imp:expr, $ret:expr, $code:block) => {{
36 #[allow(clippy::unused_unit)]
37 {
38 let panicked = $imp.panicked();
39 let element = $crate::glib::subclass::types::ObjectSubclassExt::obj($imp);
40 let element = unsafe { $crate::glib::Cast::unsafe_cast_ref::<$crate::Element>(element.as_ref()) };
41 if panicked.load(std::sync::atomic::Ordering::Relaxed) {
42 $crate::subclass::post_panic_error_message(
43 element,
44 $crate::glib::Cast::upcast_ref::<$crate::Object>(element),
45 None,
46 );
47 $ret
48 } else {
49 let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| $code));
50
51 match result {
52 Ok(result) => result,
53 Err(err) => {
54 panicked.store(true, std::sync::atomic::Ordering::Relaxed);
55 $crate::subclass::post_panic_error_message(
56 element,
57 $crate::glib::Cast::upcast_ref::<$crate::Object>(element),
58 Some(err),
59 );
60 $ret
61 }
62 }
63 }
64 }
65 }};
66);
67
68#[derive(Clone, Debug, PartialEq, Eq, Error)]
69pub enum FlowError {
70 #[error("Flushing")]
71 Flushing,
72 #[error("Eos")]
73 Eos,
74 #[error("Not Negotiated")]
75 NotNegotiated(ErrorMessage),
76 #[error("Error")]
77 Error(ErrorMessage),
78}
79
80impl From<FlowError> for FlowReturn {
81 fn from(err: FlowError) -> Self {
82 FlowReturn::from(&err)
83 }
84}
85
86impl<'a> From<&'a FlowError> for FlowReturn {
87 fn from(err: &FlowError) -> FlowReturn {
88 match *err {
89 FlowError::Flushing => FlowReturn::Flushing,
90 FlowError::Eos => FlowReturn::Eos,
91 FlowError::NotNegotiated(..) => FlowReturn::NotNegotiated,
92 FlowError::Error(..) => FlowReturn::Error,
93 }
94 }
95}
96