Skip to content
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

Returning Vec<T> where T: IntoWasmAbi #49

Open
bes opened this issue Feb 3, 2024 · 2 comments
Open

Returning Vec<T> where T: IntoWasmAbi #49

bes opened this issue Feb 3, 2024 · 2 comments

Comments

@bes
Copy link

bes commented Feb 3, 2024

Hello! Thanks for a great library!

In rustwasm/wasm-bindgen#3554 (See also: rustwasm/wasm-bindgen#111 ) the possibility to return a Vec<SomeType> where SomeType has #[wasm_bindgen] on it was introduced.

Later, in rustwasm/wasm-bindgen#3692 @hillin asked why it wasn't possible to return a Vec<T> where T: IntoWasmAbi. I now have the exact same question. Unfortunately that issue was closed, and moved into this discussion rustwasm/wasm-bindgen#3697 where it received only one reply, from the question asker themself.

The answer was to create a newtype that itself is IntoWasmAbi and then return that:

#[derive(serde::Serialize, tsify::Tsify)]
#[tsify(into_wasm_abi)]
pub struct ThingCollection(Vec<Thing>);

pub fn get_numbers() -> ThingCollection {
   ThingCollection(vec![Thing(1), Thing(2), Thing(3)])
}

Which works, but now I have to have a number of newtypes that I don't want in my code.

I tried improving the situation by creating a generic version of that:

#[derive(serde::Serialize, tsify::Tsify)]
#[tsify(into_wasm_abi)]
pub struct GenericCollection<T: IntoWasmAbi>(Vec<T>);

#[wasm_bindgen(js_class = MyTypeHandle)]
struct MyType {
    #[wasm_bindgen(js_name = getThings)]
    pub fn get_things(&self) -> GenericCollection<Thing> {
        let things = ...;
        GenericCollection(things)
    }
}

Which kind of half-worked - the TS type was correctly generated, but the return value of the function lacked the generic type argument:

export type GenericCollection<T> = T[];

export class MyTypeHandle {
  free(): void;
  getThings(): GenericCollection;
}

So the question is, what's the solution here?

  • Get wasm-bindgen to implement support for Vec<T: IntoWasmAbi>?
  • Get tsify to put the correct generic argument on the ts return type (i.e. getThings(): GenericCollection<Thing>;)?
  • Live with the suboptimal solution?
@jmigual
Copy link

jmigual commented May 21, 2024

The problem seems to be that tsify needs to implement the VectorIntoWasmAbi and WasmDescribeVector traits. These are the traits that allow converting a Vec<T> into a JS array of Ts.

@eneoli
Copy link

eneoli commented Aug 5, 2024

The tsify-next crate added support for that recently. It might be reasonable to switch to that crate as this one seems unmaintained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants