Releases: chinedufn/swift-bridge
0.1.57
-
Support Failable initializers. #276 (thanks @NiwakaDev)
// Rust #[swift_bridge::bridge] mod ffi { extern "Rust" { #[swift_bridge(Equatable)] type FailableInitType; #[swift_bridge(init)] fn new() -> Option<FailableInitType>; } }
// Swift let failableInitType = FailableInitType() if failableInitType == nil { // ... } else { // ... }
-
Support Throwing initializers #287 (thanks @NiwakaDev)
// Rust #[swift_bridge::bridge] mod ffi { enum ResultTransparentEnum { NamedField { data: i32 }, UnnamedFields(u8, String), NoFields, } extern "Rust" { type ThrowingInitializer; #[swift_bridge(init)] fn new(succeed: bool) -> Result<ThrowingInitializer, ResultTransparentEnum>; fn val(&self) -> i32; } }
// Swift do { let throwingInitializer = try ThrowingInitializer(false) } catch let error as ResultTransparentEnum { //... } catch { //... }
0.1.56
-
Add
swift-bridge parse-bridges
CLI command. #274 (thanks @integer-overflown)swift-bridge-cli parse-bridges --crate-name my-crate -f src/lib.rs -o generated
swift-bridge-cli parse-bridges --crate-name my-superb-crate \ -f src/lib.rs \ -f src/some_other_file.rs \ -o generated
-
Respect bridge modules' visibility. #284 (thanks @jnbooth)
// Notice that this is `pub mod`. // Before this commit `swift-bridge` would ignore the `pub` and instead // emit a `mod ffi`. // This made it impossible to `use enums::ffi_foo::MyEnum` from another module. #[swift_bridge::bridge] pub mod ffi_foo { enum MyEnum { VariantA, VariantB, VariantC, } } #[swift_bridge::bridge] pub(crate) mod ffi_bar { enum AnotherEnum { Variant1, Variant2, } }
-
Add a temporary work around for a dead code linting regression in Rust
1.79
. #278 (thanks @sax)rustc
's dead code linting pass regressed in1.79
, causingswift-bridge
to sometimes generate code that emitted dead code warnings, even though the code was not dead.- tracked: rust-lang/rust#126706
// Some bridge modules that used `Result` were given an // "error: field `0` is never read" warning. #[swift_bridge::bridge] mod ffi { #[swift_bridge(swift_repr = "struct")] struct TransparentErrorStruct(pub String); extern "Rust" { fn rust_func_returns_result_transparent_struct( succeed: bool ) -> Result<(), TransparentErrorStruct>; } }
0.1.55
- Fix memory leak when passing
Option<SwiftType>
from Swift to Rust. #273- It is very unlikely that users were impacted by this leak
Option<SwiftType>
support was introduced about 10 hours ago - Full explanation of the leak can be found in 87dbea3
#[swift_bridge::bridge] mod ffi { extern "Swift" { type SomeSwiftType; } extern "Rust" { // Calling with would leak memory in "0.1.54". // This no longer leaks as of "0.1.55". fn option_arg(arg: Option<SomeSwiftType>); } }
- It is very unlikely that users were impacted by this leak
0.1.54
- Add support for bridging
Option<SwiftType>
in Rust function arguments and returns. #272 (thanks @Bright-Shard)#[swift_bridge::bridge] mod ffi { extern "Swift" { type SomeSwiftType; } extern "Rust" { fn option_arg(arg: Option<SomeSwiftType>); fn returns_option() -> Option<SomeSwiftType>; } }
0.1.53
-
Add support for bridging
Option<&OpaqueRustType>
inextern "Rust"
modules. #257 (thanks @PrismaPhonic)#[swift_bridge::bridge] mod ffi { extern "Rust" { type MyRustType; fn my_func(arg: Option<&MyRustType>) -> Option<&MyRustType>; } }
-
Add support for bridging
Option<String>
inextern "Swift"
args/returns andOption<&str>
inextern "Swift"
args. #264#[swift_bridge::bridge] mod ffi { extern "Swift" { fn opt_string_function(arg: Option<String>) -> Option<String>; fn opt_str_function(arg: Option<&str>); } }
-
Improve error message when reporting an unsupported attribute #244 (thanks @bes)
0.1.52
-
Improve support for order independent declarations. #230 (thanks @NiwakaDev)
-
Support
Vec<PRIMITIVE>
in Swift function argument and return types. #229 (thanks @timwedde)// Rust fn main() { let bytes = ffi::receive_bytes(); println!("bytes: {:?}", bytes); let vec: Vec<u8> = vec![6, 1, 2, 3, 4, 5]; ffi::send_bytes(vec); } #[swift_bridge::bridge] mod ffi { extern "Swift" { fn receive_bytes() -> Vec<u8>; fn send_bytes(vec: Vec<u8>); } }
// Swift func send_bytes(vec: RustVec<UInt8>) { print("Received \(vec.len()) bytes from Rust") for val in vec { print(val) } } func receive_bytes() -> RustVec<UInt8> { let vec = RustVec<UInt8>() for i in 0 ... 4 { vec.push(value: UInt8(i)) } return vec }
-
Support using
already_declared
enums and structs as Swift arguments. #226 (thanks @conectado)// For example, the following is now possible: #[swift_bridge::bridge] mod ffi_i { enum Animal { Alligator, Cat, } } use ffi_i::Foo; #[swift_bridge::bridge] mod ffi { #[swift_bridge(already_declared)] enum Animal {} extern "Swift" { fn hug(a: Animal); } }
-
Support Rust async fn return
Result<(), enum>
. #189 (thanks @NiwakaDev)// Rust #[swift_bridge::bridge] mod ffi { enum SomeEnum { //... } extern "Rust" { async fn some_function() -> Result<(), SomeEnum>; } }
// Swift do { let value = try await some_function() //... } catch let error as SomeEnum { //... } catch { //... }
-
Support Rust async fn return
Result<enum, enum>
. #182 (thanks @NiwakaDev)// Rust #[swift_bridge::bridge] mod ffi { enum NetworkError { NoData, Authentication, } extern "Rust" { type Data; } extern "Rust" { async fn fetch_from_server() -> Result<Data, NetworkError>; } }
// Swift do { let data = try await fetch_from_server() //... } catch let error as NetworkError { //... } catch { //... }
-
Fix and test async Rust fn return
Result<(), OpaqueType>
. #221 (thanks @jfaust) -
Fix and test async Rust fn return
Result<Vec<T>, *>
. #218 (thanks @jfaust) -
Support passing primitive tuples from
Rust -> Swift
. #195 (thanks @NiwakaDev)// Rust #[swift_bridge::bridge] mod ffi { extern "Rust" { fn reflect_tuple_primitives(tuple: (i16, u32)) -> (i16, u32); } } fn reflect_tuple_primitives(tuple: (i16, u32)) -> (i16, u32) { tuple }
// Swift let tuple = reflect_tuple_primitives((-1, 10))
-
Support passing primitive tuples from
Swift -> Rust
. #205 + #211 (thanks @NiwakaDev)// Rust #[swift_bridge::bridge] mod ffi { extern "Swift" { fn swift_reflect_tuple_primitives(arg: (i32, u32)) -> (i32, u32); } }
// Swift let tuple = swift_reflect_tuple_primitives((-123, 123));
-
Support returning
Result<Tuple, *>
from Rust to Swift. #213 (thanks @NiwakaDev)// Rust #[swift_bridge::bridge] mod ffi { extern "Rust" { fn rust_func_return_result_tuple_transparent_enum( succeed: bool, ) -> Result<(i32, ResultTestOpaqueRustType, String), ResultTransparentEnum>; } }
// Swift do { //... let tuple: (Int32, ResultTestOpaqueRustType, RustString) = try rust_func_return_result_tuple_transparent_enum(true) //... } catch { //... }
-
Support
#[derive(Debug)]
on transparent enums. #194 (thanks @naturecodevoid)// Rust #[swift_bridge::bridge] mod ffi { #[derive(Debug)] enum DeriveDebugEnum { Variant, } }
// Swift let debugString = String(reflecting: DeriveDebugEnum.Variant) XCTAssertEqual(debugString, "Variant")
-
Only support the
#[swift_bridge(associated_to)]
attribute on instance methods. #206 (thanks @NiwakaDev) -
Support Option in Swift fns. #203
mod ffi { extern "Swift" { fn my_func(arg: Option<u8>) -> Option<bool>; } }
-
Add
Vec<f32>
andVec<f64>
support. #200 (thanks @rkreutz)#[swift_bridge::bridge] mod ffi { #[swift_bridge(swift_repr = "struct")] struct SomeStruct { field: Vec<f32>, } extern "Rust" { fn do_something(val: SomeStruct) -> Vec<f32>; } } fn do_something(val: SomeStruct) -> Vec<f32> { // ... }
-
Add
#[derive(Copy, Clone)]
support to transparent structs. #198 (thanks @rkreutz)#[swift_bridge::bridge] mod ffi { #[swift_bridge(swift_repr = "struct")] #[derive(Copy, Clone)] struct Foo { field: u8, } }
-
Slightly simplify generated code for returning
Result<(), OpaqueType>
. #184 (thanks @NiwakaDev) -
Support RustString in extern Swift functions. [#225] (thanks @NiwakaDev)
// Swift func reflect_swift_string(arg: RustString) -> RustString { arg }
// Rust #[swift_bridge::bridge] mod ffi { extern "Swift" { fn reflect_swift_string(arg: String) -> String; } } let foo = "foo"; let string = ffi::reflect_swift_string(foo.to_string()); assert_eq!(string.len(), 3); assert_eq!(&string, foo);
0.1.51
-
Support returning
Result<(), OpaqueRustType>
from Rust functions. #180 (thanks @jfaust)// For example, the following is now possible: #[swift_bridge::bridge] mod ffi { struct UnitStruct; extern "Rust" { type OpaqueType; fn null_result() -> Result<(), OpaqueType>; fn unit_result() -> Result<UnitStruct, OpaqueType>; } } fn null_result() -> Result<(), OpaqueType> { Ok(()) } fn unit_result() -> Result<UnitStruct, OpaqueType> { Ok(UnitStruct) }
-
Support shared enums with named data. #175 (thanks @NiwakaDev)
// For example, the following is now possible: #[swift_bridge::bridge] mod ffi { enum EnumWithNamedData { Variant1 { hello: String, data_u8: u8 }, Variant2 { data_i32: i32 }, Variant3 { foo: Foo }, } extern "Rust" { #[swift_bridge(Equatable)] type Foo; #[swift_bridge(init)] fn new() -> Foo; fn reflect_enum_with_named_data(arg: EnumWithNamedData) -> EnumWithNamedData; } }
// Swift let enumWithNamedData3 = EnumWithNamedData.Variant3(foo: Foo()) switch reflect_enum_with_named_data(enumWithNamedData3) { case .Variant3(let foo): XCTAssertEqual(foo, Foo()) break default: XCTFail() }
-
Support opaque types inside of data-carrying enums. #181 (thanks @NiwakaDev)
// For example, the following is now possible: #[swift_bridge::bridge] mod ffi { enum OpaqueRustEnum { Unnamed(MyType) Named { field: MyType }, } extern "Rust" { #[swift_bridge(Equatable)] type MyType; #[swift_bridge(init)] fn new() -> MyType; fn reflect_enum(arg: OpaqueRustEnum) -> OpaqueRustEnum; } }
// Swift let opaqueRustEnum = OpaqueRustEnum.Named(field: MyType()) switch reflect_enum(opaqueRustEnum) { case .Named(let named): XCTAssertEqual(named, MyType()) break default: XCTFail() }
-
Reduce the FFI representation of ZSTs (zero-sized types) from one byte to zero bytes. #178
- Previously ZSTs were bridged as a
u8
in order to preserve FFI safety. - Now we simply inline the ZST on both sides of the FFI boundary, enabling zero memory overhead sharing of ZSTs.
// For example, the following bridge module: #[swift_bridge::bridge] mod ffi { struct UnitStruct1; struct UnitStruct2{} struct UnitStruct3(); extern "Rust" { fn some_function( arg1: UnitStruct1, arg2: UnitStruct2, arg3: UnitStruct3, ) -> UnitStruct1; } }
// generates the following exported Rust function: #[link_name = "__swift_bridge__$some_function"] pub extern "C" fn __swift_bridge__some_function() { {super::some_function(UnitStruct1, UnitStruct2{}, UnitStruct3()); ()} }
// and generates the following Swift: func some_function(arg1: UnitStruct1, arg2: UnitStruct2, arg3: UnitStruct3) -> UnitStruct1 { { let _ = __swift_bridge__$some_function(); UnitStruct1() }() }
- Previously ZSTs were bridged as a
0.1.50
-
Support data-carrying tuple enum variants. #172 (thanks @NiwakaDev)
// For example, the following is now possible: #[swift_bridge::bridge] mod ffi { enum EnumWithUnnamedData { Variant1(String, u32), Variant2(i32, u8), Variant3, } }
// Swift let myEnum: EnumWithUnnamedData = .Variant2(10, 20)
-
Emit compile time errors when returning the wrong opaque Rust type. #169 (thanks @MikuroXina)
// For example, the following will no longer compile: #[swift_bridge::bridge] mod ffi { extern "Rust" { // Before this release calling `get_reference()` from Swift would cause // undefined behavior. // As of this release this will no longer compile. fn get_reference() -> SomeType; } } // Note that the bridge module incorrectly declares `-> SomeType` // instead of `-> &'static SomeType`. fn get_reference() -> &'static SomeType { &SomeType }
0.1.49
-
Support returning
Result<OpaqueRust, OpaqueRust>
from async Rust functions. #158 (thanks @NiwakaDev)// For example, the following is now possible: #[swift_bridge::bridge] mod ffi { extern "Rust" { type User; type ApiError; #[swift_bridge(swift_name = "loadUser")] async fn load_user() -> Result<User, ApiError>; fn print_info(self: &ApiError); } }
// Swift do { let user = try await loadUser() } catch let err as ApiError { err.print_info() }
-
Introduce the
#[swift_bridge(label = "...")]
function argument attribute for generating Swift argument labels. #156 (thanks @NiwakaDev)// For example, the following is now possible: // Rust #[swift_bridge::bridge] mod ffi { extern "Rust" { fn add( #[swift_bridge(label = "leftHand")] left_hand: i32, right_hand: i32, ) -> i32; } } fn add(left_hand: i32, right_hand: i32) -> i32 { left_hand + right_hand }
// Swift let sum = add(leftHand: 10, 20)
0.1.48
-
Support returning
Result<T, E>
whereT
andE
are opaque Rust types. #149// For example, the following is now possible: #[swift_bridge::bridge] mod ffi { extern "Rust" { type TypeA; type TypeB; fn some_function() -> Result<TypeA, TypeB>; fn print_info(self: &TypeB); } }
// Swift do { let typeA = try some_function() } catch let typeB as TypeB { typeB.print_info() }
-
Support
Option<Vec<T>>
whereT
is a primitive type. #147 (thanks @NiwakaDev)// For example, the following is now possible: #[swift_bridge::bridge] mod ffi { extern "Rust" { fn some_function(arg: Option<Vec<u8>>) -> Option<Vec<i64>>; } }
-
Optimize
RustStr
's SwiftEquatable
protocol implementation. #151 (thanks @NiwakaDev) -
Add compile time error messages for invalid
args_into
attributes. #145 (thanks @NiwakaDev)