mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-09 05:36:05 +00:00
Add more docs to DESIGN about configuration attributes
This commit is contained in:
parent
4716752991
commit
78e3537279
129
DESIGN.md
129
DESIGN.md
@ -872,6 +872,135 @@ Under the hood this generates shims that do a bunch of translation, but it
|
|||||||
suffices to say that a call in wasm to `foo` should always return
|
suffices to say that a call in wasm to `foo` should always return
|
||||||
appropriately.
|
appropriately.
|
||||||
|
|
||||||
|
## Customizing import behavior
|
||||||
|
|
||||||
|
The `#[wasm_bindgen]` macro supports a good amount of configuration for
|
||||||
|
controlling precisely how imports are imported and what they map to in JS. This
|
||||||
|
section is intended to hopefully be an exhaustive reference of the
|
||||||
|
possibilities!
|
||||||
|
|
||||||
|
* `catch` - as we saw before the `catch` attribute allows catching a JS
|
||||||
|
exception. This can be attached to any imported function and the function must
|
||||||
|
return a `Result` where the `Err` payload is a `JsValue`, like so:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
#[wasm_bindgen(catch)]
|
||||||
|
fn foo() -> Result<(), JsValue>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the imported function throws an exception then `Err` will be returned with
|
||||||
|
the exception that was raised, and otherwise `Ok` is returned with the result
|
||||||
|
of the function.
|
||||||
|
|
||||||
|
* `constructor` - this is used to indicate that the function being bound should
|
||||||
|
actually translate to a `new` constructor in JS. The final argument must be a
|
||||||
|
type that's imported from JS, and it's what'll get used in JS:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
type Foo;
|
||||||
|
#[wasm_bindgen(constructor)]
|
||||||
|
fn new() -> Foo;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will attach the `new` function to the `Foo` type (implied by
|
||||||
|
`constructor`) and in JS when this function is called it will be equivalent to
|
||||||
|
`new Foo()`.
|
||||||
|
|
||||||
|
* `method` - this is the gateway to adding methods to imported objects or
|
||||||
|
otherwise accessing properties on objects via methods and such. This should be
|
||||||
|
done for doing the equivalent of expressions like `foo.bar()` in JS.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
type Foo;
|
||||||
|
#[wasm_bindgen(method)]
|
||||||
|
fn work(this: &Foo);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The first argument of a `method` annotation must be a borrowed reference (not
|
||||||
|
mutable, shared) to the type that the method is attached to. In this case
|
||||||
|
we'll be able to call this method like `foo.work()` in JS (where `foo` has
|
||||||
|
type `Foo`).
|
||||||
|
|
||||||
|
In JS this invocation will correspond to accessing `Foo.prototype.work` and
|
||||||
|
then calling that when the import is called. Note that `method` by default
|
||||||
|
implies going through `prototype` to get a function pointer.
|
||||||
|
|
||||||
|
* `js_namespace` - this attribute indicates that the JS type is accessed through
|
||||||
|
a particular namespace. For example the `WebAssembly.Module` APIs are all
|
||||||
|
accessed through the `WebAssembly` namespace. The `js_namespace` can be
|
||||||
|
applied to any import and whenever the generated JS attempts to reference a
|
||||||
|
name (like a class or function name) it'll be accessed through this namespace.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
#[wasm_bindgen(js_namespace = console)]
|
||||||
|
fn log(s: &str);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This is an example of how to bind `console.log(x)` in Rust. The `log` function
|
||||||
|
will be available in the Rust module and will be invoked as `console.log` in
|
||||||
|
JS.
|
||||||
|
|
||||||
|
* `getter` and `setter` - these two attributes can be combined with `method` to
|
||||||
|
indicate that this is a getter or setter method. A `getter`-tagged function by
|
||||||
|
default accesses the JS property with the same name as the getter function. A
|
||||||
|
`setter`'s function name is currently required to start with "set\_" and the
|
||||||
|
property it accesses is the suffix after "set\_".
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
type Foo;
|
||||||
|
#[wasm_bindgen(method, getter)]
|
||||||
|
fn property(this: &Foo) -> u32;
|
||||||
|
#[wasm_bindgen(method, setter)]
|
||||||
|
fn set_property(this: &Foo, val: u32);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here we're importing the `Foo` type and defining the ability to access each
|
||||||
|
object's `property` property. The first function here is a getter and will be
|
||||||
|
available in Rust as `foo.property()`, and the latter is the setter which is
|
||||||
|
accessible as `foo.set_property(2)`. Note that both functions have a `this`
|
||||||
|
argument as they're tagged with `method`.
|
||||||
|
|
||||||
|
Properties in JS are accessed through `Object.getOwnPropertyDescriptor`. Note
|
||||||
|
that this typically only works for class-like-defined properties which aren't
|
||||||
|
just attached properties on any old object. For accessing any old property on
|
||||||
|
an object we can use...
|
||||||
|
|
||||||
|
* `structural` - this is a flag to `method` annotations which indicates that the
|
||||||
|
method being accessed (or property with getters/setters) should be accessed in
|
||||||
|
a structural fashion. For example methods are *not* accessed through
|
||||||
|
`prototype` and properties are accessed on the object directly rather than
|
||||||
|
through `Object.getOwnPropertyDescriptor`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
type Foo;
|
||||||
|
#[wasm_bindgen(method, structural)]
|
||||||
|
fn bar(this: &Foo);
|
||||||
|
#[wasm_bindgen(method, getter, structural)]
|
||||||
|
fn baz(this: &Foo) -> u32;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The type here, `Foo`, is not required to exist in JS (it's not referenced).
|
||||||
|
Instead wasm-bindgen will generate shims that will access the passed in JS
|
||||||
|
value's `bar` property to or the `baz` property (depending on the function).
|
||||||
|
|
||||||
## Wrapping up
|
## Wrapping up
|
||||||
|
|
||||||
That's currently at least what `wasm-bindgen` has to offer! If you've got more
|
That's currently at least what `wasm-bindgen` has to offer! If you've got more
|
||||||
|
Loading…
x
Reference in New Issue
Block a user