fn ffi_buffer_scaffolding_fn()

in uniffi_macros/src/export/scaffolding.rs [316:366]


fn ffi_buffer_scaffolding_fn(
    fn_ident: &Ident,
    return_type: &TokenStream,
    param_types: &[TokenStream],
    has_rust_call_status: bool,
) -> TokenStream {
    let fn_name = fn_ident.to_string();
    let ffi_buffer_fn_name = uniffi_meta::ffi_buffer_symbol_name(&fn_name);
    let ident = Ident::new(&ffi_buffer_fn_name, proc_macro2::Span::call_site());
    let type_list: Vec<_> = param_types.iter().map(|ty| quote! { #ty }).collect();
    if has_rust_call_status {
        quote! {
            #[doc(hidden)]
            #[unsafe(no_mangle)]
            pub unsafe extern "C" fn #ident(
                arg_ptr: *mut ::uniffi::FfiBufferElement,
                return_ptr: *mut ::uniffi::FfiBufferElement,
            ) {
                let mut arg_buf = unsafe { ::std::slice::from_raw_parts(arg_ptr, ::uniffi::ffi_buffer_size!(#(#type_list),*)) };
                let mut return_buf = unsafe { ::std::slice::from_raw_parts_mut(return_ptr, ::uniffi::ffi_buffer_size!(#return_type, ::uniffi::RustCallStatus)) };
                let mut out_status: ::uniffi::RustCallStatus = ::std::default::Default::default();

                let return_value = #fn_ident(
                    #(
                        <#type_list as ::uniffi::FfiSerialize>::read(&mut arg_buf),
                    )*
                    &mut out_status,
                );
                <#return_type as ::uniffi::FfiSerialize>::write(&mut return_buf, return_value);
                <::uniffi::RustCallStatus as ::uniffi::FfiSerialize>::write(&mut return_buf, out_status);
            }
        }
    } else {
        quote! {
            #[doc(hidden)]
            #[unsafe(no_mangle)]
            pub unsafe extern "C" fn #ident(
                arg_ptr: *mut ::uniffi::FfiBufferElement,
                return_ptr: *mut ::uniffi::FfiBufferElement,
            ) {
                let mut arg_buf = unsafe { ::std::slice::from_raw_parts(arg_ptr, ::uniffi::ffi_buffer_size!(#(#type_list),*)) };
                let mut return_buf = unsafe { ::std::slice::from_raw_parts_mut(return_ptr, ::uniffi::ffi_buffer_size!(#return_type)) };

                let return_value = #fn_ident(#(
                    <#type_list as ::uniffi::FfiSerialize>::read(&mut arg_buf),
                )*);
                <#return_type as ::uniffi::FfiSerialize>::put(&mut return_buf, return_value);
            }
        }
    }
}