-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support swift_repr = "class"
to use a Swift class for transparent structs
#196
Comments
Ok I thought through this a bit more. Here's what I'm currently thinking about (work in progress ideas...). Given the following bridge module: // Rust
#[swift_bridge::bridge]
mod ffi {
#[swift_repr = "class"]
struct User {
name: String,
age: u8,
friend: MyRustFriend
}
extern "Rust" {
type MyRustFriend;
}
} We would generate Swift code like: // Swift
class User {
var name: RustString
var age: UInt8
var friend: MyRustFriend
public init(name: RustString, age: UInt8, friend: MyRustFriend) {
self.name = name
self.age = age
self.friend = friend
}
}
class UserRefMut: UserRef {
public override init(ptr: UnsafeMutableRawPointer) {
super.init(ptr: ptr)
}
func name_mut() -> RustStringRefMut {
__swift_bridge__$User$_name_mut()
}
func friend_mut() -> MyRustFriendRefMut {
__swift_bridge__$User$_friend_mut()
}
}
class UserRef {
var ptr: UnsafeMutableRawPointer
public init(ptr: UnsafeMutableRawPointer) {
self.ptr = ptr
}
func name() -> RustStringRef {
__swift_bridge__$User$_name()
}
func age() -> UInt8 {
__swift_bridge__$User$_age()
}
func friend() -> MyRustFriendRef {
__swift_bridge__$User$_friend()
}
}
Hmmm.. I suppose this could maybe work for passing transparent structs from Rust -> Swift ... but what about the other direction ... ? Need to think about all of this more... I don't like this solution ... But I'll still post it here in the interest of sharing ideas.. |
Hey @chinedufn, that solution could work, but as you mentioned might have some conversion issues between Swift -> Rust. Plus it might possibly might introduce quite some overhead to get the Swift repr, since you need to first get the I've been thinking about whether it would be possible to instead of returning a pointer to the Rust repr, return the C (FFI) repr? Since the C repr is something that both Swift and Rust understand we should be able to easily convert them on both ways, Rust could look something like: fn something(* const ffi_repr) {
let ffi = usafe { &* ffi_repr }
let rust = ffi.into_rust_repr()
} And Swift: func something(pointer: UnsafePointer) {
let ffi = pointer.load(as: __swift_bridge__ffi.self)
let swift = ffi.toSwiftRepr()
} Honestly I'm not totally sure what I'm suggesting makes sense, I just assumed this could work having a look at how Vec support is implemented for Rust Opaque types ( Plus I have no idea how to PoC this and see how it works out. If you could help out giving some instructions on how we could try this out on a small interface, I could try implementing it so we could validate if the idea works. |
Only if you wanted an owned
I'm not really following the advantage here over a pointer?
Hmm the challenge here is that I don't even have a good idea of how to best do this myself. So, to serve as a good guide I'd need to dive in and mess around a bit. Ultimately the HOW behind all of this is an internal detail. The developer interface shouldn't really change much (as in, if we change how we solve this problem the bridge module shouldn't need to change much or at all). So I'd say that the best way to start would be to get some portion of #196 (comment) working by writing 1 or more integration tests and 1 or more codegen tests. Then we could iteratively build up from there. Please feel free to let me know if you have more questions. |
Right now a transparent struct can only be represented using a Rust
struct
and a Swiftstruct
.We want it to also be possible to have a transparent struct show up as a
struct
on the Rust side and aclass
on the Swift side.We do not currently have a way to pass a reference to a Swift
struct
fromSwift
->Rust
.Whether or not there is a good way to do this will require some research.
We do, however, already support passing a Swift
class
fromSwift
->Rust
. This is how opaque types are passed from Swift -> Rust.We get a pointer to the Swift class and pass that pointer over FFI to Rust.
Supporting
swift_repr = "class"
will unlock some use cases such as supportingVec<TransparentStruct>
and sharing references to transparent structs between languages (both immutably and mutably).Essentially, when a transparent struct has
swift_repr = "class"
it should be passed over FFI in the largely same way that we pass opaque types today.The only difference is that the generated Swift class should have accessible fields.
So this:
would become something along the lines of:
similar to how we generate classes for opaque Rust types
swift-bridge/crates/swift-bridge-ir/src/codegen/codegen_tests/opaque_rust_type_codegen_tests.rs
Lines 5 to 63 in e7aef34
The text was updated successfully, but these errors were encountered: