swift-bridge
swift-bridge copied to clipboard
swift-bridge facilitates Rust and Swift interop.
swift-bridge

swift-bridgefacilitates Rust and Swift interop.
swift-bridge is a library that lets you pass and share high-level types such as Option<T>, String,
Structs and Classes between Rust and Swift.
It also lets you bridge higher level language features between Rust and Swift, such as async functions and generics.
Installation
# In your Cargo.toml
[build-dependencies]
swift-bridge-build = "0.1"
[dependencies]
swift-bridge = "0.1"
Book
You can find information about using Rust and Swift together in The swift-bridge Book.
Quick Peek
You use swift-bridge by declaring the types and functions that you want to import and export
in a "bridge module", and then annotating that bridge module with the #[swift_bridge::bridge]
macro.
Then, at build time, you use either the swift-bridge-build API or the swift-bridge-cli CLI to
parse your annotated bridge modules and generate the Swift and C side of the FFI layer.
Here's a quick peek at how you might describe an FFI boundary between Swift and Rust using a bridge module.
// Use the `swift_bridge::bridge` macro to declare a bridge module that
// `swift-bridge-build` will parse at build time in order to generate
// the necessary Swift and C FFI glue code.
#[swift_bridge::bridge]
mod ffi {
// Create shared structs where both Rust and Swift can directly access the fields.
struct AppConfig {
file_manager: CustomFileManager,
}
// Shared enums are also supported
enum UserLookup {
ById(UserId),
ByName(String),
}
// Export Rust types, functions and methods for Swift to use.
extern "Rust" {
type RustApp;
#[swift_bridge(init)]
fn new(config: AppConfig);
fn insert_user(&mut self, user_id: UserId, user: User);
fn get_user(&self, lookup: UserLookup) -> Option<&User>;
}
extern "Rust" {
type User;
#[swift_bridge(Copy(4))]
type UserId;
#[swift_bridge(init)]
fn new(user_id: UserId, name: String, email: Option<String>) -> User;
}
// Import Swift classes and functions for Rust to use.
extern "Swift" {
type CustomFileManager;
fn save_file(&self, name: &str, contents: &[u8]);
}
}
#[derive(Copy)]
struct UserId(u32);
Quick Start
The swift-bridge repository contains example applications that you use to quickly try out the library,
or as a starting point for your own Swift + Rust based application.
For example, here's how to run the codegen-visualizer example project locally.
git clone https://github.com/chinedufn/swift-bridge
cd swift-bridge/examples/codegen-visualizer
open CodegenVisualizer/CodegenVisualizer.xcodeproj
# *** Click the "Run" button at the top left of Xcode ***
You can find information about using Rust and Swift together in The swift-bridge Book.
Built-In Types
In addition to allowing you to share your own custom structs, enums and classes between Rust and Swift,
swift-bridge comes with support for a number of Rust and Swift standard library types.
| name in Rust | name in Swift | notes |
|---|---|---|
| u8, i8, u16, i16... etc | UInt8, Int8, UInt16, Int16 ... etc | |
| bool | Bool | |
| String, &String, &mut String | RustString, RustStringRef, RustStringRefMut | |
| &str | RustStr | |
| Vec<T> | RustVec<T> | |
| SwiftArray<T> | Array<T> | Not yet implemented |
| &[T] | Not yet implemented | |
| &mut [T] | Not yet implemented | |
| Box<T> | Not yet implemented | |
| [T; N] | Not yet implemented | |
| *const T | UnsafePointer<T> | |
| *mut T | UnsafeMutablePointer<T> | |
| Option<T> | Optional<T> | |
| Result<T> | Not yet implemented | |
| Have a Rust standard library type in mind? Open an issue! |
||
| Have a Swift standard library type in mind? Open an issue! |
To Test
To run the test suite.
# Clone the repository
git clone [email protected]:chinedufn/swift-bridge.git
cd swift-bridge
# Run tests
cargo test --all && ./test-integration.sh
License
Licensed under MIT or Apache-2.0.