chinedufn / swift-bridge

swift-bridge facilitates Rust and Swift interop.
https://chinedufn.github.io/swift-bridge
Apache License 2.0
842 stars 62 forks source link

Support transparent struct via use statement #223

Closed wentao closed 1 year ago

wentao commented 1 year ago

Let's say I have a struct defined outside of ffi mod as

struct A { value: i32, }

Then in the ffi mod

mod { use super::A }

So A gets trans-compiled into the h/swift files just like if A is defined in the mod.

chinedufn commented 1 year ago

Given the following bridge module:

#[swift_bridge::bridge]
mod ffi {
    use super::A;

    extern "Rust" {
        fn get() -> Result<A, A>;
    }
}

struct A {
    value: i32
}

The swift_bridge::bridge proc macro would need to know what super::A is since the C representation that we use to pass a Result<T, E> from Rust -> Swift depends on the T and E.

For example, if super::A is meant to be opaque we'll generate different Result<A, A> FFI glue code than if super::A is meant to be a transparent struct.

I don't think that there is a good way to do something like this.


One option that you have is to use return_into and args_into to convert between a struct defined on the outside and one defined on the inside.

Depending on your needs this may or may not be too verbose, but I'll share an example with you in case it's useful.

https://chinedufn.github.io/swift-bridge/bridge-module/functions/index.html#swift_bridgereturn_into

For example:

#[swift_bridge::bridge]
mod ffi {
    struct MyFfiStruct { val: i32 }

    extern "Rust" {
        #[swift_bridge(return_into)]
        fn get() -> MyFfiStruct;
    }
}

struct MyStruct {
    val: i32
}
impl Into<ffi::MyFfiStruct> for MyStruct {
    // ...
}