uniffi-rs icon indicating copy to clipboard operation
uniffi-rs copied to clipboard

Allow objects implementing `Trait` to be passed as arguments to functions asking for `dyn Trait`

Open Enduriel opened this issue 6 months ago • 0 comments

Currently, given this rust code

#[uniffi::export]
pub trait MyTrait {}

#[uniffi::export]
pub struct MyStruct;

#[uniffi::export]
impl MyTrait for MyStruct {
    fn my_method(&self) {
        todo!()
    }
}

#[uniffi::export]
pub fn foo(x: &dyn MyTrait) {
    x.my_method();
}

#[uniffi::export]
pub fn make_struct() -> MyStruct {
    MyStruct
}

uniffi will generate these kotlin types:

public interface MyTraitInterface{}

open class MyTrait: Disposable, AutoCloseable, MyTraitInterface {}

fun `foo`(`x`: MyTrait) {}
fun `makeStruct` () : MyStruct {}

open class MyStruct: Disposable, AutoCloseable, MyStructInterface, MyTraitInterface

Which means that it is impossible to call foo with a value returned from makeStruct, from Kotlin's side, it seems obvious that foo should instead be

fun `foo`(`x`: MyTraitInterface) {}

and it would be really cool if uniffi would allow this.

As a short term potential solution, it should be possible to create functions to allow conversion between a type and any trait implemented by that type, in this case something like

pub fn my_struct_to_my_trait(x: MyType) -> dyn MyTrait

and then kotlin side do

foo(myStructToMyTrait(makeStruct())

(in practice probably with more cloning).

But long term it would be really cool (and according to a discussion on Matrix this should be possible) if it could be done automatically, since with everything exported like in the example uniffi should have all the information it needs.

Enduriel avatar May 22 '25 19:05 Enduriel