eqswift 0.1.0

Zero-config Rust-to-Swift FFI — no UDL, no build.rs, just annotations
Documentation
//! eq-swift — Zero-config Rust-to-Swift FFI
//!
//! A thin, ergonomic wrapper around [UniFFI](https://github.com/mozilla/uniffi-rs)
//! that lets you write your entire foreign interface in Rust — no UDL files, no
//! `build.rs`, no `setup!()` call, no duplication.
//!
//! Just annotate your items with `#[eqswift::export]` or `#[derive(eqswift::Record)]`
//! and build. The first `#[eqswift::export]` automatically initializes UniFFI.
//!
//! # Quick Start
//!
//! ```ignore
//! #[eqswift::export]
//! pub fn add(a: u32, b: u32) -> u32 {
//!     a + b
//! }
//!
//! #[derive(eqswift::Record)]
//! pub struct Person {
//!     pub name: String,
//!     pub age: u32,
//! }
//!
//! #[derive(eqswift::Object)]
//! pub struct Greeter;
//!
//! #[eqswift::export]
//! impl Greeter {
//!     // Automatically detected as constructor — no attribute needed
//!     pub fn new() -> Self {
//!         Self
//!     }
//!
//!     pub fn greet(&self, name: String) -> String {
//!         format!("Hello, {name}!")
//!     }
//! }
//! ```
//!
//! Then build and generate Swift bindings:
//! ```bash
//! cargo build
//! cargo eqswift swift --out-dir eq-swift/swift/Generated
//! ```
//!
//! # Macros
//!
//! | Macro | Purpose |
//! |-------|---------|
//! | [`export`](eqswift_macros::export) | Mark a free function or `impl` block for export. Auto-initializes UniFFI on first use. |
//! | [`Record`](uniffi::Record) | Derive for plain data structs (Swift `struct`). |
//! | [`Object`](uniffi::Object) | Derive for reference types with methods (Swift `class`). |
//! | [`Enum`](uniffi::Enum) | Derive for enums. |
//! | [`Error`](uniffi::Error) | Derive for error enums. |
//! | [`setup!`](eqswift_macros::setup) | Explicit initialization (optional, see [`export`](eqswift_macros::export)). |
//!
//! # Supported Types
//!
//! Most Rust primitives map directly to Swift:
//!
//! | Rust | Swift |
//! |------|-------|
//! | `u32` | `UInt32` |
//! | `i32` | `Int32` |
//! | `f64` | `Double` |
//! | `bool` | `Bool` |
//! | `String` | `String` |
//! | `Vec<T>` | `[T]` |
//! | `Option<T>` | `T?` |
//! | `Result<T, E>` | `throws` |
//!
//! See the [UniFFI type docs](https://mozilla.github.io/uniffi-rs/latest/types/builtin_types.html)
//! for the complete list.

pub use eqswift_macros::{export, setup};

// Re-export UniFFI derives so users can write `#[derive(eqswift::Record)]` etc.
pub use uniffi::Record;
pub use uniffi::Object;
pub use uniffi::Enum;
pub use uniffi::Error;

// Allow using `eqswift::` paths inside this crate too.
extern crate self as eqswift;

// ---------------------------------------------------------------------------
// Example API (smoke test — these items are exported to Swift)
// ---------------------------------------------------------------------------

/// A simple data record exported to Swift as a `struct`.
#[derive(eqswift::Record)]
pub struct Person {
    pub name: String,
    pub age: u32,
}

/// An object exported to Swift as a `class` with methods.
#[derive(eqswift::Object)]
pub struct Greeter;

#[eqswift::export]
impl Greeter {
    /// Default constructor — auto-detected by eqswift.
    pub fn new() -> Self {
        Self
    }

    /// Greet someone by name.
    pub fn greet(&self, name: String) -> String {
        format!("Hello, {name}!")
    }

    /// Greet a [`Person`].
    pub fn greet_person(&self, person: Person) -> String {
        format!("Hello, {}! You are {} years old.", person.name, person.age)
    }
}

/// Add two numbers.
#[eqswift::export]
pub fn add(a: u32, b: u32) -> u32 {
    a + b
}

/// Return the crate version string.
#[eqswift::export]
pub fn version() -> String {
    env!("CARGO_PKG_VERSION").to_string()
}