#wasm-bindgen #constructor #macro #duck-typing

ducktor

一个宏,用于生成构造函数,从JsValue使用鸭子类型实例化结构体

1个不稳定版本

0.1.0 2023年6月21日

#1549WebAssembly

MIT许可证

7KB
83

ducktor

ducktor是一个Rust crate,允许您使用鸭子类型从wasm_bindgen::JsValue创建类型。

使用ducktor,您可以定义一个结构体,指定从JsValue期望的字段和类型,然后使用#[derive(FromJsValue)]宏实现它的From<JsValue>。这样,您就可以使用Rust的类型系统和语法在WebAssembly中处理JavaScript对象。

为什么

  • 在导出的类型上使用#[wasm_bindgen]要求导出函数的输入是wasm-bindgen创建的类,这并不总是可能的
  • 使用#[wasm_bindgen] extern "C" { ... }导入类型使得类型在Rust中不可创建。这在需要从Rust创建类型实例的共享代码中成为问题。

解决方案

认识 ducktor!一个基于鸭式类型检查的结构体构造器。它允许您像平常一样创建一个结构体。然后,您可以使用宏 #[derive(FromJsValue)] 为您的结构体实现 From<JsValue>。这使得您可以使用结构体的 from 方法从一个 JsValue 创建其实例。

内部,它定义并导入了一个与结构体字段和类型匹配的、不存在的JavaScript类型。然后使用 JsValue::unchecked_refJsValue 强制转换为该类型,然后通过从JS类型获取每个字段的值来创建结构体。

示例

use ducktor::FromJsValue;

// Define a struct that represents a JavaScript object with an a field and a b field
#[derive(FromJsValue)]
struct Data {
    a: u32,
    b: String,
}

// Create a JavaScript object that conforms to the Data struct
fn roundtrip() {
    let data = js_sys::Object::new();
    js_sys::Reflect::set(&data, &"a".into(), &42.into()).unwrap();
    js_sys::Reflect::set(&data, &"b".into(), &"string".into()).unwrap();

    // Convert the JsValue to a Data using the `from_js_value` method
    let data: Data = Data::from(&data.into());
    assert_eq!(data.a, 42);
    assert_eq!(data.b, "string");
}

依赖项

~280–730KB
~17K SLoC