Call Rust from Swift and vice versa.

Overview

swift-bridge Actions Status docs

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 is fn 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.
Comments
  • Add documentation on creating a Swift Package

    Add documentation on creating a Swift Package

    Hi, I'm the one who asked about using Rust in Swift on Reddit.

    I've made a Gist that follows your steps, but slightly modified to set up a Swift project with Swift Package Manager (https://gist.github.com/Jomy10/a4873dd43942ed1bf54d387dbc888795).

    I've tried to add dependencies to Package.swift, but I don't know how to include them in the compiling process. Swiftc documentation seems to be rather scarce.

    Here's an example of the Package.swift file:

    // swift-tools-version:5.5
    import PackageDescription
    
    let package = Package(
        name: "swift",
        dependencies: [
            .package(url: "/path/to/HelloSwift", .branch("master"))
        ],
        targets: [
            .target(
                name: "swift",
                dependencies: [
                    .product(name: "HelloSwift", package: "HelloSwift")
                ]),
            .testTarget(
                name: "swiftTests",
                dependencies: ["swift"]),
        ]
    )
    

    Folder structure is also in the gist.

    I think it would be great if we could also use Swift Package Manager in the Swift project using the Rust library. Or maybe import the Rust library as a package in Package.Swift.

    opened by Jomy10 18
  • Generate Swift Package

    Generate Swift Package

    I have added support for generating Swift Packages.

    The generate_package function inside of package.rs creates a package containing the xcframework needed.

    The GeneratePackageConfig has 4 fields:

    • bridge_dir: the directory containing the generated bridge files
    • paths: the path to the compiled rust library and its platform. I have made the ApplePlatform enum follow the naming conventions of Apple. Let me know if you would rather have Rust naming conventions for this.
    • out_dir: the output directory for th swift package
    • package_name: the name for the Swift Package

    I have added a test that generates a Swift Pacakage and tests that it executes and the output is correct.

    opened by Jomy10 14
  • Swiftc flags in Swift Package?

    Swiftc flags in Swift Package?

    I was wondering if we could replace this command:

    swiftc -L target/x86_64-apple-darwin/debug/ -lswift_and_rust -import-objc-header bridging-header.h \
      main.swift lib.swift ./generated/swift-and-rust/swift-and-rust.swift
    

    with swift build


    I have tried the following in Package.swift

    // swift-tools-version:5.5
    
    import PackageDescription
    
    let package = Package(
        name: "LinuxSwiftPackage",
        dependencies: [],
        targets: [
            .executableTarget(
                name: "LinuxSwiftPackage",
                dependencies: [],
                linkerSettings: [
                    .unsafeFlags(["-L lib_mac", "-lmy_rust_lib", "-import-objc-header bridging-header.h"])
                ]
            )
        ]
    )
    

    It didn't seem to work, though.

    All settings can be found in the Apple documentation, there is CSettings, SwiftSettings, LinkerSettings, ...

    These are all things we can specify in the Package.swift.

    here you can also find some information under "Settings".


    It looks like you can also specify a json file using swift build --destination file.json. This also looks like a promising option.

    I tried swift build --destination file.json

    // file.json
    {
        "version": 1,
        "sdk": "/swift/usr/bin/swift",
        "toolchain-bin-dir": "/swift/usr/bin",
        "target": "x86_64-apple-macosx",
        "dynamic-library-extension": "lib",
        "extra-cc-flags": [
        ],
        "extra-swiftc-flags": [
            "-L lib_mac",
            "-lmy_rust_lib",
            "-import-objc-header",
            "bridging-header.h"
        ],
        "extra-cpp-flags": []
    }
    

    but I'm getting

    error: no such module 'Foundation'
    import Foundation
    

    This would allow us to link our library more easily in executable Swift packages, which I think would be useful for Linux as an alternative for generating a Swift Package.

    I can't seem to find any more information on this and I'm not really knowledgeable in linking header files.

    opened by Jomy10 13
  • Building Swift Packages

    Building Swift Packages

    I'll leave some of my thoughts here after writing that book chapter on how we should implement the build process for Swift packages into swift-bridge.

    We'll probably want an extra option in build.rs to generate a Swift package, maybe something like:

    swift_bridge_build::parse_bridges(bridges)
            .write_all_concatenated(out_dir, env!("CARGO_PKG_NAME"))
            .generate_package();
    

    For generating the xcframework, we could either use the xcodebuild command, or we could write the .plist file manually, which I think could be a good option.

    I think all of the other steps should be pretty straight forward, following the chapter of the book.

    opened by Jomy10 13
  • Are generics possible?

    Are generics possible?

    I have the following struct type defined currently APIResponseObject<T, MT>, where both T and MT are supposed to be deserialized by Rust.

    For some reason, if I try to extern them, I get a weird error, probably because generics (e.g. MyStruct<T>) aren't implemented for the bridge yet?

    Following code is my bridge:

    #[swift_bridge::bridge]
    mod ffi {
        // inferred from https://chinedufn.github.io/swift-bridge/bridge-module/opaque-types/index.html
        extern "Rust" {
            type APIResponseList<T, MT>;
            type PteroClientServer;
            type APIResponsePaginationMetaData;
            type APIResponseObject<T, MT>;
        }
    
        extern "Rust" {
            type PteroClient;
    
            #[swift_bridge(init)]
            fn new(base_url: String, api_key: String) -> PteroClient;
    
            // inferred from https://github.com/chinedufn/swift-bridge/blob/ecc6704985ea260ae502d7ccdd776602e5f263ea/examples/async-functions/src/lib.rs
            async fn get_servers(&self) -> Option<APIResponseList<APIResponseObject<PteroClientServer, APIResponsePaginationMetaData>, APIResponsePaginationMetaData>>;
        }
    }
    

    The error I receive:

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("expected `,`")', /home/cozygalvinism/.cargo/registry/src/github.com-1ecc6299db9ec823/swift-bridge-ir-0.1.29/src/bridged_type.rs:335:82
    

    Am I doing something wrong or is my assumption correct?

    opened by cozyGalvinism 11
  • Support `swift_name` attribute on extern

    Support `swift_name` attribute on extern "Swift" functions.

    Hi! First - thank you for this project! I have successfully called Rust code from Swift!

    Unfortunately, I am having some troubles, and I can't figure out how to fix them.

    I want to call a Swift function from Rust, but the generated swift code has a compiler error in it.

    This is the rust code (snippet)

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            // Works, except the function is still called rust_init on the Swift side?
            #[swift_bridge(swift_name = "rustInit")]
            fn init(url: String);
        }
    
        extern "Swift" {
            // Generates a Swift compiler error
            #[swift_bridge(swift_name = "getAuthToken")]
            fn get_authentication_token() -> String;
        }
    }
    

    This snippet is generated

    @_cdecl("__swift_bridge__$get_authentication_token")
    func __swift_bridge__get_authentication_token () -> RustString {
        { let rustString = getAuthToken().intoRustString(); rustString.isOwned = false; return rustString.ptr }()
    }
    

    And then I added this function (in the Swift package, as a new file)

    public func getAuthToken() -> String {
        return "token"
    }
    

    But the generated snippet has these compiler errors:

    • Method cannot be marked @_cdecl because its result type cannot be represented in Objective-C
    • Cannot convert return expression of type 'UnsafeMutableRawPointer' to return type 'RustString'

    An additional, minor, problem is that #[swift_bridge(swift_name = "rustInit")] doesn't seem to do anything.

    What am I doing wrong? Thanks.

    good first issue 
    opened by bes 10
  • Current version usable on M1?

    Current version usable on M1?

    I've tried both the book example + running the tests and both fail ("error[E0658]: destructuring assignments are unstable" and "panic in main thread" respectively). Do I need nightly compiler?

    I can follow up with stack traces/needed info, if someone could confirm it's buildable/usable. I really like the idea of this crate, so hoping to succeed

    opened by Maxung 9
  • Support parameters for async functions and async methods

    Support parameters for async functions and async methods

    Thanks for this crate! I'm looking into using librespot with Swift, but can't seem to have async methods or async functions with parameters.

    async method

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            type SpotifyApp;
    
            async fn connect(&mut self);
        }
    }
    
    pub struct SpotifyApp {}
    
    impl SpotifyApp {
        pub async fn connect(&mut self) {
            print!("Connecting to Spotify...");
        }
    }
    
    error[E0425]: cannot find value `this` in this scope
     --> src/lib.rs:6:1
      |
    6 | #[swift_bridge::bridge]
      | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
      |
      = note: this error originates in the attribute macro `swift_bridge::bridge`
    

    async function with parameters

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            type SpotifyApp;
    
            async fn connect(track_id: &str);
        }
    }
    
    pub struct SpotifyApp {}
    
    pub async fn connect(track_id: &str) {
        print!("Connecting to Spotify... {track_id}");
    }
    
    error[E0425]: cannot find value `track_id` in this scope
      --> src/lib.rs:11:26
       |
    11 |         async fn connect(track_id: &str);
       |                          ^^^^^^^^ not found in this scope
    

    Without one of these, I'm unable to pass data from the Swift app to Rust within async functions, do you think it is possible to have async methods or async functions with parameters? Thank you again :)

    opened by BenJeau 7
  • Add support for Result<T, E>

    Add support for Result

    This commit adds support for passing a Result<T, E> as an argument from Rust -> Swift.

    For example, the following is not possible:

    use some_crate::SomeRustType;
    
    #[swift_bridge::bridge]
    mod ffi {
        extern "Swift" {
            fn swift_func_takes_callback(
                arg: Box<dyn FnOnce(Result<SomeRustType, String>)>,
            );
        }
    
        extern "Rust" {
            type SomeRustType;
    
            #[swift_bridge::init]
            fn new () -> SomeRustType;
        }
    }
    
    opened by chinedufn 4
  • Running Swift From Rust

    Running Swift From Rust

    This could just me missing some basic things, but I wasn't able to find in the book how to compile swift code to link and use in Rust. The book seems to focus heavily on calling Rust FROM Swift but not the other way around.

    I'm currently going down the route to use a Swift Package (code is here https://github.com/lorenzolewis/tauri-ffi/tree/main/examples/swift-bridge/src-swift) to hold my Swift code. I don't see anything in the docs on how you're supposed to annotate Swift code to be exposed to Rust so I'm annotating functions with _cdecl which I've used from another implementation to text.

    On the Rust side I'm using Tauri and have the Rust code here https://github.com/lorenzolewis/tauri-ffi/tree/main/examples/swift-bridge/src-tauri.

    I'm assuming there's some sort of build/compile step I'm missing with Swift to generate the needed header files that I may have just missed in the docs?

    opened by lorenzolewis 4
  • swift bridge test suite fails to compile

    swift bridge test suite fails to compile

    To reproduce:

    1. clone swift-bridge
    2. git checkout 1951b4a262719c68590b635358677d1416248b58
    3. cargo test --all && ./test-integration.sh
       Compiling hir_def v0.0.0 (https://github.com/rust-analyzer/rust-analyzer#c6995a37)
    error[E0308]: mismatched types
      --> /Users/holliday/.cargo/git/checkouts/rust-analyzer-5e0f1308176aaeda/c6995a3/crates/hir_def/src/intern.rs:62:25
       |
    62 |             None => Err(shard),
       |                         ^^^^^ expected struct `parking_lot::RawRwLock`, found struct `dashmap::RawRwLock`
       |
       = note: expected struct `lock_api::RwLockWriteGuard<'_, parking_lot::RawRwLock, HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>`
                  found struct `lock_api::RwLockWriteGuard<'_, dashmap::RawRwLock, hashbrown::map::HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>`
    
    rustc 1.60.0 (7737e0b5c 2022-04-04)
    cargo 1.60.0 (d1fd9fe2c 2022-03-01)
    macOS 12.3.1 (21E258)
    Xcode  13.3.1 (13E500a)
    
    opened by wtholliday 4
  • Support: Option to convert snake case to camel case for Swift

    Support: Option to convert snake case to camel case for Swift

    New Feature

    //Rust side 
    
    extern "Rust" {
        fn get_value()->i16;
    }
    
    //build.rs
    
    use std::path::PathBuf;
    
    fn main() {
        let out_dir = PathBuf::from("./generated");
    
        let bridges = vec!["src/lib.rs"];
        for path in &bridges {
            println!("cargo:rerun-if-changed={}", path);
        }
        
        let support_camel_case = true  // option to convert snake case to camel case
    
        swift_bridge_build::parse_bridges(bridges, support_camel_case)
            .write_all_concatenated(out_dir, env!("CARGO_PKG_NAME"));
    }
    
    
    //Swift side 
    
    let value = getValue()
    
    

    Why

    the Swift API Design Guidelines recommend using camel case.

    opened by NiwakaDev 0
  • Document how to add Swift files to a generated Swift Package

    Document how to add Swift files to a generated Swift Package

    I would like to read some documentation on what you think the best place for auxillary Swift files for the generated Swift Package is.

    Might it be

    • In the directory of the "target Swift Package" itself (could be another folder / git)?
    • In some directory in the "source crate" using swift-bridge?
    • Some other place
    • Undefined

    Is there some automatic facility for copying Swift files already in place?

    opened by bes 0
  • Add support for async functions returning opaque types

    Add support for async functions returning opaque types

    I've got a quite complicated type I'm sharing via the swift bridge interface. I'm using an opaque type, but I want to use the async function bridge and it looks like thats not supported:

       Compiling dt-swift v0.1.0 (/Users/seph/src/diamond-types/crates/dt-swift)
    error: failed to run custom build command for `dt-swift v0.1.0 (/Users/seph/src/diamond-types/crates/dt-swift)`
    
    Caused by:
      process didn't exit successfully: `/Users/seph/src/diamond-types/target/release/build/dt-swift-82fb4d8c023013ad/build-script-build` (exit status: 101)
      --- stdout
      cargo:rerun-if-changed=src/lib.rs
    
      --- stderr
      thread 'main' panicked at 'not implemented', /Users/seph/.cargo/registry/src/github.com-1ecc6299db9ec823/swift-bridge-ir-0.1.41/src/bridged_type/bridged_opaque_type.rs:71:21
    

    The code for async functions in opaque types is unimplemented:

                    TypePosition::SwiftCallsRustAsyncOnCompleteReturnTy => {
                        unimplemented!()
                    }
    
    • What is needed to add support here?
    • Are there any workarounds? Can I have a bridged struct with an opaque reference or something?
    opened by josephg 1
  • Calling `tokio::runtime::Handle::current()` within non-async function panics

    Calling `tokio::runtime::Handle::current()` within non-async function panics

    A library I'm using calls tokio::runtime::Handle::current() in a non-async function and calling this results in a panic there is no reactor running, must be called from the context of a Tokio 1.x runtime. Presumably that context is only running when the function is async. Unsure if this is an issue with that library (i.e. you shouldn't call that) or there's an issue on this side of the fence.

    I do need to call that function in my initialisation though, and making that an init function async results in a not implemented panic on matching TypePosition::SwiftCallsRustAsyncOnCompleteReturnTy within bridged_type/bridged_opaque_type.rs:71:21.

    Any suggestions as to the best ways to work around these?

    opened by oeed 3
  • Binding more complicated swift classes to use in rust

    Binding more complicated swift classes to use in rust

    I appreciate the example showing how to link swift into rust, but I think the examples are all pretty simple swift. I'm trying to use this library to write bindings for an Apple framework, so the swift classes involved a bit more complex.

    For instance if I have nested swift structs/classes like

    class Foo {
      var x : Int
    
      init(x : Int) {
        self.x = x
      }
    
      struct Bar {
        var y: Int
      }
    
      func baz(bar: Bar) -> Int {
        return x + bar.y
      }
    }
    

    and I want to do something like

    let foo = Foo(x: 1)
    let bar = Foo.Bar(y: 2)
    print("baz: \(foo.baz(bar: bar))")
    

    but from rust, how would I write the bindings?

    Also, some swift libraries have vars that I might want to access from rust. Is it possible to write bindings to do this?

    opened by ericmarkmartin 0
  • Use cargo-xcode instead of cargo-lipo for XCode setup tutorial

    Use cargo-xcode instead of cargo-lipo for XCode setup tutorial

    Since cargo-lipo is considered deprecated by its developer, the tutorial for setting up swift-bridge in an xcode project should use a properly maintained alternative instead. cargo-xcode seems to be a promising alternative since it also does some of the required XCode project configuration and therefore eliminates the need for additional setup/build scripts (build.rs is still necessary but minimal).

    I was able to set up and built a project using swift-bridge + cargo-xcode with the Apple Multiplatform target, so I could do a draft for the revised tutorial section if wanted.

    opened by antoniusnaumann 5
