elfo-core 0.2.0-alpha.21

The core of the elfo system
Documentation
use std::{
    any::Any,
    future::Future,
    panic::{self, AssertUnwindSafe},
};

use futures::FutureExt;

pub(crate) fn sync_catch<R>(f: impl FnOnce() -> R) -> Result<R, String> {
    panic::catch_unwind(AssertUnwindSafe(f)).map_err(panic_to_string)
}

pub(crate) async fn catch<R>(f: impl Future<Output = R>) -> Result<R, String> {
    AssertUnwindSafe(f)
        .catch_unwind()
        .await
        .map_err(panic_to_string)
}

fn panic_to_string(payload: Box<dyn Any + Send>) -> String {
    if let Some(message) = payload.downcast_ref::<&str>() {
        format!("panic: {message}")
    } else if let Some(message) = payload.downcast_ref::<String>() {
        format!("panic: {message}")
    } else {
        "panic: <unsupported payload>".to_string()
    }
}