ezffi 0.1.0

Generate C-FFI bindings from Rust types/functions via a single proc-macro attribute
//! Generate C-FFI bindings from Rust types and functions through a single
//! attribute, with no manual `#[repr(C)]` and no hand-written extern wrappers.
//!
//! ```ignore
//! #[ezffi::export]
//! pub fn add(a: u32, b: u32) -> u32 { a + b }
//! ```
//!
//! gives you, on the C side:
//!
//! ```c
//! uint32_t my_crate_add(uint32_t a, uint32_t b);
//! ```
//!
//! Pair with cbindgen for the header and you're done. The macro picks layout
//! (C-compatible by value vs opaque pointer) by reading the source, ships
//! pre-wrapped headers for `Option`, `Result`, `String`, slices, and (under
//! the `std` feature) `Vec`, `HashMap`, `Arc`, etc.
//!
//! **Full documentation lives in [The ezffi Book](https://zocolini.github.io/ezffi/)** —
//! configuration, supported type shapes, std prelude, cross-crate usage,
//! async dispatchers, and the design rationale.
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::wrong_self_convention)]

// Lets macro-generated code inside this crate (e.g. `export_extern_type!` in
// std_impls) refer to ezffi by name, so the macros can always emit `::ezffi::`
// regardless of whether they expand here or in a downstream crate.
extern crate self as ezffi;

pub use ezffi_macros::export;

#[cfg(feature = "async")]
mod async_rt;
#[cfg(feature = "_option_result")]
mod optres;
#[cfg(feature = "_slice")]
mod slice;
// Cannot be defined under a feature bcs cbindgen doesnt work properly,
// i really need my own solution
mod std_impls;
#[cfg(feature = "_string")]
mod string;

#[cfg(feature = "async")]
pub use async_rt::*;
#[cfg(feature = "_option_result")]
pub use optres::*;
#[cfg(feature = "_slice")]
pub use slice::*;
#[allow(unused_imports)]
pub use std_impls::*;
#[cfg(feature = "_string")]
pub use string::*;

/// One of the four conversion traits used by the C wrapper to translate
/// between Rust and C: C args → Rust call → Rust return → C return.
/// `RustRefIntoC` is the borrowed Rust→C half.
///
/// Derived by `#[ezffi::export]`; implement manually for full control
pub trait RustRefIntoC<T> {
    type C: CRefIntoRust<Self>;

    unsafe fn ref_into_c(&self) -> Self::C;
}

/// Owned Rust→C half of the conversion (see [`RustRefIntoC`]).
/// Ownership moves to C; free via the generated `_free` fn or by
/// consuming with [`COwnedIntoRust::into_rust_owned`].
///
/// Derived by `#[ezffi::export]`; implement manually for full control
pub trait RustOwnedIntoC<T>: Sized {
    type C: COwnedIntoRust<Self>;

    unsafe fn owned_into_c(self) -> Self::C;
}

/// Borrowed C→Rust half of the conversion (inverse of [`RustRefIntoC`]).
///
/// Derived by `#[ezffi::export]`; implement manually for full control
pub trait CRefIntoRust<T: ?Sized> {
    unsafe fn into_rust(&self) -> &T;
    unsafe fn into_rust_mut(&mut self) -> &mut T;
}

/// Owned C→Rust half of the conversion (inverse of [`RustOwnedIntoC`]).
///
/// Derived by `#[ezffi::export]`; implement manually for full control
pub trait COwnedIntoRust<T> {
    unsafe fn into_rust_owned(self) -> T;
}