CO3
Safely export and/or import FFI bindings:
- Native-Rust ergonomics
- ergonomics of APIs and generated wrappers is idiomatic to Rust users.
- FFI boundary mechanics are zero-cost abstracted yet remain configurable.
- The syntax of exports and imports is completely interchangeable.
- Soundness-first FFI interoperability
- soundness is never weakened for the sake of performance or memory footprint in the default configuration.
- if preserving soundness requires additional validation, temporary storage, or cloning, that cost is accepted.
- only explicit opt-in modes prioritize performance by explicitly shifting soundness responsibility to the user.
Example
Using CO3 is super-duper simple yet highly expressive. In a nutshell:
- mark Rust types that cross the boundary with
#[derive(ReprC)] - describe the boundary API with
ffi!(fns, impls and types)
use ;
ffi!
Note that type deriving ReprC, although recommended, is not required to have a stable representation.
Tagged Dispatch
It is common in FFI for several concrete types to share one C representation. Think of FFI functions
like SQLAllocHandle
which works for different tag types
or SQLSetEnvAttr
where an attribute's concrete type determines the accepted value representation.
use ;
;
;
ffi!
ABI Stability
Although this crate is pre-1.0.0, its ABI is considered stable. This does not mean the API is stable. In practice:
- ABI stability means FFI contracts (symbol names, calling conventions, and data layout expectations) are intended to remain compatible across updates.
- API instability means Rust-facing items (fns, trait shapes, modules, and type signatures) may still change and require source updates when upgrading.
In other words, external binaries that integrate through the defined ABI should keep working, while Rust code using this crate directly may need refactoring between releases.