alef 0.70.0

Opinionated polyglot binding generator for Rust libraries
Documentation
/// Attach a vtable visitor bridge to a `{{ options_type_name }}` options handle.
///
/// The `{{ handle_type }}` encapsulates C callbacks invoked during conversion. Neither handle
/// is consumed; both must be freed independently after every conversion using the options
/// handle has completed. Pass `visitor = 0` to clear a previously attached visitor.
///
/// # Safety
///
/// `options` must be a live handle returned by `{{ prefix }}_{{ options_type_snake }}_from_json`
/// or an equivalent constructor. `visitor` must be zero or a live handle returned by
/// `{{ handle_constructor }}`. The visitor handle must remain live while the options handle
/// can be used for conversion.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn {{ function_name }}(options: AlefHandle, visitor: AlefHandle) {
    catch_ffi_panic((), || {
        if options == 0 {
            return;
        }
        if visitor == 0 {
            if let Err(error) =
                with_handle_mut::<{{ core_import }}::{{ options_type_name }}, _>(options, |options_ref| {
                    options_ref.{{ field_name }} = None;
                })
            {
                set_handle_error(&error);
            }
            return;
        }

        if let Err(error) = with_handle::<{{ handle_type }}, _>(visitor, |_| ()) {
            set_handle_error(&error);
            return;
        }

        // `VtableRef` resolves the registry-owned visitor for each callback invocation.
        struct VtableRef(AlefHandle);

        impl std::fmt::Debug for VtableRef {
            fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                formatter.debug_tuple("VtableRef").finish()
            }
        }

        impl {{ trait_path }} for VtableRef {
{{ delegation_methods }}        }

        if let Err(error) = with_handle_mut::<{{ core_import }}::{{ options_type_name }}, _>(options, |options_ref| {
            options_ref.{{ field_name }} = Some(std::sync::Arc::new(std::sync::Mutex::new(VtableRef(visitor))));
        }) {
            set_handle_error(&error);
        }
    })
}