tesseract_swift_utils/
panic.rs

1use std::error::Error;
2use std::panic;
3use std::result::Result;
4
5pub trait FromPanic {
6    fn from_panic(panic: &str) -> Self;
7}
8
9pub trait PanicContext<E: Error> where Self: Sized, Self: Into<E>, Self: FromPanic {
10    fn panic_context<T>(
11        fun: impl FnOnce() -> Result<T, Self> + panic::UnwindSafe
12    ) -> Result<T, E> {
13        panic::catch_unwind(fun)
14            .map_err(|err| {
15                let panic = if let Some(string) = err.downcast_ref::<String>() {
16                    string.clone()
17                } else if let Some(string) = err.downcast_ref::<&'static str>() {
18                    (*string).to_owned()
19                } else {
20                    format!("{:?}", err)
21                };
22                Self::from_panic(&panic).into()
23            }).and_then(|res| res.map_err(|e| e.into()))
24    }
25
26    fn panic_context_value<T>(fun: impl FnOnce() -> T + panic::UnwindSafe) -> Result<T, E> {
27        Self::panic_context(|| Ok(fun()))
28    }
29}
30
31impl<EI, EO> PanicContext<EO> for EI where EI: Sized, EI: Into<EO>, EI: FromPanic, EO: Error {}
32
33#[allow(dead_code)]
34pub fn hide_exceptions() {
35    panic::set_hook(Box::new(|_| {}));
36}