Skip to content

frender-rs/convert-js

Repository files navigation

convert-js

Crates.io docs.rs GitHub license GitHub stars

[wip] convert between rust wasm and js

Current State

This crate is NOT production ready. Development is in alpha branch, with auto releasing. Release

You can find the latest alpha version in crates.io.

convert-js = "1.0.0-alpha.11"

ToJs trait is available for common types.

use convert_js::ToJs;

let v = Some("my_str");
v.to_js(); // "my_str" in js

let v: Option<i32> = None;
v.to_js(); // undefined in js

ToJs derive macro is available for structs;

use convert_js::ToJs;

/// NewType style struct can contain any type impl ToJs
#[derive(ToJs)]
struct Wrap(String);

/// Tuple struct
#[derive(ToJs)]
struct KeyValuePair(String, Option<js_sys::Object>);

/// Object struct
#[derive(ToJs)]
struct Position {
    x: f64,
    y: f64,
    data: KeyValuePair,
}

TODO

  • derive ToJs for enum
  • flatten
  • into, from try_from
  • FromJs trait and macro

Why not #[wasm_bindgen]

wasm-bindgen provides an api to export rust structs to js.

However, supported types are very limited. convert-js aims to support arbitrary data.

And it works more like a proxy between rust wasm and js runtime: The data is actually in wasm memory and wasm-bindgen generates a js class to proxy the data accessors and methods. That is why we must call free manually on exported objects in js to let rust know when to drop the data. (As wasm-bindgen documents, this issue may be resolved by weak references proposal in js). convert-js is designed to convert between rust and js rather than to proxy:

  • for js types (JsValue and imported #[wasm-bindgen] extern "C" types, e.g. js_sys::Array, web_sys::HtmlElement), pass them directly with wasm-bindgen
  • for rust types (primitives and arbitrary structs, enums), convert them to/from JsValue.

Why not serde ?

serde is a great framework for deserializing and serializing rust data structures. To communicate with js and wasm-bindgen, both serde-json and serde-wasm-bindgen are helpful. stdweb also provides the ability to pass values between rust wasm and rust.

However, the above libraries are all based on serde, whose data model are very limited. For example, there is no way to represent wasm_bindgen::closure::Closure in serde data model.

Thus, I created convert-js, to provide serde like apis for js specific serialization and deserialization. This crate is greatly inspired by the crates mentioned before. Thanks for the developers.