swift-bridge
Call Rust from Swift and vice versa.
swift-bridge
generates code that helps you call Rust from Swift and vice versa.
swift-bridge
takes inspiration from the bridge module idea pioneered by cxx.
Current Status
swift-bridge
works, but there are still some edge cases where it's easy to make a mistake if you don't know about that. All of them are addressable.
So, swift-bridge
is not yet production ready.
Right now I'm looking for feedback from bleeding-edge users in order to continue to improve the APIs and the generated code.
I can especially use feedback from people with Swift experience, since I don't have much.
I'm using swift-bridge
to ship an application that has extreme reliability requirements, so you can rest assured that the core maintaners have a vested interest in addressing your feedback.
The 0.1.x
versions will not follow semver.
We'll maintain semver from 0.2
and onwards.
Installation
# In your Cargo.toml
[build-dependencies]
swift-bridge-build = "0.1"
[dependencies]
swift-bridge = "0.1"
Resources
Quick Peek
Here's a quick peek at how defining FFI bindings looks.
A more thorough walk through of swift-bridge
can be found in the book.
// lib.rs
#[swift_bridge::bridge]
mod ffi {
// Shared types
#[swift_bridge(swift_repr = "struct")]
struct ASharedStruct {
field: u32
}
// Exposes super::ARustStack to Swift.
extern "Rust" {
type ARustStack;
fn push (&mut self, val: String);
fn pop (&mut self) -> Option<String>;
fn as_slice (&self) -> &[String];
}
extern "Rust" {
fn do_stuff(a: &mut SomeType, b: AnotherType) -> Vec<ARustStack>;
}
extern "Rust" {
type SomeType;
type AnotherType;
}
// Exposes a Swift `class SwiftApiClient` to Rust.
extern "Swift" {
type SwiftApiClient;
#[swift_bridge(init)]
fn new_with_timeout(timeout: u8) -> SwiftApiClient;
#[swift_bridge(associated_to = SwiftApiClient)]
fn version () -> String;
fn post_bytes(&self, bytes: &[u8]);
}
}
Known issues
TODO... make GitHub issues for these..
- Fix bug where we can define an extern "Rust"
fn foo () -> SomeType
even though the real definition isfn foo () -> &SomeType {}
Built-In Types
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 | |
&str | RustStr | |
Vec | RustVec<T> | |
SwiftArray<T> | Array<T> | Not yet implemented |
&[T] | UnsafeBufferPointer<T> | |
&mut [T] | UnsafeMutableBufferPointer<T> | Not yet implemented |
SwiftString | String | |
Box | Not yet implemented | |
[T; N] | Not yet implemented | |
*const T | UnsafePointer<T> | |
*mut T | UnsafeMutablePointer<T> | |
Option<T> | Optional<T> | Currently only supports function return types that are primitive (i.e. -> Option<i32> ), or -> Option<String> ..More support will come. Other places such as function arguments are not yet implemented but will come. |
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
See Also
- Rust on iOS
- A blog post by Mozilla that explains how to run Rust on iOS.