[package]
name = "cera-ffi"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
description = "UniFFI bindings for cera — exposes the core inference engine to Kotlin, Swift, Python, etc."

[lib]
# - `cdylib` for Android / Linux / macOS dynamic linking (UniFFI loadBundle at runtime).
# - `staticlib` for iOS (XCFramework static archive, Swift Package Manager).
# - `lib` stays so other Rust crates in the workspace (future parity
#   harness, examples) can depend on the crate as a normal library.
crate-type = ["lib", "cdylib", "staticlib"]

# Binding-generation binary. Runs `uniffi::uniffi_bindgen_main()` so the
# standard `uniffi-bindgen generate --library <dylib> --language <lang>`
# CLI is available in-repo. Invoked from `just bindings` + CI; see
# `cera-ffi/README.md`.
#
# `required-features = ["bindgen"]` is the load-bearing bit: it keeps
# the `uniffi/cli` dep (clap + friends) out of every cdylib / staticlib
# consumer's build. Mobile consumers (Android cdylib, iOS staticlib)
# never run the CLI; there's no reason to pull clap through their
# binary. `cargo run -p cera-ffi --bin uniffi-bindgen --features
# bindgen -- ...` is the full invocation. The justfile recipe +
# CI job both pass the flag.
[[bin]]
name = "uniffi-bindgen"
path = "src/bin/uniffi-bindgen.rs"
required-features = ["bindgen"]

[features]
# Opt-in crate feature that lights up the `uniffi/cli` feature. Only
# needed by the `uniffi-bindgen` binary target; library consumers
# (including the `cdylib` / `staticlib` targets used by mobile builds)
# don't need it and shouldn't pay for the extra dep cost.
bindgen = ["uniffi/cli"]

# Light up cera's Metal GPU backend in the built cdylib/staticlib. Only valid on
# Apple targets (the `metal` crate is macOS/iOS-only) — the Apple XCFramework
# slices (`just apple-xcframework`) build with `--features metal`; other targets
# must not enable it.
metal = ["cera/metal"]

# Opt-in feature for the Dart/Flutter bindings (cera-ffi-flutter). The Dart
# generator (uniffi-bindgen-dart) calls `uniffi_ffibuffer_*` trampolines —
# extra scaffolding functions that pass args/returns through an FfiBuffer —
# which UniFFI only emits under `scaffolding-ffi-buffer-fns`. Build the cdylib
# with `--features ffi-buffer` for Dart; Kotlin/Swift use the standard symbols
# and don't need it, so it stays off by default (extra symbols = larger lib).
ffi-buffer = ["uniffi/scaffolding-ffi-buffer-fns"]

[dependencies]
# `tokio` feature activates the `async_runtime = "tokio"` export path
# — required for the `async fn` methods on `Session` that offload the
# synchronous decode loop to a blocking worker.
uniffi = { workspace = true, features = ["tokio"] }
# `FfiError` derives `thiserror::Error` so `CeraError` messages can
# flow through the FFI boundary unchanged. Already a workspace dep.
thiserror.workspace = true
# Bulk little-endian reinterpret of `&[f32]` → bytes in `f32_vec_to_le_bytes`
# (hidden-states payloads) on LE hosts — one copy instead of per-element.
bytemuck.workspace = true
# Async runtime for `#[uniffi::export(async_runtime = "tokio")]`.
# `rt` for the runtime core, `rt-multi-thread` so `spawn_blocking`
# dispatches decode work onto a dedicated blocking worker thread
# instead of the runtime's async worker pool. `default-features = false`
# is currently a no-op (tokio 1.x defaults to empty) but makes the
# intent explicit and defends against a future tokio adding defaults.
tokio = { version = "1", default-features = false, features = ["rt", "rt-multi-thread"] }
# cera: default features + `remote` for the `BundleRepo` surface
# exposed to foreign callers in PR 10. `remote` pulls `reqwest` +
# `sha2` + `std-fs` — the downloader + per-file SHA-256 verifier.
# Default features (`parallel`, `mmap`, `std-fs`, `disk-cache`) stay
# on; `CeraEngine::from_bundle_id` requires both `remote` and `mmap`.
cera = { path = "../cera", version = "0.2.6", features = ["remote"] }

[dev-dependencies]
# Full tokio feature set for `#[tokio::test]` so the async unit tests
# get a runtime + macro expansion. Kept dev-only — non-test builds
# stay minimal.
tokio = { version = "1", features = ["full"] }

# No `[build-dependencies]` block: the proc-macro path doesn't need
# UDL-scaffolding generation at build time, so `uniffi = { features =
# ["build"] }` as a build-dep would compile UniFFI twice for no gain.
# If/when we migrate to UDL, add `uniffi = { workspace = true,
# features = ["build"] }` here and call `uniffi::generate_scaffolding`
# from `build.rs`.
