是否可以在另一个板条箱中定义#[wasm_bindgen]公共结构和函数?

Leo*_*Ven 10 rust wasm-bindgen

我有一个lib包含大量结构和实现的板条箱。然后我还有另一个叫做web它将核心移植lib到网络上的工具。还有一种api情况是我希望应用程序位于服务器端。

  • myproject-api
  • myproject-lib
  • myproject-web

我不想要的是将所有wasm依赖项添加到lib, 仅在web项目中并将主库的部分内容公开到网络。in#[wasm_bindgen]中定义的结构是否可能?myproject-libmyproject-web

kmd*_*eko 12

不直接。这#[wasm_bindgen]属性依赖于能够解析结构和实现以生成绑定。您必须为要绑定的属性创建包装类型和函数。

说说你的myproject-lib样子:

pub struct MyStruct {
    pub foo: i32,
}

impl MyStruct {
    pub fn bar(&self) {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

绑定的实现方式如下myproject-web

use myproject_lib::*;
use wasm_bindgen::prelude::*;

#[wasm_bindgen(js_name = MyStruct)]
pub struct MyStructWrapper(MyStruct);

#[wasm_bindgen(js_class = MyStruct)]
impl MyStructWrapper {
    #[wasm_bindgen(getter)]
    pub fn foo(&self) -> i32 {
        self.0.foo
    }

    #[wasm_bindgen(setter)]
    pub fn set_foo(&mut self, value: i32) {
        self.0.foo = value;
    }

    pub fn bar(&self) {
        self.0.bar();
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,一切都非常明确地完成。

  • 封装原始结构并使用原始名称导出js_namejs_class
  • 列出并实现getter 和 setter公共字段的
  • 在原始结构体中添加简单的转发函数。

我相信更广泛使用的方法是将绑定添加到原始库,但仅由功能启用。这可以避免大量重复,实现起来也不那么麻烦,并确保绑定始终保持同步。

添加一个"wasm" 功能wasm-bindgen,该功能将作为选择加入的依赖项添加到您的Cargo.toml

pub struct MyStruct {
    pub foo: i32,
}

impl MyStruct {
    pub fn bar(&self) {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用cfgcfg_attrwasm_bindgen在启用该功能时启用该属性:

#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;

#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct MyStruct {
    pub foo: i32,
}

#[cfg_attr(feature = "wasm", wasm_bindgen)]
impl MyStruct {
    pub fn bar(&self) {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)