#swift #ios #bindings #ffi #parser-generator #mac #data-structures

swift-bridge-ir

包含桥接模块解析和代码生成所需的数据结构和逻辑

58个版本

新版本 0.1.57 2024年8月15日
0.1.55 2024年4月29日
0.1.53 2024年3月26日
0.1.52 2023年7月10日
0.1.5 2021年11月26日

过程宏 中排名 #96

Download history 19078/week @ 2024-04-27 14692/week @ 2024-05-04 18556/week @ 2024-05-11 19737/week @ 2024-05-18 18956/week @ 2024-05-25 21010/week @ 2024-06-01 17268/week @ 2024-06-08 20166/week @ 2024-06-15 22544/week @ 2024-06-22 18902/week @ 2024-06-29 14071/week @ 2024-07-06 10840/week @ 2024-07-13 15321/week @ 2024-07-20 11223/week @ 2024-07-27 10243/week @ 2024-08-03 8462/week @ 2024-08-10

每月下载量 47,150
7crate中使用(直接使用2个)

Apache-2.0/MIT

1MB
25K SLoC

swift-bridge Actions状态 docs crates.io

swift-bridge 促进Rust和Swift的互操作性。

swift-bridge 使Rust和Swift之间传递和共享高级类型变得简单,例如 StringOption<T>Result<T, E>structclass 等更多。

它还帮助您桥接更高层次的语言特性,如异步函数和泛型。

使用 swift-bridge 应该比手动管理Rust和Swift FFI更安全、更高效、更易于使用。

安装

# In your Cargo.toml

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

[dependencies]
swift-bridge = "0.1"

书籍

您可以在 swift-bridge 书籍 中找到有关使用Rust和Swift的信息。

快速浏览

您可以通过在“桥接模块”中声明要导入和导出的类型和函数来使用 swift-bridge,然后使用宏 #[swift_bridge::bridge] 注释该桥接模块。

在构建时,您可以使用 swift-bridge-build API 或 swift-bridge-cli CLI 解析您注释的桥接模块,并生成 FFI 层的 SwiftC 部分。

以下是使用桥接模块描述 Swift 和 Rust 之间 FFI 边界的快速示例。

// We use the `swift_bridge::bridge` macro to declare a bridge module.
// Then at build time the `swift-bridge-build` crate is used to generate
// the corresponding Swift and C FFI glue code.
#[swift_bridge::bridge]
mod ffi {
    // Create "transparent" structs where both Rust and Swift can directly access the fields.
    struct AppConfig {
        file_manager: CustomFileManager,
    }

    // Transparent enums are also supported.
    enum UserLookup {
        ById(UserId),
        ByName(String),
    }

    // Export opaque Rust types, functions and methods for Swift to use.
    extern "Rust" {
        type RustApp;

        #[swift_bridge(init)]
        fn new(config: AppConfig) -> RustApp;
        
        fn get_user(&self, lookup: UserLookup) -> Option<&User>;
    }

    extern "Rust" {
        type User;
        type MessageBoard;

        #[swift_bridge(get(&nickname))]
        fn informal_name(self: &User) -> &str;
    }

    // Import opaque Swift classes and functions for Rust to use.
    extern "Swift" {
        type CustomFileManager;
        fn save_file(&self, name: &str, contents: &[u8]);
    }
}

struct User {
    nickname: String
}

快速入门

swift-bridge 仓库包含示例应用程序,您可以使用这些应用程序快速尝试库,或作为您自己的 Swift + Rust 基于应用程序的起点。

例如,以下是本地运行 codegen-visualizer 示例项目的步骤。

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 ***

您可以在 swift-bridge 书籍 中找到有关使用Rust和Swift的信息。

内置类型

除了允许您在 Rust 和 Swift 之间共享自定义的结构体、枚举和类之外,swift-bridge 还支持许多 Rust 和 Swift 标准库类型。

Rust 中的名称 Swift 中的名称 备注
u8, i8, u16, i16 等 UInt8, Int8, UInt16, Int16 等
bool Bool
String, &String, &mut String RustString, RustStringRef, RustStringRefMut
&str RustStr
Vec<T> RustVec<T>
SwiftArray<T> Array<T> 尚未实现
&[T] 尚未实现
&mut [T] 尚未实现
Box<T> 尚未实现
Box<dyn FnOnce(A,B,C) -> D> (A, B, C) -> D 从 Rust 传递到 Swift 是支持的,但 Swift 到 Rust 尚未实现。
Box<dyn Fn(A,B,C) -> D> (A, B, C) -> D 尚未实现
Arc<T> 尚未实现
[T; N] 尚未实现
*const T UnsafePointer<T>
*mut T UnsafeMutablePointer<T>
Option<T> Optional<T>
fn x() -> Result<T, E> func x() throws -> T
fn x(arg: Result<T, E>) func x(arg: RustResult<T, E>)
(A, B, C, ...) (A, B, C, ...)
您有 Rust 标准库类型的想法吗?
提交一个 issue!
您有 Swift 标准库类型的想法吗?
提交一个 issue!

性能

swift-bridge 旨在在性能关键环境中很有用。

其生成的 FFI 代码不使用对象序列化、克隆、同步或其他任何形式的不必要开销。

要测试

运行测试套件。

# Clone the repository
git clone [email protected]:chinedufn/swift-bridge.git
cd swift-bridge

# Run tests
cargo test --all && ./test-swift-rust-integration.sh && ./test-swift-packages.sh 

贡献

如果您想为 swift-bridge 做贡献,请查看贡献指南

熟悉贡献过程后,尝试查看一些好的第一个 issue,看看是否引起您的兴趣。

这些问题附带逐步说明,应有助于您实施第一个补丁。

鸣谢

  • cxx 启发了使用桥接模块描述 FFI 边界的想法。

许可

MITApache-2.0 许可下发布。


lib.rs:

FFI 层的中间表示。

使用属性 #[swift_bridge::bridge] 标注的内容会被解析成这个 IR。

然后使用这个 IR 生成 C 头文件、Objective-C 桥接头文件、Swift 代码和 Rust 代码,用于驱动 Rust + Swift 互操作性。

依赖项

~1.5MB
~36K SLoC