Splits the Rust codegen the way C++ is split: rename `rust.nim` -> `rust_cbor.nim` (CBOR) and add `rust_native.nim` (native). Dispatch on `targetLang=rust` now honours `-d:ffiMode` (native/cbor); the crates share file names so each mode writes its own dir (rust_bindings vs rust_native_bindings). `rust_native.nim` emits a `<lib>_native` crate — the Rust analogue of `cpp_native`: `#[repr(C)]` POD mirrors + `extern "C"` native entry points (ffi.rs); idiomatic structs with `to_c`/`from_c`, a holder owning the CStrings for the call (types.rs); and a `<Lib>Node` whose methods marshal typed args in / read typed struct returns out, blocking via std mpsc (api.rs). First cut: scalar/string/bool/float/nested-struct fields (create/version/echo); seq/Option params are SKIPPED, native events next. Verified end-to-end — the generated crate builds and the demo round-trips a typed EchoResponse. Tasks: genbindings_rust (CBOR), genbindings_rust_native. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
timer example
This example is a self-contained Nimble project demonstrating how to import nim-ffi and use the .ffiCtor. / .ffi. abstraction.
Two ABIs, one library
Every generated library exports two ABIs side by side, and you choose per call site:
| ABI | Header / symbols | Use it for |
|---|---|---|
| Native (pure C) | <lib>.h / <name> |
Same-process / local calls. Flat C structs by value, zero serialization. |
| CBOR | <lib>_cbor.h / <name>_cbor |
Inter-process communication only — a different process or machine, where the request must be serialized to cross the boundary. |
In a shared address space the CBOR round-trip is pure overhead, so default to the native ABI locally and reach for CBOR only when you actually cross a process/machine boundary (see ipc/). The per-language examples below: native C (c_bindings/), native Go (go_bindings/), native/CBOR C++ (cpp_bindings/), CBOR Rust (rust_client/), and CBOR-over-socket IPC (ipc/).
Usage
-
Change into the example directory:
cd examples/timer -
Install the local
ffidependency:nimble install -y ../.. -
Build the example library:
nimble build -
Generate bindings:
nimble genbindings_rust nimble genbindings_cpp
Rust example clients
The Rust client lives in examples/timer/rust_client.
-
Run the sync example:
cd examples/timer/rust_client cargo run --bin rust_client -
Run the Tokio example:
cd examples/timer/rust_client cargo run --bin tokio_client
C++ example
The generated C++ example lives in examples/timer/cpp_bindings.
Build and run it with:
cd examples/timer/cpp_bindings
cmake -S . -B build
cmake --build build
./build/example