1个不稳定版本
0.1.0 | 2023年5月1日 |
---|
#575 in Proc宏
91 每月下载量
56KB
1.5K SLoC
一个使使用wasm-bindgen
更容易的crate。
该crate包含一个wasm_bindgen_struct
宏,可以用来声明wasm-bindgen
类型,并像使用普通Rust结构体一样实现getter/setter。它还可以用于实现类型的方法,包括内联映射来克服wasm-bindgen-futures
的限制。
示例
// Or you can use this instead to avoid needing to import
// the macro throughout your crate
// #[macro_use]
// extern crate wasm_bindgen_struct;
use wasm_bindgen_struct::wasm_bindgen_struct;
#[wasm_bindgen_struct]
// `module` here means this type comes from the JS "my-module" module
// with the class name `aAnotherType`
#[opts(module = "my-module", js_name = "AnotherType")]
struct MyJsType {
// field names are automatically converted to `camelCase`
field_a: String,
// ...but can be manually specified if needed
#[opts(js_name = "field_b")]
field_b: String,
}
#[wasm_bindgen_struct]
#[opts(module = "my-module")]
impl MyJsType {
// Automatically gets the `static_method_of = MyJsType` applied,
// as well as `catch` due to the `Result`
fn apple() -> Result<String, JsValue>;
// `async` functions in `wasm-bindgen` can only currently return
// `()`, `JsValue`, or Result<_, JsValue>`, where `_` is one of
// the two previously mentioned types. We use `MapValue<T, U>`
// to tell the macro that the binding method should return `T`,
// but we'll map the value to `U`
async fn oranges(&self) -> MapValue<JsValue, String> {
self
.oranges_js()
.await
.unchecked_into::<js_sys::JsString>()
.into()
}
}
上面的代码展开为
// For getters/setters
#[wasm_bindgen(module = "my-module")]
extern "C" {
#[wasm_bindgen(js_name = "AnotherType")]
type MyJsType;
#[wasm_bindgen(
method,
getter,
js_class = "AnotherType",
js_name = "fieldA"
)]
fn field_a(this: &MyJsType) -> String;
#[wasm_bindgen(
method,
setter,
js_class = "AnotherType",
js_name = "fieldA"
)]
fn set_field_a(this: &MyJsType, value: String);
#[wasm_bindgen(
method,
getter,
js_class = "AnotherType",
js_name = "field_b"
)]
fn field_b(this: &MyJsType) -> String;
#[wasm_bindgen(
method,
setter,
js_class = "AnotherType",
js_name = "field_b"
)]
fn set_field_b(this: &MyJsType, value: String);
}
// And for methods
impl MyJsType {
fn apple() -> Result<String, JsValue> {
#[wasm_bindgen(module = "my-module")]
extern "C" {
#[wasm_bindgen(static_method_of = MyJsType, js_name = "apple")]
#[wasm_bindgen(catch)]
fn apple_js() -> Result<String, JsValue>;
}
Self::apple_js()
}
async fn oranges(&self) -> String {
#[wasm_bindgen(module = "my-module")]
extern "C" {
#[wasm_bindgen(method, js_name = "oranges")]
async fn oranges_js(this: &MyJsType) -> JsValue;
}
self
.oranges_js()
.await
.unchecked_into::<js_sys::JsString>()
.into()
}
}
#[opts(...)]
在结构体上
-
dbg:
bool
在
Type
上显示宏的格式化输出作为警告 -
on:
Type
允许使用结构体语法使用现有类型。
示例
#[wasm_bindgen] extern "C" { type JsType; } #[wasm_bindgen_struct] #[opts(on = JsType)] // Struct can be named anything, it doesn't matter struct JsType { field_1: bool, }
-
<unknown>
未知属性,如文档注释,将被转发到
type MyType
声明,或者在on
的情况下被忽略。
#[opts(...)]
在结构体字段上
#[opts(...)]
在 impl
上
-
调试: 布尔型
在
Type
上显示宏的格式化输出作为警告
#[opts(...)]
在 impl
方法上
- 构造函数:
bool
- final_:
bool
- structural:
bool
- getter:
bool
- setter:
bool
- 索引获取器:
bool
- 索引设置器:
bool
- 索引删除器:
bool
- js_name:
Lit
- 可变参数:
bool
特殊类型的处理
-
结果<T, E>
意味着
catch
。 -
MapValue<T, U>
允许指定生成的
wasm-bindgen
绑定的类型,以及实际的方法类型。这允许在绑定的方法和输出方法之间进行任意转换。示例
#[wasm_bindgen_struct] struct JsType; #[wasm_bindgen_struct] impl JsType { async fn get_async_string(&self) -> MapValue<JsValue, String> { self .get_async_string_js() .await .unchecked_into::<js_sys::JsString>() .into() } }
重要提示
MapValue
是一个伪类型,仅在宏的作用域内存在。即,此类型在#[wasm_bindgen_struct] impl { /* ... */ }
之外不存在,因此无需导入。
依赖
~1–1.4MB
~30K SLoC