mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-05-28 13:11:22 +00:00
Merge pull request #813 from fitzgen/duck-typed-interfaces
Duck typed interfaces
This commit is contained in:
commit
4e86ecd2c5
@ -64,6 +64,7 @@ members = [
|
||||
"examples/closures",
|
||||
"examples/comments",
|
||||
"examples/console_log",
|
||||
"examples/duck-typed-interfaces",
|
||||
"examples/dom",
|
||||
"examples/fetch",
|
||||
"examples/guide-supported-types-examples",
|
||||
|
4
examples/duck-typed-interfaces/.gitignore
vendored
Normal file
4
examples/duck-typed-interfaces/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
package-lock.json
|
||||
rust_duck_typed_interfaces.js
|
||||
rust_duck_typed_interfaces_bg.js
|
||||
rust_duck_typed_interfaces_bg.wasm
|
10
examples/duck-typed-interfaces/Cargo.toml
Normal file
10
examples/duck-typed-interfaces/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "rust-duck-typed-interfaces"
|
||||
version = "0.1.0"
|
||||
authors = ["The wasm-bindgen Developers"]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = { path = "../.." }
|
14
examples/duck-typed-interfaces/README.md
Normal file
14
examples/duck-typed-interfaces/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Duck-Typed Interfaces Example
|
||||
|
||||
This directory is an example of using duck-typed JS interfaces with `wasm-bindgen`.
|
||||
|
||||
You can build and run the example with:
|
||||
|
||||
```
|
||||
$ ./build.sh
|
||||
```
|
||||
|
||||
(or running the commands on Windows manually)
|
||||
|
||||
and then opening up `http://localhost:8080/` in a web browser should show a
|
||||
smiley face drawn on canvas by Rust and WebAssembly.
|
15
examples/duck-typed-interfaces/build.sh
Executable file
15
examples/duck-typed-interfaces/build.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# For more coments about what's going on here, see the `hello_world` example
|
||||
|
||||
set -ex
|
||||
cd "$(dirname $0)"
|
||||
|
||||
cargo +nightly build --target wasm32-unknown-unknown
|
||||
|
||||
cargo +nightly run --manifest-path ../../crates/cli/Cargo.toml \
|
||||
--bin wasm-bindgen -- \
|
||||
../../target/wasm32-unknown-unknown/debug/rust_duck_typed_interfaces.wasm --out-dir .
|
||||
|
||||
npm install
|
||||
npm run serve
|
21
examples/duck-typed-interfaces/duck-typed-interfaces.js
Normal file
21
examples/duck-typed-interfaces/duck-typed-interfaces.js
Normal file
@ -0,0 +1,21 @@
|
||||
import { make_em_quack_to_this } from "./rust_duck_typed_interfaces";
|
||||
|
||||
// All of these objects implement the `Quacks` interface!
|
||||
|
||||
const alex = {
|
||||
quack: () => "you're not wrong..."
|
||||
};
|
||||
|
||||
const ashley = {
|
||||
quack: () => "<corgi.gif>"
|
||||
};
|
||||
|
||||
const nick = {
|
||||
quack: () => "rappers I monkey-flip em with the funky rhythm I be kickin"
|
||||
};
|
||||
|
||||
// Get all our ducks in a row and call into wasm!
|
||||
|
||||
make_em_quack_to_this(alex);
|
||||
make_em_quack_to_this(ashley);
|
||||
make_em_quack_to_this(nick);
|
9
examples/duck-typed-interfaces/index.html
Normal file
9
examples/duck-typed-interfaces/index.html
Normal file
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" height="150" width="150" />
|
||||
<script src='./index.js'></script>
|
||||
</body>
|
||||
</html>
|
3
examples/duck-typed-interfaces/index.js
Normal file
3
examples/duck-typed-interfaces/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
// For more comments about what's going on here, check out the `hello_world`
|
||||
// example.
|
||||
import('./duck-typed-interfaces');
|
10
examples/duck-typed-interfaces/package.json
Normal file
10
examples/duck-typed-interfaces/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^4.11.1",
|
||||
"webpack-cli": "^2.0.10",
|
||||
"webpack-dev-server": "^3.1.0"
|
||||
}
|
||||
}
|
23
examples/duck-typed-interfaces/src/lib.rs
Executable file
23
examples/duck-typed-interfaces/src/lib.rs
Executable file
@ -0,0 +1,23 @@
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
/// Here is a duck-typed interface for any JavaScript object that has a `quack`
|
||||
/// method.
|
||||
///
|
||||
/// Note that any attempts to check if an object is a `Quacks` with
|
||||
/// `JsCast::is_instance_of` (i.e. the `instanceof` operator) will fail because
|
||||
/// there is no JS class named `Quacks`.
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
pub type Quacks;
|
||||
|
||||
#[wasm_bindgen(structural, method)]
|
||||
pub fn quack(this: &Quacks) -> String;
|
||||
}
|
||||
|
||||
/// Next, we can export a function that takes any object that quacks:
|
||||
#[wasm_bindgen]
|
||||
pub fn make_em_quack_to_this(duck: &Quacks) {
|
||||
let s = duck.quack();
|
||||
// ...
|
||||
}
|
10
examples/duck-typed-interfaces/webpack.config.js
Normal file
10
examples/duck-typed-interfaces/webpack.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: './index.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'index.js',
|
||||
},
|
||||
mode: 'development'
|
||||
};
|
@ -15,6 +15,7 @@
|
||||
- [No ES Modules](./reference/no-esm.md)
|
||||
- [Arbitrary Data with Serde](./reference/arbitrary-data-with-serde.md)
|
||||
- [Accessing Properties of Untyped JS Values](./reference/accessing-properties-of-untyped-js-values.md)
|
||||
- [Working with Duck-Typed Interfaces](./reference/working-with-duck-typed-interfaces.md)
|
||||
- [Command Line Interface](./reference/cli.md)
|
||||
- [Supported Types](./reference/types.md)
|
||||
- [Imported JavaScript Types](./reference/types/imported-js-types.md)
|
||||
|
@ -5,6 +5,10 @@ regardless if it is an `instanceof` some JavaScript class or not, use [the
|
||||
`js_sys::Reflect` APIs][js-sys-reflect]. These APIs are bindings to the
|
||||
[JavaScript builtin `Reflect` object][mdn-reflect] and its methods.
|
||||
|
||||
You might also benefit from [using duck-typed
|
||||
interfaces](./working-with-duck-typed-interfaces.html) instead of working with
|
||||
untyped values.
|
||||
|
||||
## Reading Properties with `js_sys::Reflect::get`
|
||||
|
||||
[API documentation for `js_sys::Reflect::get`.](https://rustwasm.github.io/wasm-bindgen/api/js_sys/struct.Reflect.html#method.get)
|
||||
|
20
guide/src/reference/working-with-duck-typed-interfaces.md
Normal file
20
guide/src/reference/working-with-duck-typed-interfaces.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Working with Duck-Typed Interfaces
|
||||
|
||||
Liberal use of [the `structural`
|
||||
attribute](./attributes/on-js-imports/structural.html) on imported methods,
|
||||
getters, and setters allows you to define duck-typed interfaces. A duck-typed
|
||||
interface is one where many different JavaScript objects that don't share the
|
||||
same base class in their prototype chain and therefore are not `instanceof` the
|
||||
same base can be used the same way.
|
||||
|
||||
## Defining a Duck-Typed Interface in Rust
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/duck-typed-interfaces/src/lib.rs}}
|
||||
```
|
||||
|
||||
## JavaScript Usage
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/duck-typed-interfaces/duck-typed-interfaces.js}}
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user