1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-05-23 19:00:13 +02:00

import-js-type

This commit is contained in:
sakex 2023-07-24 19:47:27 +02:00
parent 806335795c
commit 13af2243ec
5 changed files with 115 additions and 6 deletions

View File

@ -298,11 +298,13 @@
- [WebAssembly basics](webassembly.md) - [WebAssembly basics](webassembly.md)
- [Load a WASM module](webassembly/load-wasm-module.md) - [Load a WASM module](webassembly/load-wasm-module.md)
- [Import Method](webassembly/import-method.md)
- [web-sys](webassembly/web-sys.md)
- [Expose a method](webassembly/expose-method.md) - [Expose a method](webassembly/expose-method.md)
- [Error handling](webassembly/error-handling.md) - [Error handling for exposed methods](webassembly/expose-method/error-handling.md)
- [Import Method](webassembly/import-method.md)
- [Error handling for imported methods](webassembly/import-method/error-handling.md)
- [web-sys](webassembly/import-method/web-sys.md)
- [Expose user-defined Rust types](webassembly/expose-rust-type.md) - [Expose user-defined Rust types](webassembly/expose-rust-type.md)
- [Import user-defined Javascript types](webassembly/import-js-type.md)
- [Borrow Checker](webassembly/borrow-checker.md) - [Borrow Checker](webassembly/borrow-checker.md)
# Final Words # Final Words

View File

@ -5,7 +5,7 @@ will automatically throw an error if the variant of the return value is `Result:
```rust ```rust
#[wasm_bindgen] #[wasm_bindgen]
pub fn str_to_int(s: &str) -> Option<i32, JsValue> { pub fn str_to_int(s: &str) -> Result<i32, JsValue> {
s.parse::<i32>() s.parse::<i32>()
.map_err(|_| JsValue::from_str("Failed to parse string")) .map_err(|_| JsValue::from_str("Failed to parse string"))
} }
@ -21,7 +21,7 @@ pub fn str_to_int(s: &str) -> Option<i32> {
``` ```
Javascript (click on the wasm output box) to parse the string: Javascript, click on the wasm output box to parse the string:
```javascript ```javascript
import init, {set_panic_hook, str_to_int} from '/wasm/project.js'; import init, {set_panic_hook, str_to_int} from '/wasm/project.js';
@ -49,6 +49,6 @@ import init, {set_panic_hook, str_to_int} from '/wasm/project.js';
<details> <details>
* Click on the wasm output box to see the output * Click on the wasm output box to see the output
* `?` and other error handling toos also work * `?` and other error handling tools are also supported
</details> </details>

View File

@ -0,0 +1,89 @@
# Import user-defined Javascript types
User-defined Javascript types can be imported by declaring the relevant methods as `extern "C"` just like
other foreign functions.
For instance, let's declare a class `OutputBox`
```javascript
import init, {set_panic_hook, edit_box} from '/wasm/project.js';
class OutputBox {
constructor(element) {
this.element = element;
this.lastText = null;
}
setText(text) {
this.element.innerHTML = text;
}
get currentText() {
return this.element.innerHTML;
}
}
window.OutputBox = OutputBox;
(async () => {
// Run the init method to initiate the WebAssembly module.
await init();
set_panic_hook();
const wasmoutput = document.querySelector('#wasmoutput');
const outputBox = new OutputBox(wasmoutput);
const input = document.createElement('input');
document.body.appendChild(input);
wasmoutput.onclick = () => {
const inputValue = input.value;
edit_box(outputBox, inputValue);
};
})();
```
It can be imported as such in Rust
```rust
#[wasm_bindgen]
extern "C" {
pub type OutputBox;
#[wasm_bindgen(constructor)]
pub fn new(text: i32) -> OutputBox;
#[wasm_bindgen(method)]
pub fn setText(this: &OutputBox, text: &str);
// Has to return owned
#[wasm_bindgen(method, getter)]
pub fn lastText(this: &OutputBox) -> Option<String>;
#[wasm_bindgen(method, setter)]
pub fn set_lastText(this: &OutputBox, text: Option<String>);
#[wasm_bindgen(method, getter)]
pub fn currentText(this: &OutputBox) -> String;
}
#[wasm_bindgen]
pub fn edit_box(output_box: &OutputBox, text: &str) {
match text {
"reset" => output_box.set_lastText(None),
"recover" => {
if let Some(last_text) = output_box.lastText() {
output_box.setText(&last_text);
} else {
output_box.setText("No last text");
}
}
"save" => output_box.set_lastText(Some(output_box.currentText())),
_ => output_box.setText(text),
}
}
```
<details>
* Getters and Setters have to be declared with an added parameter in the proc macro.
* `null` and `undefined` can be both represented by `Option::None`
</details>

View File

@ -0,0 +1,18 @@
# Error handling for imported Javascript methods
Javascript methods that throw can be imported in Rust like this:
```javascript
window.throwsIfPair = (num) => {
if (num % 2 === 0) throw new Error("Pair number");
return num;
};
```
```rust
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(catch)]
pub fn throwsIfPair(text: i32) -> Result<i32, JsValue>;
}
```