Skip to content

Added more documentation for bool, char, and numeric types #4245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions guide/src/reference/types/bool.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | Yes | Yes | A JavaScript boolean value |

> **Note**: Only [JavaScript `Boolean`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) values (`true` or `false`) are supported when calling into Rust. If you want to pass truthy or falsy values to Rust, convert them to a boolean using `Boolean(value)` first.
>
> If you are using TypeScript, you don't have to worry about this, as TypeScript will emit a compiler error if you try to pass a non-`boolean` value.

## Example Rust Usage

```rust
Expand Down
2 changes: 1 addition & 1 deletion guide/src/reference/types/boxed-number-slices.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | Yes | Yes | A JavaScript `TypedArray` of the appropriate type (`Int32Array`, `Uint8Array`, etc...) |

Note that the contents of the slice are copied into the JavaScript `TypedArray`
> **Note:** The contents of the slice are copied into a JavaScript [`TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)
from the Wasm linear memory when returning a boxed slice to JavaScript, and vice
versa when receiving a JavaScript `TypedArray` as a boxed slice in Rust.

Expand Down
8 changes: 8 additions & 0 deletions guide/src/reference/types/char.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | No | No | A JavaScript string value |

Since JavaScript doesn't have a character type, `char` is represented as a JavaScript string with one Unicode code point.

> **Note**: [JavaScript strings uses UTF-16 encoding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#utf-16_characters_unicode_code_points_and_grapheme_clusters). This means that a single `char` may be represented by a string of length 1 or 2 in JavaScript, depending on the Unicode code point. See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) for more information.

When passed into Rust, the `char` value of a JavaScript string is determined using [`codePointAt(0)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt). If the JavaScript string is empty or starts with an unpaired surrogate, a runtime error will be thrown.

> **Note**: For more information about unpaired surrogates, see the [documentation for `str`](str.html).

## Example Rust Usage

```rust
Expand Down
5 changes: 3 additions & 2 deletions guide/src/reference/types/exported-rust-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | Yes | Yes | Yes | Yes | Yes | Instances of a `wasm-bindgen`-generated JavaScript `class Whatever { ... }` |

> **Note**: Public fields implementing Copy have automatically generated getters/setters.
> To generate getters/setters for non-Copy public fields, use #[wasm_bindgen(getter_with_clone)] for the struct
> **Note**: Public fields implementing `Copy` have automatically generated getters/setters.
> To generate getters/setters for non-`Copy` public fields, use `#[wasm_bindgen(getter_with_clone)]` for the struct
> or [implement getters/setters manually](https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-rust-exports/getter-and-setter.html).

## Example Rust Usage

```rust
Expand Down
53 changes: 52 additions & 1 deletion guide/src/reference/types/numbers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,58 @@

| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | Yes | Yes | A JavaScript number value |
| Yes | No | No | Yes | Yes | Yes | A JavaScript number or bigint value |

[JavaScript `Number`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_encoding) are 64-bit floating point value under the hood and cannot accurately represent all of Rust's numeric types. `wasm-bindgen` will automatically use either [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) or `Number` to accurately represent Rust's numeric types in JavaScript:

- `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, `usize`, `f32`, and `f64` will be represented as `Number` in JavaScript.
- `u64` and `i64` will be represented as `BigInt` in JavaScript.

> **Note**: Wasm is currently a 32-bit architecture, so `isize` and `usize` are 32-bit integers and "fit" into a JavaScript `Number`.

## Converting from JavaScript to Rust

`wasm-bindgen` will automatically handle the conversion of JavaScript numbers to Rust numeric types. The conversion rules are as follows:

### `Number` to `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `isize`, and `usize`

If the JavaScript number is `Infinity`, `-Infinity`, or `NaN`, then the Rust value will be 0. Otherwise, the JavaScript number will rounded towards zero (see [`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) or [`f64::trunc`](https://doc.rust-lang.org/std/primitive.f64.html#method.trunc)). If the rounded number is too large or too small for the target integer type, it will wrap around.

For example, if the target type is `i8`, Rust will see the following values for the following inputs:

| JS input number | Rust value (`i8`) |
| --------------: | :---------------- |
| 42 | 42 |
| -42 | -42 |
| 1.999 | 1 |
| -1.999 | -1 |
| 127 | 127 |
| 128 | -128 |
| 255 | -1 |
| 256 | 0 |
| -0 | 0 |
| `±Infinity` | 0 |
| `NaN` | 0 |

This is the same behavior as assigning the JavaScript `Number` to a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) of the appropriate integer type in JavaScript, i.e. `new Uint8Array([value])[0]`.

Except for the handling of `Infinity` and `-Infinity`, this is the same behavior as [casting](https://doc.rust-lang.org/reference/expressions/operator-expr.html#numeric-cast) `f64` to the appropriate integer type in Rust, i.e. `value_f64 as u32`.

### `BigInt` to `u64` and `i64`

If the JavaScript `BigInt` is too large or too small for the target integer type, it will wrap around.

This is the same behavior as assigning the JavaScript `BigInt` to a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) of the appropriate integer type in JavaScript, i.e. `new Int64Array([value])[0]`.

### `Number` to `f32`

The JavaScript `Number` is converted to a Rust `f32` using the same rules as [casting](https://doc.rust-lang.org/reference/expressions/operator-expr.html#numeric-cast) `f64` to `f32` in Rust, i.e. `value_f64 as f32`.

This is the same behavior as [`Math.fround`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround) or assigning the JavaScript `Number` to a [`Float32Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array) in JavaScript, i.e. `new Float32Array([value])[0]`.

### `Number` to `f64`

Since JavaScript numbers are 64-bit floating point values, converting a JavaScript `Number` to a Rust `f64` is a no-op.

## Example Rust Usage

Expand Down
Loading