C FFI API
The C API provides a stable ABI for embedding gridwell in any language with C interop. The header is crates/gridwell-ffi/include/gridwell.h. It is generated from the Rust source by cbindgen, and a test fails if the committed copy goes stale, so the header is the authoritative reference. The summary below mirrors it.
Types
typedef struct GridwellTable GridwellTable; // opaque
typedef struct GridwellError GridwellError; // opaque
typedef struct GridwellTextResult {
char *text; // NUL-terminated UTF-8; null on failure
size_t len; // bytes, excluding the terminator
} GridwellTextResult;
typedef struct GridwellBinaryResult {
uint8_t *data; // null on failure
size_t len;
} GridwellBinaryResult;Error codes
| Code | Constant | Meaning |
|---|---|---|
| 1 | GRIDWELL_ERR_PARSE |
Invalid UTF-8 or JSON, or JSON that isn’t a table IR |
| 2 | GRIDWELL_ERR_VALIDATE |
The IR failed validation; the message lists the errors |
| 3 | GRIDWELL_ERR_RENDER |
A writer failed, the format name is unknown, or a binary format was passed to gridwell_render_text (or a text one to gridwell_render_binary) |
| 4 | GRIDWELL_ERR_INVALID_ARG |
A required pointer was null, or a string wasn’t UTF-8 |
| 5 | GRIDWELL_ERR_PANIC |
An internal panic was caught at the boundary (always a gridwell bug; please report it) |
| 6 | GRIDWELL_ERR_OPTIONS |
The writer options are invalid: malformed JSON, not an object, an unknown option, a wrong type, or a value out of range |
No Rust panic ever unwinds into C: each function catches panics and reports them as GRIDWELL_ERR_PANIC.
Functions
// Parse
GridwellTable *gridwell_parse_ir(const char *json, size_t len, GridwellError **err);
// Validate: null on success, else an error listing every problem.
GridwellError *gridwell_validate(const GridwellTable *table);
// Render text (html, latex, typst, rtf, svg, ansi, pandoc, quarto).
// Both render functions validate first: invalid IR returns an empty result and an
// error with code GRIDWELL_ERR_VALIDATE whose message lists the validation errors.
GridwellTextResult gridwell_render_text(
const GridwellTable *table, const char *format, GridwellError **err);
// Render binary (docx, xlsx, pptx)
GridwellBinaryResult gridwell_render_binary(
const GridwellTable *table, const char *format, GridwellError **err);
// The same with writer options: a JSON object, or null for the defaults.
GridwellTextResult gridwell_render_text_with_options(
const GridwellTable *table, const char *format, const char *options,
GridwellError **err);
GridwellBinaryResult gridwell_render_binary_with_options(
const GridwellTable *table, const char *format, const char *options,
GridwellError **err);
// Formats: a static comma-separated list of names (do not free), and a name's kind
// (GRIDWELL_FORMAT_TEXT, GRIDWELL_FORMAT_BINARY or GRIDWELL_FORMAT_UNKNOWN).
const char *gridwell_format_names(void);
int32_t gridwell_format_kind(const char *format);
// Error inspection
const char *gridwell_error_message(const GridwellError *err); // valid until freed
int32_t gridwell_error_code(const GridwellError *err); // 0 if err is null
// Memory management (all accept null / failed results)
void gridwell_free_table(GridwellTable *table);
void gridwell_free_error(GridwellError *err);
void gridwell_free_text_result(GridwellTextResult result);
void gridwell_free_binary_result(GridwellBinaryResult result);Every err out-parameter may be null if you don’t need the error. Format names are case-insensitive. See Writer Options for each format’s options.
Example
#include "gridwell.h"
#include <stdio.h>
#include <string.h>
int main(void) {
const char *json = "{ ... }";
GridwellError *err = NULL;
GridwellTable *table = gridwell_parse_ir(json, strlen(json), &err);
if (!table) {
fprintf(stderr, "Parse error: %s\n", gridwell_error_message(err));
gridwell_free_error(err);
return 1;
}
GridwellTextResult result = gridwell_render_text(table, "html", &err);
if (result.text) {
printf("%.*s\n", (int)result.len, result.text);
gridwell_free_text_result(result);
}
gridwell_free_table(table);
return 0;
}Linking
Build the library with cargo build --release -p gridwell-ffi. That produces libgridwell_ffi.{so,dylib} and libgridwell_ffi.a in target/release/. Then:
cc -o myapp myapp.c -I crates/gridwell-ffi/include -L target/release -lgridwell_fficrates/gridwell-ffi/tests/c/smoke.c is a complete working example. The test suite compiles it as C99, as C++, and under AddressSanitizer.