Files
calctext/_bmad-output/implementation-artifacts/1-5-c-ffi-layer-for-swift.md
2026-03-16 19:54:53 -04:00

2.0 KiB

epic, story, title, status
epic story title status
1 1.5 C FFI Layer (for Swift) draft

Epic 1 — Core Calculation Engine (Rust Crate)

Goal: Build calcpad-engine as a standalone Rust crate that powers all platforms. This is the foundation.

Story 1.5: C FFI Layer (for Swift)

As a macOS/iOS developer integrating CalcPad, I want a stable C ABI with explicit memory ownership and no panics crossing the FFI boundary, So that Swift can safely call into the Rust engine without undefined behavior.

Acceptance Criteria:

Given a Swift caller invoking calcpad_eval_line with a C string input When the function executes Then it returns a pointer to a CalcResult struct (or JSON-serialized string) allocated on the Rust heap And the caller is responsible for freeing the result via calcpad_free_result

Given a Swift caller invoking calcpad_eval_sheet with multiple lines When the function executes Then it returns an array of results corresponding to each line And variable assignments on earlier lines are visible to later lines

Given an expression that would cause a Rust panic (e.g., internal bug) When the FFI function is called Then catch_unwind intercepts the panic And an error result is returned instead of unwinding into Swift

Given the FFI result is serialized as JSON When the result crosses the FFI boundary Then the JSON schema is versioned so Swift can handle backward-compatible changes And the JSON includes result type, display value, raw value, and any error information

Given a CalcResult pointer returned from calcpad_eval_line When the Swift caller calls calcpad_free_result with that pointer Then the Rust allocator deallocates the memory And no double-free or use-after-free is possible from correct usage

Given a null or invalid pointer passed to calcpad_free_result When the function is called Then it safely handles the null/invalid input without crashing And no undefined behavior occurs