7个版本

1.0.0-alpha.152022年2月23日
1.0.0-alpha.142022年1月22日
1.0.0-alpha.112021年11月30日

#557WebAssembly

29 每月下载量
3 个包中使用 (2 直接使用)

MIT 许可证

22KB
539

convert-js

Crates.io docs.rs GitHub license GitHub stars

[wip] 在rust wasm和js之间转换

当前状态

此包**尚未准备好生产使用**。开发处于alpha分支,带有自动发布。 发布

您可以在 crates.io 中找到最新的alpha版本。

convert-js = "1.0.0-alpha.11"

ToJs trait可用于常见类型。

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宏可用于结构体;

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,
}

待办事项

  • 为枚举推导 ToJs
  • 扁平化
  • into, from try_from
  • FromJs trait和宏

为什么不使用 #[wasm_bindgen]

wasm-bindgen 提供了一个API将Rust结构体导出到js。

然而,支持的类型非常有限。 convert-js 的目标是支持任意数据。

并且它更像是rust wasm和js运行时的代理:数据实际上在wasm内存中,wasm-bindgen 生成一个js类来代理数据访问器和方法的调用。这就是为什么我们必须在js中手动调用导出对象上的 free,让rust知道何时释放数据。(如 wasm-bindgen 文档中所述,这个问题可能通过js中的弱引用提议 解决)。 convert-js 被设计为在rust和js之间**转换**,而不是作为代理

  • 对于js类型(例如JsValue和导入的#[wasm-bindgen] extern "C"类型,例如js_sys::Arrayweb_sys::HtmlElement),可以直接通过wasm-bindgen传递。
  • 对于rust类型(原始类型和任意结构体、枚举),将它们转换为/从JsValue

为什么不使用serde

serde是一个用于反序列化和序列化rust数据结构的优秀框架。为了与js和wasm-bindgen通信,serde-jsonserde-wasm-bindgen都非常有用。stdweb还提供了在rust wasm和rust之间传递值的能力。

然而,上述库都是基于serde的,其数据模型非常有限。例如,在serde数据模型中无法表示wasm_bindgen::closure::Closure

因此,我创建了convert-js,以提供类似于serde的api进行js特定的序列化和反序列化。这个crate深受前面提到的crate的启发。感谢开发者们。

依赖关系

~3.5MB
~66K SLoC