How do I accept and return a Vec in a Rust to a Wasm function?

I have the following structure setup:

#[derive(Debug, Copy, Clone)]
pub enum Fs{
    A,
    B,
    C,
}

pub struct F {
    ms: MS,
    health: Health,
    pos: POS,
}
impl F {
    fn new(which: Fs) -> Self {
        let (ms, health) = match which {
            Fs::A=> (5, 5),
            Fs::B=> (10, 10),
            Fs::C=> (15, 15),
        };
        let pos = spawn_point_R();
        Self {
            ms,
            health,
            pos,
        }
    }
}

And the following function:

#[wasm_bindgen]
pub fn createF(which: Fs, mut amount: i16) -> Vec<F>  {
    let mut fs: Vec<F> = Vec::new();
    while amount != 0 {
        fs.push(F::new(which));
        amount-=1;
    }
    fs
}

which gives the following error at #[wasm_bindgen]:

the trait bound Fs: FromWasmAbi is not satisfied

Can I resolve this?

I wanted to do my structuring in Rust, but maybe it'd just be better to do in JS?

In general, you can't return values with a type that is non-trivial from an ABI point of view, i.e., anything other than primitive numbers, String (which is special-cased), or one of the (U)Int[8/16/32/64]Array flat buffer types.

If you need to return a complex structure to JavaScript from WASM (or vice versa), your best bet is to (de)serialize it to/from JSON and convert it to a JsValue object via the from_serde() and into_serde() methods.

Okay, I think I read a solution like so as well. I doubt it's very efficient, and read the same, so hopefully something else exists, or I'll pass on doing it this way :confused:

Also, I'm only using the Vec in Rust, I don't need to read or use it in JS. But I can't even call a function which calls another function in Rust which creates the Vec, it will still show the error:

the trait bound Fs: FromWasmAbi is not satisfied

You should probably not worry about efficiency unless you have measured by actual benchmarks (or better yet, real usage data) that the speed of returning JSON to WASM matters. Write for clarity first, and optimize later if/when needed.

1 Like

This*. Sorry. At least that would be another way I thought I could avoid it.

The implementation of a function doesn't affect its ABI/interface; the problem now becomes the Fs type itself, not the Vec. Unfortunately, support for enums in wasm_bindgen is genuinely not too good, so I until the situation improves, I usually just use const string literals instead.

So regardless if I use the Rust code in JS, it will need to be converted to WASM anyway? And that's just the issue with these types.

Sorry I don't follow. Your setup clearly includes wasm_bindgen, which suggests that you do want to compile the Rust code to WASM in order to interact with JavaScript. What else do you have in mind?

Think I found the issue, thanks for suggesting

I looked into it. Might have another issue but hopefully not.