alef 0.114.0

Opinionated polyglot binding generator for Rust libraries
Documentation
clear_last_error();

    if client.is_null() {
        set_last_error(99, "{{ prefix }}_{{ name }}: client must not be NULL");
        return -1;
    }
    if request_json.is_null() {
        set_last_error(99, "{{ prefix }}_{{ name }}: request_json must not be NULL");
        return -1;
    }

    // SAFETY: caller guarantees `client` and `request_json` are non-null and valid.
    let client_ref = unsafe { &(*client) };

    let json_str = match unsafe { std::ffi::CStr::from_ptr(request_json) }.to_str() {
        Ok(s) => s,
        Err(e) => {
            set_last_error(99, &format!("{{ prefix }}_{{ name }}: request_json is not valid UTF-8: {e}"));
            return -1;
        }
    };

    let request: {{ request_type }} = match serde_json::from_str(json_str) {
        Ok(r) => r,
        Err(e) => {
            set_last_error(99, &format!("{{ prefix }}_{{ name }}: failed to parse request JSON: {e}"));
            return -1;
        }
    };

    let rt = get_ffi_runtime();

    let result = rt.block_on(async {
        use futures_util::StreamExt;

        let mut stream = match {{ core_call }}.await {
            Ok(s) => s,
            Err(e) => return Err(format!("{{ prefix }}_{{ name }}: failed to open stream: {e}")),
        };

        loop {
            match stream.next().await {
                None => break,
                Some(Err(e)) => return Err(format!("{{ prefix }}_{{ name }}: stream error: {e}")),
                Some(Ok(chunk)) => {
                    let chunk_json = match serde_json::to_string(&chunk) {
                        Ok(s) => s,
                        Err(e) => return Err(format!("{{ prefix }}_{{ name }}: failed to serialise chunk: {e}")),
                    };
                    match std::ffi::CString::new(chunk_json) {
                        Ok(c_str) => {
                            // SAFETY: `callback` is a valid function pointer supplied by the caller.
                            // `c_str.as_ptr()` is valid for this block scope.
                            // `user_data` is forwarded as-is; ownership stays with the caller.
                            unsafe { callback(c_str.as_ptr(), user_data) };
                        }
                        Err(e) => return Err(format!("{{ prefix }}_{{ name }}: chunk JSON contained NUL byte: {e}")),
                    }
                }
            }
        }
        Ok(())
    });

    match result {
        Ok(()) => 0,
        Err(e) => {
            set_last_error(99, &e);
            -1
        }
    }