swift-bridge 0.1.5

Generate FFI bindings for safe interop between Rust and Swift.
Documentation
# swift-bridge [![Actions Status]https://github.com/chinedufn/swift-bridge/workflows/test/badge.svg]https://github.com/chinedufn/swift-bridge/actions [![docs]https://docs.rs/swift-bridge/badge.svg]https://docs.rs/swift-bridge

> 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 awesome bridge module macro based approach pioneered by [cxx](https://github.com/dtolnay/cxx)._

## Installation

```toml
# In your Cargo.toml

[build-dependencies]
swift-bridge-build = "0.1"

[dependencies]
swift-bridge = "0.1"
```

## Phases

- 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

## Quick Peek

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

#[swift_bridge::bridge]
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<u8>);

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 do_stuff(override: Option<u8>) {
    assert_eq!(SwiftApiClient::version(), 1);

    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
	}
}
```

## TODO's before open sourcing

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 link_name and export_name

## Quick Peek


- 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
- Create examples dir example of macOS app

## 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<T>                                                          | RustVec\<T>                                                      |                                                                                                                                                                                     |
| SwiftArray\<T>                                                  | Array\<T>                                                        | Not yet implemented                                                                                                                                                                 |
| &[T]                                                            | UnsafeBufferPointer\<T>                                          |                                                                                                                                                                                     |
| &mut [T]                                                        | UnsafeMutableBufferPointer\<T>                                   | Not yet implemented                                                                                                                                                                 |
| SwiftString                                                     | String                                                           |                                                                                                                                                                                     |
| Box<T>                                                          |                                                                  | Not yet implemented                                                                                                                                                                 |
| [T; N]                                                          |                                                                  | Not yet implemented                                                                                                                                                                 |
| *const T                                                        | UnsafePointer\<T>                                                |                                                                                                                                                                                     |
| *mut T                                                          | UnsafeMutablePointer\<T>                                         |                                                                                                                                                                                     |
| Option\<T>                                                      | Optional\<T>                                                     | Currently only supported for primitive function return types.<br /> Other places such as function arguments are  not yet implemented.<br /> Non primitive T is not yet implemented. |
| Result\<T>                                                      |                                                                  | Not yet implemented                                                                                                                                                                 |
| Have a Rust standard library type in mind?<br /> Open an issue! |                                                                  |                                                                                                                                                                                     |
|                                                                 | Have a Swift standard library type in mind?<br /> Open an issue! |                                                                                                                                                                                     |

## To Test

To run the test suite.

```sh
# Clone the repository
git clone git@github.com:chinedufn/swift-bridge.git
cd swift-bridge

# Run tests
cargo test --all
```

## See Also

- [Rust on iOS]https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-06-rust-on-ios.html
  - A blog post by Mozilla that explains how to run Rust on iOS.