2

I am trying to use a Web API that contains a method which accepts an array of strings from Rust.

I am using web_sys to "talk" to the JS API, but I can't find a way to pass in an array of static Strings into it.

In Rust, unfortunately, the type of the parameter is mistakenly declared as arg: &JsValue, so I can pass just about anything into it and it still compiles, but crashes in the browser.

How can I create an array of strings in Rust that can be used as a &JsValue?

Renato
  • 12,940
  • 3
  • 54
  • 85

2 Answers2

2

This converts &[&str] to JsValue:

fn js_array(values: &[&str]) -> JsValue {
    return JsValue::from(values.into_iter()
        .map(|x| JsValue::from_str(x))
        .collect::<Array>());
}
Renato
  • 12,940
  • 3
  • 54
  • 85
1

With the use of js_sys you can create arrays like this:

use js_sys::Array;

#[wasm_bindgen]
pub fn strings() -> Array {
    let arr = Array::new_with_length(10);
    for i in 0..arr.length() {
        let s = JsValue::from_str(&format!("str {}", i));
        arr.set(i, s);
    }
    arr
}

But can you give an example with string literals like ["hello"].to_array()

For the requested example you cannot use any method to convert directly. Therefore, you have to use a helper function:

#[wasm_bindgen]
pub fn strings() -> Array {
    to_array(&["str 1", "str 2"])
}

pub fn to_array(strings: &[&str] ) -> Array {

    let arr = Array::new_with_length(strings.len() as u32);
    for (i, s) in strings.iter().enumerate() {
        arr.set(i as u32, JsValue::from_str(s));
    }
    arr
}
schrieveslaach
  • 1,689
  • 1
  • 15
  • 32
  • Thanks! But can you give an example with string literals like `["hello"].to_array()`? – Renato May 07 '20 at 14:50
  • Have a look at the new version – schrieveslaach May 07 '20 at 15:00
  • as I mention in the question, I need a `&JsValue`, not an `Array` so the code does not compile. Doing `JsValue::from(array)` does not seem to be working. – Renato May 07 '20 at 15:26
  • Could test your code with a changed version of the example: ``` #[wasm_bindgen] pub fn strings() -> JsValue { to_array(&["str 1", "str 2"]).into() } ``` – schrieveslaach May 08 '20 at 06:10
  • Does `JsValue::from_str` involve serialization? Or is it like passing pointers? – User Oct 24 '20 at 18:13
  • 1
    @Ixx From the docs: “The utf-8 string provided is copied to the JS heap and the string will be owned by the JS garbage collector.” https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html So there is copying involved but no serialization. – schrieveslaach Oct 26 '20 at 07:04