1

I want to create a function find which accepts a matrix argument with type Vec<Vec<isize>> and returns another matrix with type Vec<Vec<(usize, usize)>>. Unfortunately, wasm_bindgen complains that types are not "compatible".

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
  ^^^^^^^^^^^^ <- Error
pub fn find (matrix: Vec<Vec<isize>>, threshold: usize) -> Vec<Vec<(usize, usize)>> {
   // cut
}

Error

rustc: the trait bound `Vec<isize>: JsObject` is not satisfied
   the following other types implement trait `JsObject`:
     Array
     ArrayBuffer
     BigInt
     BigInt64Array
     BigUint64Array
     Boolean
     Collator
     CompileError
   and 47 others
   required because of the requirements on the impl of `FromWasmAbi` for `Box<[Vec<isize>]>`
3. rustc: the trait bound `Vec<(usize, usize)>: JsObject` is not satisfied
   the following other types implement trait `JsObject`:
     Array
     ArrayBuffer
     BigInt
     BigInt64Array
     BigUint64Array
     Boolean
     Collator
     CompileError
   and 47 others
   required because of the requirements on the impl of `IntoWasmAbi` for `Box<[Vec<(usize, usize)>]>`

What function signature to use in this case?

Roman Mahotskyi
  • 4,576
  • 5
  • 35
  • 68
  • 1
    It sounds like you can't nest `Vec` so you have 2 options. You could use a `Vec` and convert each `JsValue` to your desired type one at a time (https://stackoverflow.com/a/59720484/5987669). Alternatively, you could derive `#[wasm_bindgen]` on a struct to make it implement `JsObject` to get around the no nested `Vec`s issue. Personally, I would go with the latter option since I don't think tuples are allowed either way and you need to decide how they will be treated. In this case, I think the closest option may be to turn them into 2 element arrays (another `Vec` layer). – Locke Aug 27 '22 at 20:22
  • I'd go with receiving and returning a JsValue and handling the conversions myself. [Related answer](https://stackoverflow.com/questions/70838939/converting-vecrtcicecandidate-into-jsvalue/70842475#70842475). – Caesar Aug 28 '22 at 02:39

2 Answers2

0

I had the same problem and I know I am not solving your direct problem, but the way i solved mine was rather than returning vec of undefined sizes in a vec was by converting the inner vec to Uint8Array using js_sys. the best way i can show it is by this. then you can wrap the arrays in arrays is my guess. From my understanding it is because the compiler need to know the size of the array which undefined usize does not allow.

use wasm_bindgen::prelude::*;
use js_sys;
    
#[wasm_bindgen]
pub fn find (matrix: Vec<Vec<isize>>, threshold: usize) -> Vec<js_sys::Uint8Array> {
    // cut
}
kelsny
  • 23,009
  • 3
  • 19
  • 48
0
#[wasm_bindgen]
pub fn find(matrix: JsValue, threshold: usize) -> js_sys::Array{
    // cut
    let mut res: Vec<Vec<(usize, usize)>> = vec![
        vec![(1 as usize, 2 as usize)],
        vec![(2 as usize, 3 as usize)]];
    let mut ans:js_sys::Array = js_sys::Array::new();
    let matrix: Vec<Vec<isize>> = matrix.into_serde().unwrap_or(vec![]);

    // convert res to ans
    ans
}

Cognia
  • 437
  • 3
  • 10