pub fn panics_and_errors_to_ffi_enum<E: Debug, FE>(
    f: impl FnOnce() -> Result<(), E>,
    error_context: &str
) -> FE
where FE: From<E> + FFIError,
Expand description

Helper to transform Result types to FFIError::SUCCESS enums inside extern "C" functions.

This function executes the given closure f. If f returns Ok(()) the SUCCESS variant is returned. On a panic or Err the respective error variant is returned instead.

§Feature Flags

If the log crate option is enabled this will invoke log::error on errors and panics.

§Example

use interoptopus::patterns::result::panics_and_errors_to_ffi_enum;
use interoptopus::{ffi_type, ffi_function, here};

// The FFI error the library users will see.
#[ffi_type(patterns(ffi_error))]
#[repr(C)]
pub enum MyFFIError {
    Ok = 0,
    Null = 100,
    Panic = 200,
    Fail = 300,
}

// How to convert a normal error to an FFI Error.
impl From<Error> for MyFFIError {
    fn from(x: Error) -> Self {
        match x {
            Error::Bad => Self::Fail,
        }
    }
}

// Map special error conditions to your error type.
impl interoptopus::patterns::result::FFIError for MyFFIError {
    const SUCCESS: Self = Self::Ok;
    const NULL: Self = Self::Null;
    const PANIC: Self = Self::Panic;
}

// Now call a function that may panic or throw an error.
#[ffi_function]
#[no_mangle]
#[allow(unreachable_code)]
pub extern "C" fn panics() -> MyFFIError {
    panics_and_errors_to_ffi_enum(
        || {
            panic!("Oh no");
            Ok::<(), Error>(())
        },
        here!(),
    )
}

§Safety

Once FFIError::PANIC has been observed the enum’s recipient should stop calling this API (and probably gracefully shutdown or restart), as any subsequent call risks causing a process abort.