rustwasm / wasm-bindgen

Facilitating high-level interactions between Wasm modules and JavaScript

Home Page:https://rustwasm.github.io/docs/wasm-bindgen/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Impl `From` traits for conversion between `Array` and `std::vec::Vec` (in favor of `Array::to_vec`)

biewers2 opened this issue · comments

Motivation

In the js-sys crate, I noticed the Array type implemented a to_vec method, and wanted to propose implementing the From trait in favor of this method to work nicer with Rust's type system.

I also found conversion between the JS Array type and Rust's Vec<...> may be common enough to warrant these trait implementations for easier conversion.

Proposed Solution

To put it simply, I would add the following impl's:

impl From<Vec<JsValue>> for Array {
    #[inline]
    fn from(value: Vec<JsValue>) -> Self {
        value.into_iter().collect()
    }
}

impl From<Array> for Vec<JsValue> {
    #[inline]
    fn from(value: Array) -> Self {
        value.into_iter().collect()
    }
}

A downside to this is that it would "hide" the performance impact if a user was doing the conversion implicitly (i.e. passing it to a function that takes an Into<Array> or Into<Vec<JsValue>>), since this conversion would have to cross the JS/Rust boundary for each access. This would have to be well documented in these implementations.

Alternatives

I attempted to do this for the borrowed versions of each, but I ran into some conflicts with trait implementations.
For example, when trying to impl<A: AsRef<[JsValue]>> From<A> for Array, the compiler warns about possible upstream future trait implementations. So I found specifying the owned values to be the most feasible. I'm very open to hearing what approaches others might have!

I don't believe we should do this as it's not really supported, as it has to go through the FFI boundary for each element. This hides the performance impact, as you already pointed out.

Thank you for the suggestion though!