#wasm-bindgen #bindgen

wasm-bindgen-struct

通过宏使声明wasm-bindgen导入变得容易

1个不稳定版本

0.1.0 2023年5月1日

#575 in Proc宏

Download history 31/week @ 2024-03-13 27/week @ 2024-03-20 8/week @ 2024-03-27 33/week @ 2024-04-03 33/week @ 2024-04-10 101/week @ 2024-04-17 93/week @ 2024-04-24 65/week @ 2024-05-01 68/week @ 2024-05-08 81/week @ 2024-05-15 36/week @ 2024-05-22 2/week @ 2024-05-29 25/week @ 2024-06-05 12/week @ 2024-06-12 32/week @ 2024-06-19 22/week @ 2024-06-26

91 每月下载量

MIT许可证

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(...)]在结构体上

#[opts(...)]在结构体字段上

#[opts(...)]impl

#[opts(...)]impl 方法上

特殊类型的处理

  • 结果<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