Call Rust from Swift and vice versa.
swift-bridge
generates code that helps you call Swift from Rust and vice versa.
swift-bridge
takes inspiration from the bridge module idea pioneered by cxx.
```toml
[build-dependencies] swift-bridge-build = "0.1"
[dependencies] swift-bridge = "0.1" ```
Put the library out to get feedback from bleeding edge users.
Continue to support more standard library types.
Continue to hone the API based on real usage feedback.
Figure out the safety story. What should be marked as safe vs. unsafe?
Focus on making usage of swift-bridge feel ergonomic.
Polish the documentation, examples and tutorials
Get to a point where we feel that there has been enough, real world production use and feedback for us to be confident that the user-facing API's won't need any breaking changes.
Release swift-bridge version 1.0
TODO: Shorten this quick peak.. we don't need to include the build script, for example
Here's a quick peek at the Rust and Swift of a bridge that should give you a sense of how bindings look.
A more thorough walk through of swift-bridge
can be found in the book (TODO: Link to GitHub pages).
```rust // build.rs
fn main() { let bridges = vec!["src/lib.rs"];
let out_dir = "./generated";
swift_bridge_build::parse_bridges(&bridges)
.write_all_concatenated(out_dir);
for path in &bridges {
println!("cargo:rerun-if-changed={}", path);
}
} ```
```rust // lib.rs
mod ffi { extern "Rust" { type ARustStack;
fn push (&mut self, val: u8);
fn pop (&mut self) -> Option<u8>;
fn as_slice (&self) -> &[u8];
fn do_stuff(override: Option<u8>);
}
extern "Swift" {
type SwiftApiClient;
#[swift_bridge(init)]
fn new_with_timeout(timeout: u8) -> SwiftApiClient;
#[swift_bridge(associated_to = FileSystemClient)]
fn version () -> u32;
fn set_timeout(&self, timeout: u8);
}
}
struct ARustStack(Vec
impl ARustStack { fn push(&mut self, val: u8) { self.0.push(val); }
fn pop(&mut self) -> Option<u8> {
self.0.pop();
}
fn as_slice(&self) -> &[u8] {
self.0.pop();
}
}
fn dostuff(override: Option
let client = SwiftApiClient::new_with_timeout(10);
if let Some(override) = override {
client.setTimeout(20)
}
} ```
```swift // Swift
class SwiftApiClient { var timeout: UInt8
init(timeout: UInt8) {
self.timeout = timeout
}
class func version() -> u32 {
1
}
func setTimeout(timeout: UInt8) {
self.timeout = timeout
}
} ```
We don't need to solve all of these, but we should at least create issues
Look up how to programatically set the linking settings and programatically set the run script. Our docs can recommend that as well as show how to manually set them
Remove #[no_mangle]
since we're using linkname and exportname
Write instructions on going from 0 to most basic iOS app
Add book chapter on setting up iOS app from scratch
Create examples dir example of iOS app
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
Other places such as function arguments are not yet implemented.
Non primitive T is not yet implemented. |
| Result\
Open an issue! | | |
| | Have a Swift standard library type in mind?
Open an issue! | |
To run the test suite.
```sh
git clone git@github.com:chinedufn/swift-bridge.git cd swift-bridge
cargo test --all && ./test-integration.sh ```