#wasm-bindgen #macro-derive #jsvalue #wasm-bindgen-futures

macro into-jsvalue-derive

derive into-jsvalue for enum return values in async wasm_bindgen functions

2 unstable releases

0.2.0 Jul 8, 2024
0.1.0 Jun 26, 2024

#369 in Procedural macros

MIT license

6KB

into_jsvalue - Rust Macro for Deriving From for JsValue

This crate provides a derive macro IntoJsValue for Rust that simplifies the implementation of From<T> for wasm_bindgen::JsValue. This crate is for a particular use case. wasm_bindgen only supports c-style enums. tsify allows us to get around this using serde-wasm-bindgen, but it only works for synchronous functions This crate adds a simple derive macro that will implement the neccassary From implementation

use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;

use into_jsvalue_derive::IntoJsValue;
use tsify::Tsify;

#[wasm_bindgen]
pub async fn test() -> Test { // this works because of the tsify macro above our enum 
    Test::One(String::new())
}

#[wasm_bindgen]
pub async fn async_test() -> Test { // this does not work. It need From<Test> for JsValue to be implemented
    Test::One(String::new())
}

#[derive(Serialize, Deserialize, Tsify)]
#[wasm_bindgen] // This does not work because wasm_bindgen only supports c-style enums
#[tsify(into_wasm_abi, from_wasm_abi)] // this allows test() to work, but not async test. It does not impl the required trait 
pub enum Test {
    One(String),
    Two(String, String),
}

Usage

  1. Add this crate as a dependency in your Cargo.toml:
[dependencies]
into-jsvalue-derive = "0.1.0"  # Replace with the actual version
# include serde, wasm-bindgen and serde-wasm-bindgen
  1. Use the #[derive(IntoJsValue)] attribute on your struct definition: Note:: the struct must impl serde::Serialize
#[derive(Serialize, IntoJsValue)]
struct MyStruct {
  field1: i32,
  field2: String,
}

The macro will generate the following code.

// generated by the macro
impl From<MyStruct> for JsValue{
  fn from(value: MyStruct) -> Self {
    let res = serde_wasm_bindgen::to_value(&value);
    wasm_bindgen::UnwrapThrowExt::expect_throw(
      res,
      format!("failed to convert MyStruct to a JsValue"),
    )
  }
}

Important Note:

This crate requires serde, wasm_bindgen, and serde_wasm_bindgen crates to be present in your project.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Dependencies

~1–2MB
~36K SLoC