mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-19 16:01:23 +00:00
Implement Deref
for all imported JS types
This commit implements the first half of [RFC #5] where the `Deref` trait is implemented for all imported types. The target of `Deref` is either the first entry of the list of `extends` attribute or `JsValue`. All examples using `.as_ref()` with various `web-sys` types have been updated to the more ergonomic deref casts now. Additionally the `web-sys` generation of the `extends` array has been fixed slightly to explicitly list implementatoins in the hierarchy order to ensure the correct target for `Deref` is chosen. [RFC #5]: https://github.com/rustwasm/rfcs/blob/master/text/005-structural-and-deref.md
This commit is contained in:
55
guide/src/web-sys/inheritance.md
Normal file
55
guide/src/web-sys/inheritance.md
Normal file
@ -0,0 +1,55 @@
|
||||
# Inheritance in `web-sys`
|
||||
|
||||
Inheritance between JS classes is the bread and butter of how the DOM works on
|
||||
the web, and as a result it's quite important for `web-sys` to provide access to
|
||||
this inheritance hierarchy as well! There are few ways you can access the
|
||||
inheritance hierarchy when using `web-sys`.
|
||||
|
||||
### Accessing parent classes using `Deref`
|
||||
|
||||
Like smart pointers in Rust, all types in `web_sys` implement `Deref` to their
|
||||
parent JS class. This means, for example, if you have a `web_sys::Element` you
|
||||
can create a `web_sys::Node` from that implicitly:
|
||||
|
||||
```rust
|
||||
let element: &Element = ...;
|
||||
|
||||
element.append_child(..); // call a method on `Node`
|
||||
|
||||
method_expecting_a_node(&element); // coerce to `&Node` implicitly
|
||||
|
||||
let node: &Node = &element; // explicitly coerce to `&Node`
|
||||
```
|
||||
|
||||
Using `Deref` allows ergonomic transitioning up the inheritance hierarchy to the
|
||||
parent class and beyond, giving you access to all the methods using the `.`
|
||||
operator.
|
||||
|
||||
### Accessing parent classes using `AsRef`
|
||||
|
||||
In addition to `Deref`, the `AsRef` trait is implemented for all types in
|
||||
`web_sys` for all types in the inheritance hierarchy. For example for the
|
||||
`HtmlAnchorElement` type you'll find:
|
||||
|
||||
```rust
|
||||
impl AsRef<HtmlElement> for HtmlAnchorElement
|
||||
impl AsRef<Element> for HtmlAnchorElement
|
||||
impl AsRef<Node> for HtmlAnchorElement
|
||||
impl AsRef<EventTarget> for HtmlAnchorElement
|
||||
impl AsRef<Object> for HtmlAnchorElement
|
||||
impl AsRef<JsValue> for HtmlAnchorElement
|
||||
```
|
||||
|
||||
You can use `.as_ref()` to explicitly get a reference to any parent class from
|
||||
from a type in `web_sys`. Note that because of the number of `AsRef`
|
||||
implementations you'll likely need to have type inference guidance as well.
|
||||
|
||||
### Accessing child clases using `JsCast`
|
||||
|
||||
Finally the `wasm_bindgen::JsCast` trait can be used to implement all manner of
|
||||
casts between types. It supports static unchecked casts between types as well as
|
||||
dynamic runtime-checked casts (using `instanceof`) between types.
|
||||
|
||||
More documentation about this can be found [on the trait itself][jscast]
|
||||
|
||||
[jscast]: https://docs.rs/wasm-bindgen/0.2/wasm_bindgen/trait.JsCast.html
|
Reference in New Issue
Block a user