Closed cozyGalvinism closed 2 years ago
You're right that the issue is because we don't currently support generics.
Would something like this meet your needs for now?
type MyApiResponse = APIResponseList<
APIResponseObject<PteroClientServer, APIResponsePaginationMetaData>,
APIResponsePaginationMetaData,
>;
#[swift_bridge::bridge]
mod ffi {
extern "Rust" {
type MyApiResponse;
}
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<MyApiResponse>;
}
}
Not as flexible as generics, but could work fine in the meantime if you don't have a lot of combinations that you need to support.
I actually tried that and it still didn't work. However, this may be because async also isn't working for me, like, in general. If I clone your repo, I can build the example just fine, however in my project, async just results in thread 'main' panicked at 'not implemented', /home/cozygalvinism/.cargo/registry/src/github.com-1ecc6299db9ec823/swift-bridge-ir-0.1.29/src/bridged_type.rs:695:25
.
I spent the last few hours converting my generics to flat classes, to no avail, then I wrote a few macros that define structs twice: once with serde support and another time without with a From implementation (because I thought it could've been serde's macros) but that also didn't work.
So right now, my entire code looks like:
pub struct MyAsyncClient;
impl MyAsyncClient {
async fn run_something(&self) -> String;
}
#[swift_bridge::bridge]
mod ffi {
extern "Rust" {
type MyAsyncClient;
async fn run_something(&self) -> String;
}
}
with my Cargo.toml looking like:
[package]
name = "ptero-rs"
version = "0.1.0"
edition = "2021"
build = "build.rs"
[lib]
name = "ptero_rs"
crate-type = ["staticlib"]
[dependencies]
reqwest = { version = "0.11.10", features = ["json"] }
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79"
swift-bridge = { version = "0.1", features = ["async"] }
[build-dependencies]
swift-bridge-build = "0.1"
I'm probably missing something obvious... And if so, I'm sorry for bothering you x)
I think I found out why: In my example, I try to run an async function that's implemented for a struct. If I just make it an unbound async function, it compiles fine. I will unbind my async functions tomorrow and test if that works with the type solution you proposed.
If this is intended for now (as in: it will be possible to use bound async methods in the future), I will make adjustments to my library and call it done until this crate has implemented support for it c: I also cannot thank you enough for working on this crate, truly amazing job!
Thanks for the detailed report. And thanks a lot for the kind words.
Right now we only support async functions that have 0 arguments. We also don't support async functions that take a receiver (i.e. &self
).
Not including arguments made it easier to get a first version out.
This does mean that what you're trying to do is more or less impossible to express with swift-bridge
right now.
I'd be more than happy to guide you on how to add support for &self
in async functions to swift-bridge
if you like.
Otherwise, I can see if I can possibly implement this this week. But week ahead so I'm not entirely sure.
Thanks for the detailed report. And thanks a lot for the kind words.
Right now we only support async functions that have 0 arguments. We also don't support async functions that take a receiver (i.e.
&self
).Not including arguments made it easier to get a first version out.
This does mean that what you're trying to do is more or less impossible to express with
swift-bridge
right now.I'd be more than happy to guide you on how to add support for
&self
in async functions toswift-bridge
if you like. Otherwise, I can see if I can possibly implement this this week. But week ahead so I'm not entirely sure.
Implementing this sounds good but even if that doesn't work out, I will implement this using a blocking client in the meantime (async seems like more trouble than it's worth for now). Big reason why I wanted to use this crate was because I already had the request and response models done in Rust, so I didn't want to do them again in Swift but rather just writing the client in Rust and then using that client in Swift (and because I'm rather new to Swift).
Or I just do it in Swift for the learning experience.
I thought of a way to implement support for generics.
I can implement generics and async functions that have arguments. Then you should be good to go.
Just not sure if I'll get to it this week.
Did you manage to find a path forward in the meantime?
Sort of? I am using reqwest::blocking
rn and that builds just fine (as expected). I will re-implement my generics now and see if that works too.
EDIT: Yup, confirmed the following as working:
type GetServersResponseList = models::responses::APIResponseList<models::responses::APIResponseObject<models::responses::PteroClientServer, models::responses::APIResponsePaginationMetaData>, models::responses::APIResponsePaginationMetaData>;
#[swift_bridge::bridge]
mod ffi {
extern "Rust" {
type GetServersResponseList;
}
extern "Rust" {
type PteroClient;
#[swift_bridge(init)]
fn new(base_url: String, api_key: String) -> PteroClient;
fn get_servers(&self) -> Option<GetServersResponseList>;
}
}
Async Rust functions and methods are now supported
https://github.com/chinedufn/swift-bridge/releases/tag/0.1.30
Oh wow! I will test this once I have a bit more time on my hands c: Thank you very much!
No problem!
Your use case would still be a bit painful until generics are supported.
Feel free to subscribe to https://github.com/chinedufn/swift-bridge/issues/44 which tracks generics support.
Closing in favor of https://github.com/chinedufn/swift-bridge/issues/44
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:
The error I receive:
Am I doing something wrong or is my assumption correct?