[wasm_bindgen] struct attribute

I'mn trying to get a project to work on WASM, and in the process I've noticed that Result<T, E> and Option<T> are not always available for use in methods when tagging a struct with the #[wasm_bindgen] attribute. So e.g.

enum Err;

#[wasm_bindgen]
struct Foo {
   // definition
} 

#[wasm_bindgen]
impl Foo {
   pub fn do_foo(&self) -> Result<String, Err> { // <- The Result in return position here is rejected when compiling to WASM
      // impl
   }
}

What I don't understand is why?
Those types are crucial to properly building software in Rust, so it seems to me there must be a very good reason. But I cannot imagine what it would be, other than the seeming inability of enums in general to cross the ABI boundary. But if that's the reason, it just transforms the question to "why can't enums be compiled to WASM?"

besides not being able to map enum types, it doesn't know what to do with Err in the error position
only Result<T, JsValue> is available
see Result<T, JsValue> - The `wasm-bindgen` Guide — it exhaustively lists all the types that can be exported—JsValue is the only option for Results error, this will result in an exception on the javascript side

Yeah I've seen the list - and I suppose I can work around the "Result-is-sort-of-available" deal by just matching on the Result and serializing the destructured Ok and Err variants.

What I meant to ask is, why doesn't it know how to handle enums? Seems like a core feature to me.

it probably doesn't help that javascript has no enums natively, you could submit a proposal at the rust-wasm github how to map rust enums to some javascript type and who knows it might get adopted

Naively I'd expect enums to be laid out similarly as on native platforms, as those don't have any notion of enum either, neither full sum types nor C-style enums.
There may be some reason that that has not been done, though if there is, I don't know what.

Right—it does map to the native wasm platform otherwise you wouldn't be able to use enums as all, not even internally !
The problem is the interface, which would need to be somehow user friendly to javascript. Returning, say, a byte sequence with the native representation would likely be rejected. If you do want that, I think you can return a pointer to it you really want. Then you have the binary representation in an ArrayBuffer and can map it however you want on the javascript side.
(though I'd suggest to choose a type that does go over the API boundary and not bother)

1 Like