boltffi_bindgen 0.25.0

Code generation library for BoltFFI - generates Swift, Kotlin, and TypeScript bindings
Documentation
    internal static unsafe class {{ closure.bridge_name }}
    {
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
{%- if closure.method.native_return_type.is_bool() %}
        [return: MarshalAs(UnmanagedType.I1)]
{%- endif %}
        internal delegate {{ closure.method.native_return_type }} NativeInvoke({{ closure.method.native_params }});

        private static readonly NativeInvoke InvokeDelegate = Invoke;

        internal static Scope Pin({{ closure.public_name }} impl_) => new(impl_);

        internal sealed class Scope : IDisposable
        {
            private GCHandle _handle;
            private bool _disposed;

            internal Scope({{ closure.public_name }} impl_)
            {
                _handle = GCHandle.Alloc(impl_);
                Function = InvokeDelegate;
                Context = GCHandle.ToIntPtr(_handle);
            }

            internal NativeInvoke Function { get; }
            internal IntPtr Context { get; }

            public void Dispose()
            {
                if (_disposed) return;
                _disposed = true;
                if (_handle.IsAllocated) _handle.Free();
            }
        }

        private static {{ closure.method.native_return_type }} Invoke({{ closure.method.native_params }})
        {
            var impl_ = ({{ closure.public_name }})((GCHandle)context).Target!;
{%- for param in closure.method.bridge_params %}
{%- match param %}
{%- when CSharpCallbackBridgeParamPlan::Direct with { public_param, native_param, decoded_arg, proxy_arg } %}
{%- when CSharpCallbackBridgeParamPlan::WireEncoded with { public_param, native_ptr_param, native_len_param, reader_local, decoded_arg, writer, pin_local, ptr_local } %}
            var {{ reader_local }} = new WireReader({{ native_ptr_param.name }}, {{ native_len_param.name }});
{%- endmatch %}
{%- endfor %}
{%- match closure.method.invoke %}
{%- when CSharpClosureInvokePlan::Void with { decoded_args } %}
            impl_({{ decoded_args }});
{%- when CSharpClosureInvokePlan::Direct with { decoded_args, native_value_expr } %}
            var __boltffiValue = impl_({{ decoded_args }});
            return {{ native_value_expr }};
{%- when CSharpClosureInvokePlan::Encoded with { is_result, decoded_args, result_assignment, writer } %}
{%- if let Some(result_assignment) = result_assignment %}
            BoltFFIResult<{{ result_assignment.result_type.ok_type }}, {{ result_assignment.result_type.err_type }}> __boltffiResult;
            try
            {
{%- match result_assignment.ok %}
{%- when CSharpCallbackResultOkPlan::Void with { receiver, method_name, args } %}
                {{ receiver }}.{{ method_name }}({{ args }});
                __boltffiResult = BoltFFIResult<{{ result_assignment.result_type.ok_type }}, {{ result_assignment.result_type.err_type }}>.Ok(default);
{%- when CSharpCallbackResultOkPlan::Value with { receiver, method_name, args } %}
                __boltffiResult = BoltFFIResult<{{ result_assignment.result_type.ok_type }}, {{ result_assignment.result_type.err_type }}>.Ok({{ receiver }}.{{ method_name }}({{ args }}));
{%- endmatch %}
            }
{%- match result_assignment.catch %}
{%- when Some with (catch_plan) %}
{%- match catch_plan %}
{%- when CSharpCallbackResultCatchPlan::TypedException with { exception_type } %}
            catch ({{ exception_type }} __boltffiException)
            {
                __boltffiResult = BoltFFIResult<{{ result_assignment.result_type.ok_type }}, {{ result_assignment.result_type.err_type }}>.Err(__boltffiException.Error);
            }
{%- when CSharpCallbackResultCatchPlan::ExceptionMessage %}
            catch (Exception __boltffiException)
            {
                __boltffiResult = BoltFFIResult<{{ result_assignment.result_type.ok_type }}, {{ result_assignment.result_type.err_type }}>.Err(__boltffiException.Message);
            }
{%- endmatch %}
{%- when None %}
            catch
            {
                throw;
            }
{%- endmatch %}
{%- else %}
            var __boltffiValue = impl_({{ decoded_args }});
{%- endif %}
            byte[] {{ writer.bytes_binding_name }};
            using (var {{ writer.binding_name }} = new WireWriter({{ writer.size_expr }}))
            {
{%- for stmt in writer.encode_stmts %}
                {{ stmt }};
{%- endfor %}
                {{ writer.bytes_binding_name }} = {{ writer.binding_name }}.ToArray();
            }
            return FfiBuf.FromBytes({{ writer.bytes_binding_name }});
{%- endmatch %}
        }
    }