Skip to main content

ferroui_base/threading/
dispatcher_unhandled_exception_event_args.rs

1use std::any::Any;
2use std::cell::Cell;
3use std::sync::Arc;
4
5use super::{Dispatcher, DispatcherEventArgs};
6
7/// Returns the message of a panic payload when it is a string, which is the
8/// case for every `panic!` with a message.
9pub(crate) fn panic_message(payload: &(dyn Any + Send)) -> Option<&str> {
10    if let Some(message) = payload.downcast_ref::<&'static str>() {
11        Some(message)
12    } else {
13        payload.downcast_ref::<String>().map(String::as_str)
14    }
15}
16
17/// Provides data for the [`Dispatcher::unhandled_exception`] event.
18pub struct DispatcherUnhandledExceptionEventArgs<'a> {
19    dispatcher: &'a Arc<Dispatcher>,
20    exception: &'a (dyn Any + Send),
21    handled: Cell<bool>,
22}
23
24impl<'a> DispatcherUnhandledExceptionEventArgs<'a> {
25    pub(crate) fn new(dispatcher: &'a Arc<Dispatcher>, exception: &'a (dyn Any + Send), handled: bool) -> Self {
26        Self { dispatcher, exception, handled: Cell::new(handled) }
27    }
28
29    /// The panic payload that was raised while executing code by way of a
30    /// dispatcher.
31    pub fn exception(&self) -> &(dyn Any + Send) {
32        self.exception
33    }
34
35    /// The panic message, when the payload is a string.
36    pub fn exception_message(&self) -> Option<&str> {
37        panic_message(self.exception)
38    }
39
40    /// Whether the exception event has been handled.
41    pub fn handled(&self) -> bool {
42        self.handled.get()
43    }
44
45    pub fn set_handled(&self, value: bool) {
46        // Only allow to be set true.
47        if value {
48            self.handled.set(value);
49        }
50    }
51}
52
53impl DispatcherEventArgs for DispatcherUnhandledExceptionEventArgs<'_> {
54    fn dispatcher(&self) -> &Arc<Dispatcher> {
55        self.dispatcher
56    }
57}