Releases(0.1.44)
  • 0.1.44(Dec 15, 2022)

    • Make enums support the swift_name attribute. #126

      	// For example, the following is now possible:
      
      #[swift_bridge::bridge]
      mod ffi {
          #[swift_bridge(swift_name = "EnumRename")]
          enum EnumName {
              Variant1,
              Variant2,
          }
      }
      
    • Fix using the return_into attribute an already declared enum. [#125]

      	// For example, the following is now possible:
      
      #[swift_bridge::bridge]
      mod ffi {
          #[swift_bridge(already_declared)]
          enum SomeEnum {}
      
          extern "Rust" {
              #[swift_bridge(return_into)]
              fn return_into_already_declared() -> SomeEnum;
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.43(Dec 15, 2022)

    • Show a spanned compile time error for invalid module items. #124

      #[swift_bridge::bridge]
      mod ffi {
          use std;
          fn foo() {}
      }
      
      // error: Only `extern` blocks, structs and enums are supported.
      //  --> tests/ui/invalid-module-item.rs:6:5
      //   |
      // 3 |     use std;
      //   |     ^^^^^^^^
      //
      // error: Only `extern` blocks, structs and enums are supported.
      //  --> tests/ui/invalid-module-item.rs:7:5
      //   |
      // 4 |     fn foo() {}
      //   |     ^^^^^^^^^^^
      
    • Allow enums to use the #[already_declared] attribute. #125

      	// For example, the following is now possible:
      
      use some_other_bridge_module::SomeEnum;
      
      #[swift_bridge::bridge]
      mod ffi {
          #[swift_bridge(already_declared)]
          enum SomeEnum {}
      
          extern "Rust" {
              fn print(val: SomeEnum);
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.42(Dec 15, 2022)

    • Support returning String from Swift -> Rust #123 (thanks @bes)
      // For example, the following is now possible:
      
      #[swift_bridge::bridge]
      mod foo {
          extern "Swift" {
              fn some_function () -> String;
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.41(Oct 28, 2022)

    • Support Vec<TransparentEnum> #117
      // For example, the following is now possible:
      
      #[swift_bridge::bridge]
      mod ffi {
          enum SomeEnum {
              VariantA,
              VariantB,
          }
      
          extern "Rust" {
              fn some_function(arg: Vec<SomeEnum>) -> Vec<SomeEnum>;
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.40(Oct 3, 2022)

    • Support opaque Swift types in results #115
      // For example, the following is now possible:
      
      #[swift_bridge::bridge]
      mod ffi {
          extern "Swift" {
              type SomeSwiftType;
      
              fn some_function(arg: Result<(), SomeSwiftType>);
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.39(Oct 2, 2022)

    • Fix compile time error from trailing commas after a boxed FnOnce #113
      // For example, the following is now possible:
      
      #[swift_bridge::bridge]
      mod ffi {
          extern "Swift" {
              fn swift_func_takes_callback(
                  // Note the trailing comma after the `FnOnce(..)`
                  arg: Box<dyn FnOnce(Result<SomeRustType, String>), >
              );
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.38(Sep 20, 2022)

    • Add support for Result<T, E> #111
      // For example, the following is now possible:
      
      use some_crate::SomeRustType;
      
      #[swift_bridge::bridge]
      mod ffi {
          extern "Swift" {
              fn swift_func_takes_callback(
                  arg: Box<dyn FnOnce(Result<SomeRustType, String>)>,
              );
          }
      
          extern "Rust" {
              type SomeRustType;
      
              #[swift_bridge::init]
              fn new () -> SomeRustType;
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.37(Sep 15, 2022)

    • Support passing callbacks from Rust -> Swift #110
      // For example, the following is now possible:
      #[swift_bridge::bridge]
      mod ffi {
          extern "Swift" {
              type StripeTerminalSingleton;
      
              #[swift_bridge(init)]
              fn new() -> StripeTerminalSingleton;
      
              fn retrieve_payment_intent(
                  &self,
                  client_secret: &str,
                  callback: Box<dyn FnOnce(Result<PaymentIntentWrapper, String>)>,
              );
      
              fn collect_payment_method(
                  &self,
                  payment_intent: PaymentIntentWrapper,
                  callback: Box<dyn FnOnce(Result<PaymentIntentWrapper, String>)>,
              );
      
              fn process_payment(
                  &self,
                  payment_intent: PaymentIntentWrapper,
                  callback: Box<dyn FnOnce(Result<PaymentIntentWrapper, ProcessPaymentError)>,
              );
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.36(Aug 23, 2022)

    • Support returning opaque Swift types from Swift -> Rust #109
      // For example, the following is now possible:
      #[swift_bridge::bridge]
      mod ffi {
          extern "Swift" {
              type SomeType;
      
              fn some_function(arg: SomeType) -> SomeType;
              fn some_method(&self, arg: SomeType) -> SomeType;
          }
      }
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.35(Jul 27, 2022)

  • 0.1.34(Jun 6, 2022)

  • 0.1.33(May 10, 2022)

    This release brings support for bridging Rust generic types such as SomeType<String, u32>, as well as a couple new function attributes that make certain use cases a bit more ergonomic.

    For example, the following is now possible:

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            // Declare the generic type once.
            #[swift_bridge(declare_generic)]
            type MyType<A, B>;
        }
    
        extern "Rust" {
            // Bridge as many monomorphic types as you like.
            type MyType<u32, String>;
            fn some_function(arg: MyType<u32, String>) -> &str;
    
            type MyType<i8, Vec<u8>>;
        }
    }
    
    pub struct MyType<T, U> {
        my_field1: T,
        my_field2: U
    }
    fn some_function(arg: MyType<u32, String>) -> &str {
        unimplemented!()
    }
    
    • Support bridging generic opaque Rust types such as MyType<u32> #81

    • Support Option generic opaque Rust types such as Option<MyType<u32>> #87

    • Support bridging generic opaque Rust Copy types such as chrono::DateTime<Utc> #84

    • Support Option opaque Rust copy types such as Option<MyCopyType> #85

    • Introduce get and get_with attributes to directly access a field without going through a function #82

    • Better compile time errors for unrecognized attributes #83

    • Deprecate into_return_type attribute in favor of return_into #73 #95 (thanks @pouria-007)

    Source code(tar.gz)
    Source code(zip)
  • 0.1.32(Apr 24, 2022)

    • Introduce the #[swift_bridge(Copy)] attribute for efficiently passing opaque Copy types between Rust and Swift #63
      #[swift_bridge::bridge]
      mod ffi {
          extern "Rust" {
              #[swift_bridge(Copy(16))]
              type UserId;
      
              #[swift_bridge(Copy(16))]
              type OrganizationId;
          }
      }
      
      #[derive(Copy, Clone)]
      struct UserId(uuid::Uuid);
      
      #[derive(Copy, Clone)]
      struct OrganizationId(uuid::Uuid);
      
    Source code(tar.gz)
    Source code(zip)
  • 0.1.31(Apr 21, 2022)

  • 0.1.30(Apr 20, 2022)

  • 0.1.29(Mar 12, 2022)

    • Add swift_bridge_build::create_package API for creating a Swift Package from a Rust library #36 (Thanks @Jomy10)

    • Add swift-bridge create-package CLI command for creating a Swift Package from a Rust library #38 (Thanks @Jomy10)

    • Update the Swift Package book chapter with the new API and CLI command for creating swift packages (Thanks @Jomy10)

    Source code(tar.gz)
    Source code(zip)
  • 0.1.28(Feb 17, 2022)

  • 0.1.27(Feb 9, 2022)

    This release starts adding support for defining and passing enums between Swift and Rust. Enums where variants have data are not yet supported, but will be in a future release.

    • Add support for defining shared enums #27

    • Add support for passing shared enums across the FFI boundary #28

    • Add support for passing Option<Shared Enum> across the FFI boundary #29

    Source code(tar.gz)
    Source code(zip)
  • 0.1.26(Feb 2, 2022)

    • Add support for Option<T> shared struct fields #24

    For example, the following is now possible:

    #[swift_bridge::bridge]
    mod ffi {
        #[swift_bridge(swift_repr = "struct")]
        struct SomeStruct {
            field: Option<u8>,
            another_field: Option<f32>,
        }
    }
    
    • Add a return_with = path::to::function attribute #25

    For example, the following is now possible:

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            #[swift_bridge(return_with = some_module::convert_str_to_u32)]
            fn get_str_value_return_with() -> u32;
        }
    }
    
    fn get_str_value_return_with() -> &'static str {
        "123"
    }
    
    mod some_module {
        pub fn convert_str_to_u32(val: &str) -> u32 {
            val.parse().unwrap()
        }
    }
    
    Source code(tar.gz)
    Source code(zip)
  • 0.1.25(Jan 28, 2022)

    • Add attribute for auto-implementing the Swift Identifiable protocol #21

    This release introduces the #[swift_bridge(Identifiable)] attribute which is used to generate an Identifiable protocol implementation for a type.

    For example:

    // Rust
    
    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            type SomeType;
    
            #[swift_bridge(Identifiable, swift_name = "someFunction")]
            fn some_function(&self) -> i16;
        }
    }
    
    // Generated Swift
    // (rough example, the real generated code looks a little different)
    
    class SomeType {
        // ...
    }
    extension SomeType: Identifiable {
        var id: UInt16 {
            return self.someFunction()
        }
    }
    

    • Fix RustStr bug due to incorrect buffer size
    Source code(tar.gz)
    Source code(zip)
  • 0.1.24(Jan 26, 2022)

    • Support Vec<OpaqueRustType> as a fn arg #20

    For example, the following signature is now possible:

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            type ARustTypeInsideVecT;
    
            fn rust_reflect_vec_opaque_rust_type(
                arg: Vec<ARustTypeInsideVecT>,
            ) -> Vec<ARustTypeInsideVecT>;
        }
    }
    
    Source code(tar.gz)
    Source code(zip)
  • 0.1.23(Jan 25, 2022)

    • Support Option<OpaqueRustType> in functions #19

    For example, the following is possible as of this release.

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            type SomeType;
            type AnotherType;
    
            fn some_function (arg: Option<SomeType>) -> Option<AnotherType>;
        }
    }
    
    pub struct SomeType { /* */ }
    pub struct AnotherType(/* ... */);
    fn some_function(arg: Option<SomeType>) -> Option<AnotherType> { /* ... */  }
    
    Source code(tar.gz)
    Source code(zip)
  • 0.1.22(Jan 25, 2022)

    • Make generated Swift structs public #18

    Allows you to (at this time manually) implement certain protocols, such as Identifiable, on generated structs in Swift.

    Without this you get an error:

    Property 'id' must be declared public because it matches a requirement in public protocol 'Identifiable'
    

    In the future we might allow the user to control whether or not the generated struct is public (perhaps by declaring pub on the struct declaration in the bridge module..) but let's hold off on that until we are more familiar with Swift's Access Control.

    Source code(tar.gz)
    Source code(zip)
  • 0.1.21(Jan 24, 2022)

    • Fix span when reporting an incorrect argument type.

    For example, given this bridge module...:

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            #[swift_bridge(rust_name = "some_function")]
            fn fn1(arg: &str);
        }
    }
    
    fn some_function(_arg: u16) {}
    

    Before this release

    ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
    error[E0308]: mismatched types
    
     --> tests/ui/incorrect-argument-type.rs:1:1
      |
    1 | #[swift_bridge::bridge]
      | ^^^^^^^^^^^^^^^^^^^^^^^ expected `u16`, found `&str`
      |
    ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
    

    As of this release

    ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
    error[E0308]: mismatched types
      --> tests/ui/incorrect-argument-type.rs:4:16
       |
     4 |         fn fn1(arg: &str);
       |                ^^^^^^^^^ expected `u16`, found `&str`
    ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
    

    • Fix using the into_return_type attribute when returning shared structs.

    A recent regression broke this behavior. Added an integration test to prevent this from breaking again.

    Source code(tar.gz)
    Source code(zip)
  • 0.1.20(Jan 22, 2022)

    • It is now possible to use Option<T> in extern "Rust" function arguments. #15

    For example, as of this release the following is now possible.

    #[swift_bridge::bridge]
    mod ffi {
        extern "Rust" {
            // You can now expose functions that have Option<T> arguments.
            fn some_function(count: Option<u32>, message: Option<String>);
        }
    }
    
    fn some_function(count: Option<u32>, message: Option<String>) {
        // ...
    }
    

    So far we support:

    Option<Integer>s such as `u8` and `i64`
    Option<f32>, Option<f64>
    Option<bool>
    
    Option<String>
    Option<&str>
    

    It is already possible for functions to return Option<T>.

    In the future we will support Option<T> fields in shared structs.

    Source code(tar.gz)
    Source code(zip)
  • 0.1.19(Jan 17, 2022)

    • Fix parsing multiple function attributes b15b3659382b60751d4a5ecb1feb4577331f44b5

    • Fix parsing opaque Rust doc comments f4d8b73e9fb2b17e1ac722548c811f829f3682fa

    Source code(tar.gz)
    Source code(zip)
  • v0.1.18(Jan 17, 2022)

The project brings the IC ecosystem to Unity, allowing Unity developers to call the functions of canisters on IC,

Agent of Internet Computer for Unity The Intro The project brings the IC ecosystem to Unity, allowing Unity developers to call the functions of canist

Shiku Labs 9 Nov 18, 2022
A high performance Remote Procedure Call system.

A high performance Remote Procedure Call (RPC) system. Usage Add this to your Cargo.toml file. [dependencies] frpc = { git = "https://github.com/nurmo

Nur 5 Jul 28, 2023
Simple node and rust script to achieve an easy to use bridge between rust and node.js

Node-Rust Bridge Simple rust and node.js script to achieve a bridge between them. Only 1 bridge can be initialized per rust program. But node.js can h

Pure 5 Apr 30, 2023
IBC modules and relayer - Formal specifications and Rust implementation

ibc-rs Rust implementation of the Inter-Blockchain Communication (IBC) protocol. This project comprises primarily four crates: The ibc crate defines t

Informal Systems 296 Dec 31, 2022
Fast and efficient ed25519 signing and verification in Rust.

ed25519-dalek Fast and efficient Rust implementation of ed25519 key generation, signing, and verification in Rust. Documentation Documentation is avai

dalek cryptography 563 Dec 26, 2022
Complete Ethereum and Celo wallet implementation and utilities in Rust

ethers.rs Complete Ethereum and Celo wallet implementation and utilities in Rust Documentation Extensive documentation and examples are available here

Georgios Konstantopoulos 1.5k Jan 8, 2023
A simple and secure rust command-line tool to protect your text by encrypting and decrypting it using the robust AES-256 algorithm.

Secret Keeper A simple and secure command-line tool to protect your text by encrypting and decrypting it using the robust AES-256 algorithm. Built wit

Kunal Bagaria 9 May 11, 2023
🔐 UPLINK is a Rust lightweight (2MB) tool for file transfer and remote management that uses AES-GCM and Envelope Encryption over WebSockets.

UPLINK ░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░░▒▓█▓▒░ ░▒▓█▓▒░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█

Krystian Bajno 5 Sep 28, 2024
Diem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.

Note to readers: On December 1, 2020, the Libra Association was renamed to Diem Association. The project repos are in the process of being migrated. A

Diem 16.7k Jan 8, 2023
A safe implementation of the secure remote password authentication and key-exchange protocol (SRP), SRP6a and legacy are as features available.

Secure Remote Password (SRP 6 / 6a) A safe implementation of the secure remote password authentication and key-exchange protocol (SRP version 6a). Ver

Sven Assmann 10 Nov 3, 2022
Retrieving SSH and GPS keys from GitHub and GitLab

Dormarch Retrieving SSH and GPS keys from GitHub and GitLab Usage After having installed Dormarch, you can see all the options with dormarch -h. To re

Riccardo Padovani 2 Dec 24, 2021
Terabethia - A Bridge and Messaging Protocol between Ethereum and the Internet Computer.

Terabethia - A Bridge Between Ethereum & the Internet Computer Terabethia is a bridge between Ethereum & the Internet Computer that contracts in both

Psychedelic 36 Dec 26, 2022
A guide for Mozilla's developers and data scientists to analyze and interpret the data gathered by our data collection systems.

Mozilla Data Documentation This documentation was written to help Mozillians analyze and interpret data collected by our products, such as Firefox and

Mozilla 75 Dec 1, 2022
Diem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.

Note to readers: On December 1, 2020, the Libra Association was renamed to Diem Association. The project repos are in the process of being migrated. A

Diem 16.7k Jan 9, 2023
Library with support for de/serialization, parsing and executing on data-structures and network messages related to Bitcoin

Rust Bitcoin Library with support for de/serialization, parsing and executing on data-structures and network messages related to Bitcoin. Heads up for

Rust Bitcoin Community 1.3k Dec 29, 2022
Fiddi is a command line tool that does the boring and complex process of checking and processing/watching transactions on EVM compatible Blockchain.

Fiddi is a command line tool that does the boring and complex process of checking and processing/watching transactions on EVM compatible Blockchain.

Ahmad Abdullahi Adamu 7 Jan 9, 2023
Selendra is a multichains interoperable nominated Proof-of-Stake network for developing and running Substrate-based and EVM compatible blockchain applications.

Selendra An interoperable nominated Proof-of-Stake network for developing and running Substrate-based and EVM compatible blockchain applications. Read

Selendra 16 Nov 29, 2022
Confidential credit scores and loan disbursal, powered by zkSNARKs and NEAR Protocol

zkLoans zkLoans brings confidential Credit Scores. It proves to a counterparty if you meet threshold requirements for a credit score without revealing

Anirudha Bose 2 Sep 13, 2022
A fast, simple and powerful open-source cross platform utility tool for generating strong, unique and random passwords

password-generator-pro A fast, simple and powerful open-source cross platform utility tool for generating strong, unique and random passwords. Feature

Sebastien Rousseau 3 Dec 16, 2022