Reputation: 550
I'm trying to implement a method to send an array of u32
(eventually an array of arrays of usize
, if possible), since you can't just declare a public array field on a wasm_bindgen
type. However, using the example outlined in the wasm_bindgen
PR 1749, I can't seem to convert arrays or slices to a js_sys::Array
; it only works for Vec
s. My question is, why? See below
pub fn test() -> js_sys::Array {
let arr: [u32; 5] = [0,1,2,3,4];
let slice = &arr[0..2];
let vec: Vec<u32> = vec![0,1,2];
arr.into_iter().map(JsValue::from).collect() // This doesn't work
slice.into_iter().map(JsValue::from).collect() // Also doesn't work
vec.into_iter().map(JsValue::from).collect() // Works as expected!
}
The specific error is: the trait 'wasm_bindgen::cast::JsCast' is not implemented for 'u32'
The array and slice examples don't seem to work for any number type, ints or floats. My only thought is because the implementation in PR 1749 seems to expect a ref, and arrays are allocated on the stack that the FromIterator
is not valid for items in an array?
Is there some other way to achieve what I'm trying to do with the array (passing across the boundary to JS through wasm_bindgen
), or if not, why? I'd be very interested to know.
Upvotes: 2
Views: 1015
Reputation: 15105
Although Rust arrays and slices have an into_iter
method it returns the same Iterator
as the iter
method does which iterates over references to values instead of the values themselves. Yes, this is confusing. Since JsValue::from
is implemented for u32
but not for &u32
you can take your Iterator<Item = &u32>
and convert it to a Iterator<Item = u32>
using the copied
method. Fixed working examples:
use wasm_bindgen::JsValue;
use js_sys::Array;
fn array_to_js_array(array: [u32; 5]) -> Array {
array.iter().copied().map(JsValue::from).collect()
}
fn slice_to_js_array(slice: &[u32]) -> Array {
slice.iter().copied().map(JsValue::from).collect()
}
fn vec_to_js_array(vec: Vec<u32>) -> Array {
vec.into_iter().map(JsValue::from).collect()
}
Upvotes: 2