Returning Vec<T> where T: IntoWasmAbi
Hello! Thanks for a great library!
In https://github.com/rustwasm/wasm-bindgen/pull/3554 (See also: https://github.com/rustwasm/wasm-bindgen/issues/111 ) the possibility to return a Vec<SomeType> where SomeType has #[wasm_bindgen] on it was introduced.
Later, in https://github.com/rustwasm/wasm-bindgen/issues/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 https://github.com/rustwasm/wasm-bindgen/discussions/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-bindgento implement support forVec<T: IntoWasmAbi>? - Get
tsifyto put the correct generic argument on the ts return type (i.e.getThings(): GenericCollection<Thing>;)? - Live with the suboptimal solution?
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.
The tsify-next crate added support for that recently. It might be reasonable to switch to that crate as this one seems unmaintained.